Greg's FreeWare Projects Page

This web page is an attempt to promote some of the freeware projects I currently work on.

Projects With Separate Project Pages

Here are more detailed project pages for some of the freeware projects I'm working on:

Projects without their own project page

User Login Session Setup and Configuration Files

For a rather long time now I've been maintaining a set of mostly cross-platform startup scripts for my login shell (usually ksh or pdksh), editor (Emacs of course), X11 window manager (either twm or preferably ctwm) configurations, as well as various other little configuration files. These have grown over the years to quite a substantial collection of nifty tricks and handy little trinkets, and together at times have more than once been called a project with a life of its own! You can find them all here:

    ftp://ftp.planix.com/pub/local/dotfiles.tar.gz

*BSD Inetd

I've created a local release of the inetd program. This version incorporates several new features, including:

This version of inetd has been submitted to the NetBSD project in PR#18955.

libcrack for NetBSD

NetBSD allows, depending on the chosen cipher algorithm, users to set passwords of up to 128 characters in length. However as supplied it does not prevent the user from choosing trivially crackable passwords. To solve this problem I've integrated Alec Muffett's cracklib library such that all passwords set by any user must be reasonably strong.

This change integrating libcrack has been submitted to the NetBSD project in PR#10206. Updated versions of this patch are available from me directly.

fopen_as_user()

Traditional UNIX offered a system call known as access() that could be used by a process started from a setuid binary to check if a filesystem object could be accessed by the real-user (as opposed to the effective-user that the program was set-user-ID to). Unfortunately it took a pathname parameter and has since been made almost completely useless by the fact it is vulnerable to a race condition. While several other system calls were provided with variants accepting file descriptors (f*(2)), there has never, to the best of my knowledge, been an implementation of faccess() provided in any popular UNIX variant. However the utility of this call, along with one other approach to the problem, have been discussed in several places, including this paper by: Matt Bishop: ``Race Conditions, Files, and Security Flaws: or, The Tortoise and the Hare Redux,'' Technical Report 95-9, Department of Computer Science, University of California at Davis (Sep. 1995). [PS] [PDF]

Note the saved-set-ID swapping feature available in may systems has NEVER been an actual necessity. It is a possible solution to the access();open() race, but it has often been misused, it is extremely mis-understood, and it has been broken in the past. There are more than enough reasons to get rid of it entirely. Using ID-swapping in some vain attempt to make privileged processes run in a more secure manner except for the few lines of code which need their privileges is a fallacy. Such programs are only one system call away from regaining their privileges at any time, even at the control of an attacker. The fallacy of running privileged programs at some reduced privilege while still allowing them to regain their privileges at any time is in fact a danger, not a benefit, because it gives only a very false sense of security. The best systems security will come from never running big monolithic daemons as root, and from always permanently dropping privilege as soon as possible in any program which performs authentication and authorisation.

Some time ago I faced a similar but slightly more generic issue in Smail-3 and I implemented the more-or-less standard and portable solution in a function I called fopen_as_user(). It opens the file with open(), stats it via the open file descriptor with fstat(), then while still holding the file open it forks a child process which first lowers its privileges and then does the same thing. If the child process is able to successfully open and stat the file it then compares the second struct stat contents with the first one from the parent process and if they are identical and all was well it exits with a status code of zero indicating to the parent process that the specified user had access to the file in question. Previously Smail-3 had used setreuid() or some variant to temporarily lower its privileges, but of course this ability is not possible to use securely, and neither is it portable. Even seteuid() is not portable since sane operating systems do not allow privileged processes to temporarily lower and then regain their privileges as this would open a whole can of worms that we've seen discussed in CERT and similar security advisories.

Here's another slightly more efficient, elegant, and reliable way to implement fopen_as_user() using kernel file descriptor passing through AF_LOCAL socket, derived mostly from code provided by the late W. Richard Stevens in his book `` UNIX Network Programming, Volume 1, Second Edition: Networking APIs: Socketsand XTI'' (Prentice Hall, 1998.)

    ftp://ftp.planix.com/pub/Planix/fopen_as_user.c
    http://www.weird.com/~woods/projects/fopen_as_user.c

So far I've used this code successfully to replace the seteuid() ID-swapping calls in NetBSD's lib/libc/net/rcmd.c, usr.bin/login/login.c, usr.sbin/cron/crontab.c and usr.sbin/lpr/lpr/lpr.c, as well. All of these are examples of having a privileged process having to drop privileges to even get anywhere near an NFS-mounted file that might be protected from any kind of root access by the remote server. Still to be fixed are ftpd, and some other subsystems I don't regularly use.

This interface can also be used to allow privileged programs to make use of the tzset(3) feature where the $TZ environment variable can specify an arbitrary pathname from whence to read time conversion information from.

Potentially this interface can similarly be used to keep the gethostbyname() feature where the $HOSTALIASES> can specify the name of an alias file provided by the user. However I don't think there's any safe way to keep $HOSTALIASES in any form if you've got any concern whatsoever about the name-to-location mapping issue.

I have of course made my fopen_as_user() interface necessary in the above situations as I've patched my NetBSD releases so that they totally disable setreuid(), and seteuid() has been modified such that if the superuser calls it then the effect is the sam as if setuid() had been called instead. I.e. the superuser must always permanently revoke its privileges. Logging has been introduced to report on processes which still attempt to do ID-swapping or to call the old disabled interface.

One of these days I plan to implement int open_as(const char *path, int flags, mode_t mode, uid_t uid, uid_t gid); as a true system call. There has been some debate in various forums about whether such a system call should allow the saved-set-ID credentials to be specified after a process had (permanently) lowered its privileges via a call to seteuid(getuid()) or not. Such an ability would allow some processes to drop privileges earlier than they otherwise would be able to and yet still access privileged files, and also work with non-root set-ID programs. Note if the use of saved-set-ID credentials is allowed then this call must prevent setting of any set-ID flags on any files which it might be used to create. Note also that no other existing system calls may be allowed to use saved-set-ID credentials in this way (except perhaps a socket-related call). Somewhat limited but similar results could be had by adding something like an O_REAL_ID flag to the existing open() interface as well.

In order for some programs, such as ftpd, to avoid ID-swapping, privileged helper programs may be needed in order to bind sockets to privileged port numbers, for example. Such programs will also need to be set-group-ID to a unique group such that they can be given access to execute these otherwise privileged helper programs.

Wintec WSG-2000 GPS Tracker Log Parser and GPSBabel Interface Module [new-stuff!]

I have a Wintec WSG-2000 (``G-Trender II'') GPS-based cycle computer. It produces GPS and data logs and stores them on a FAT filesystem on an internal Micro-SD card which is mountable as a mass-storage device over the USB interface. The log files are nicely organised in a date-based directory structure with time-based filename that has an extension of NAL. However these logs have a proprietary binary format.

After much searching and some un-answered queries to the manufacturer I finally found a post by someone who had managed to decode the record format:

    http://www.mikrocontroller.net/topic/260568

Using the data structure described in the post I wrote some code to read these log files, and I further adapted my code to serve as a GPSBabel ``format'' module. This code, and in particular the patch file, is only known to work directly with the ``old'' C version of GPSBabel, i.e. 1.4.3 and older. You can still check out the old code from the Source Forge CVS servers, as per the link below. I refuse to work with C++, but if anyone should care to re-package it in such a way that it might be included in the newer version of GPSBabel, please be my guest and do so! I only ask that my name remain as the main author of the module.

    http://www.weird.com/~woods/projects/wsg2000.c
    http://www.weird.com/~woods/projects/wsg2000.patch
    http://sourceforge.net/p/gpsbabel/code/?source=navbar

Note: This code was written primarily for BSD (and OS X) systems. In this case this mostly just means it needs <err.h> and the associated functions.

FYI, it has been tested on both i386 based systems as well as Power PC (i.e. on big-endian and little-endian systems where bit-field order is different on each).

gTLD Wildcard Finder and BIND-8 Patches

For a short period of time in the fall of 2003 Verisign, the registrar in charge of the .net and .com global top level domains had published a wildcard A record as an attempt to hijack every non-existent domain for advertising purposes (though ostensibly they claimed it was only for assisting people searching for things without using a search engine). The response from both ICANN and from the maintainers of BIND was swift and sure. However this has not stopped other gTLD operators from implementing similar stupid tricks (often far more poorly). Indeed many ISPs have jumped on this subversive marketing plan as well.

I've integrated some patches for BIND-8 to provide the equivalent of an access control list (ACL) to block A records which point to the specified list of IP addresses. This isn't quite as generic as the BIND-9 fix, but it suffices. The patches are available here as part of a larger set of fixes and tweaks for BIND-8:

    ftp://ftp.planix.com/pub/Planix/bind-8.4.7-REL-Planix-1.diff

I've also written a little script that helps me keep the list of naughty IP addresses up to date. It is available here:

    ftp://ftp.planix.com/pub/Planix/gtld-wildhosts.sh
    http://www.weird.com/~woods/projects/gtld-wildhosts.sh

CIDR NetBlock Aggregator

On occasion I've had to aggregate CIDR netblocks, i.e. make sure only the minimum number of widest-possible blocks are specified (e.g. when writing filter rules, etc.). Normally I've done this by hand, but recently I encountered a list of nearly a thousand routes and I wanted to be able to aggregate it into the smallest inclusive number of routes accruately and repeatedly and so I wrote this little program:

    ftp://ftp.planix.com/pub/Planix/netagg.c
    http://www.weird.com/~woods/projects/netagg.c

vm-bogofilter.el for Emacs ViewMail

I've made some major changes and improvements to vm-bogofilter, and interface between Emacs ViewMail (VM) and bogofilter.

    ftp://ftp.weird.com/pub/local/vm-bogofilter.el
    http://www.weird.com/~woods/projects/vm-bogofilter.el

Note that I no longer use ViewMail as I've switched over using Wanderlust exclusively. This bogofilter patch is no longer maintained, nor do I use anything similar yet in ViewMail.

Tape File Management

I've also written a couple of nifty tape copy scripts that several people have asked for. They're available for ftp from here:

    ftp://ftp.planix.com/pub/Planix/tapestuff.shar.

Hardware Monitoring

I've written a BSD device driver for the National Semiconductor LM78 environmental monitoring ASIC chip often found on modern system motherboards, such as the Asus P297L (Intel Pentium-II board). This chip monitors power supply voltages, fan rotation speeds, as well as on-board temperature. The driver was originally designed on FreeBSD-2.2.8 using a very primitive Linux driver as the primary source of ideas. Since then the driver has been migrated to NetBSD-1.3.3 and -current as of about 1.3K. You can download a copy of the LM7X.shar file and try it out on your system. Note that you'll have to apply the diffs after unpacking the archive.

Other stuff you can get from my server...

You may also find some other useful and perhaps interesting stuff in my Public FTP, Planix, Inc. FTP archives, such as local versions of various software packages.

Custom NetBSD Release Management

Another project of sort (really it's a whole class of related projects) which deserves mentioning, but which does not (yet) have its own project page either, is my custom NetBSD release work. My first experiments with building custom OS releases were with the FreeBSD-2.2 branch where I produced several customised releases for a client. Since beginning in late in 1998 I've produced two highly customised NetBSD releases that have been used in production both for my own systems as well as at some of our client sites. The first of these was based on the official NetBSD 1.3.3 release. The second is a cut from NetBSD-current as of 2001/06/24.

Since the release of NetBSD 1.6 I've been working on following the NetBSD-release branch (stable, aka netbsd-1-6). With the integration of a unified buffer cache to the virtual memory system NetBSD-1.6 is the first NetBSD release with most of the core kernel features necessary to make a really viable good performance production quality system. As of 2003/09/14 I now have a full test release of NetBSD/alpha, NetBSD/sparc, and NetBSD/i386 built with all of the relevant changes from my previous -current release integrated and this new release, along with significant new development efforts as well. This new release is now running on both of my development servers, as well as on our main Internet (mail, web, DNS, etc.) server. I can make complete CD-ROM ISO images available to anyone interested in trying it out.

Many of my 1.6-based changes were migrated to a custom release of the netbsd-4 branch which I have used with good success both locally as well as at client sites.

Beginning soon after the branch of netbsd-5 I began merging my local changes over to NetBSD-5, and I now have even more of the original 1.6-based changes in a new custom release of the head of the netbsd-5 branch.

I also maintain a local variant of the NetBSD pkgsrc system. I build binary packages from this tree and use them to support various client sites running my custom NetBSD release. Once upon a time a great deal of effort was necessary to ensure binary packages produced from pkgsrc were correct, complete, and usable. Vast improvements in pkgsrc have made exclusive use of official binary packages much more viable of course, but I still need to be able to provide more timely support. My pkgsrc tree also has the beginnings of support for building static-linked packages, which greatly improves performance of some software and drastically reduces the run-time interdependency maze many packages suffer greatly from.

Anyone interested in influencing, by way of monetary remuneration or other considerations such as hardware donations or connectivity offers, etc., how and when I do this work is welcome to contact me for further details.


For further information about my freeware projects in general, or to comment on this particular web page, please contact me at this address: woods-freeware-proj@planix.com

Last modified:
Copyright by Greg A. Woods. All rights Reserved
Last published on 2003/06/15 at 02:33:59 (version 1.17).