This web page is an attempt to promote some of the freeware projects I currently work on.
Here are more detailed project pages for some of the freeware projects I'm working on:
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:
http://www.planix.com/~woods/dotfiles.list
http://www.planix.com/~woods/dotfiles.tar.gz
I've created a local release of the
inetd
program. This version incorporates several new features, including:
libwrap
support for UDP connections (as best
as can be done — no IDENT, etc. of course)
libwrap
is now only relied upon to log refused connections)
-DMULOG
option (per-service logging and IDENT logging) (and
corresponding removal of the MULOG #ifdefs
)
fd_set
arrays from OpenBSD
This version of inetd
has been submitted to the
NetBSD project in
PR#18955.
libcrack
for NetBSDNetBSD 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.
Recently Jeff Atwood wrote about this issue in his post titled "Password Rules Are Bullshit".
To help 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.
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).
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
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
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.
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.
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.
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.
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.
woods-freeware-proj@planix.com