Bugtraq mailing list archives

s/key rant, with source code


From: hobbit () asylum sf ca us (*Hobbit*)
Date: Tue, 20 Sep 1994 07:59:04 -0400


Instead of continuing to whine about the divergence of s/key versions, I've
decided to do something about it.  As I read through the variants, I noticed
that each one had some nice features -- NRL with md5 support, Crimelab with
some Solaris support and cute interface functions, for example.  I've made
what for me are Herculean efforts, because coding isn't really my strongest
point, to merge these features back into one common source.  I may have
dropped a thing or two here and there, but I believe I snagged most of it.  I
don't particularly relish the idea of introducing yet more version skew into
the picture, but I'd like to think of this as anti-skew and a bid for better
portability.  For example, "skey" should now build on many architectures and
produce the same output; with this you get an MD5 s/key calculator for DOS
that will work against your unix box.

I also added a new twist, based partially on TIS or Chasin or whoever's
"skeysh" idea, which I've called "skeyin".  This was talked about on skey-
users some time ago but I don't know if anyone really implemented it.  It
allows people to use s/key to log in without your having to change the
/bin/login binary.  This was relevant for me because I deal with a couple of
sites that already have changed their login binaries to handle something
*else*, like kerberos or SRA or something, and I didn't want to fool with
jacking s/key into those.  So now people can simply log in as some
pseudo-user, like "skey", whose shell is "skeyin"; this asks for their real
username, authenticates their s/key, and logs them in for real.  This way, no
regular passwords have to travel the net, as they possibly would if "skeysh"
was being used, and several of the other "skeysh"-related problems discussed
over time go away.

The "skeyin" scheme should be reasonably tight if your ftpd enforces
restrictions governed by /etc/shells and/or /etc/ftpusers; I'm not completely
sure about other protocols that deal with usernames and passwords, but if
you're not running XDM and user "skey" can't receive mail, there isn't much
else left for the pseudo-user account to open a hole.  Please correct me with
hard examples if I'm wrong here.  The more paranoid can completely disable
their own regular passwords if "skeyin" is sufficient.  Besides, this is
mostly to protect "offsite" logins, right?

My in-progress merged version of the s/key core code is available for
anonymous FTP at asylum.sf.ca.us:/pub/hobbit/skey-H-alpha.tar.Z.  Have at,
with the caveat that this is still in a seriously ALPHA state, the "todo" list
is a mile long, and the code is riddled with "xxx: fix this" comments.
"skeyin" in particular probably won't work completely right on some platforms;
I've managed to test it so far on sunos4.1.x, ultrix, solaris, aix kind of up
and limping, and an incomplete Linux run.  You're on your own for anything
that isn't in the makefile.  I just want to get some feedback from the
harder-core s/key folks if they find this useful.  Responses in whatever form
are welcome: suggestions, improved code, overripe fruit ...

The rest of this message overviews some of my changes/merges/todo, so skip it
if you're not interested.
_____________________________________________________________________________

First and foremost: to build this stuff, use the following syntax:

        make <systype> SKEYUID=nn

where <systype> is one of the ones listed near the end of the Makefile, and nn
is a UID for the "skeyin" pseudo-user account.  This account should have a
unique UID and GID, its shell should be /wherever/skeyin, and "skeyin" itself
should be owned by root, have its GID the same as SKEYUID, and mode 4110.  The
account can have a trivial or null password.  "Skeyin" tries to log as much
information as possible, so you can track use or abuse through syslog.

Add "MD=5" to the above command line to build everything using MD5.

Because of much common functionality, the source for "skeyin" is actually
three sources in one, and will build to "skeyin", "skeysu", or "skeysh" per
#ifdefs. Now, the "obvious" thing to do was authenticate, and then hand the
whole mess off to another invocation of "login -f username" -- in fact, that's
how the whole idea started, but I ran into a large problem.  Many platforms'
/bin/logins don't support the "-f" switch [especially these days!], so skeyin
has to take care of utmp/wtmp/utmpx/wtmpx/lastlog itself.  These are handled
in a whole variety of different ways, and will probably need specific support
on oddball platforms.  If your /bin/login DOES support the -f switch, take out
the define of LOGIN_HAIR in the Makefile, build "skeyin", and it should simply
hand off through a second invocation of login to fix up everything else.  This
may still show the "skey" pseudo-user shown as having been still logged in the
entire time you were in "last" information.  I have NOT yet been able to find
a platform to accurately test this on, so feedback would be immensely useful.

"Skeyin" completely zorches the environment except for TERM, just like its
big brother "login".  If you don't agree with doing this, fix as you like.

I did not include any of the login or ftpd sources.  They are all completely
different, and everyone has different needs, so you're on your own to dink the
one you like your own way.  The all-singing all-dancing source to telnetd +
login + rshd + ftpd that supports kerberos 4 & 5, securID, SNK, SRA, S/Key,
Enigma, etc, along with fbtab, hosts-access, login-access, AIX stanza-oriented
files, you get the idea -- it doesn't exist yet, so for now we're stuck with
this lossage.  The firewall toolkit has an interesting approach to the growing
plethora of authentication schemes...

I didn't include any of the manpages, either; I know that many people have
been writing or fixing their own anyhow.  S/Key is doomed to remain soggy and
hard to light for many users who just don't get it, until there are some nicer
front-end apps that make it easy for them.  If you've read this far, you
aren't one of those users, but the problem still remains.

The same "skey" calculator source compiles unmodified on unix or DOS, in MD4
or MD5 mode.  [You may need the included getopt, particularly for DOS; I
grabbed getopt.c and getopt.h from the PGP distribution.]  I also merged some
divergent tty handling code from various skey-users messages in.  I didn't do
anything about "termkey", or Mac stuff; "termkey" in particular was built with
a different compiler than mine.  Anyone want to send me "tsr.h", for starters?

I don't supply DOS executables in this package, but if you REALLY need one
and can't build it locally, I can make one available to trusting souls.

I swiped the MD5 code from Tripwire, instead of using the one from NRL; this
version is byte-order independent and doesn't seem to care about word sizes.
I am also using this same MD5 elsewhere, notably L5.  The MD4 code is from the
NRL skey.  The calling interfaces for these MD4 and MD5 routines are almost
identical.  "global.h" was eliminated.

I included Chasin's wrapper functions, such as skey_authenticate and
skey_haskey, which make adding s/key support to stuff like login and ftpd
easier.  The modified BSD "login" from bellcore was just gross.

I separated some big printf()s into pieces, because they were losing on my
creaky ol' DOS box.

I left in the #ifdef MJR hooks for Ranum's "desmode" stuff; if you want to use
it, get his support directory from the NRL distribution.  Or just use a good
passphrase to generate your keys.

I merged a bunch of different concepts into one fairly lean and mean Makefile.
This one doesn't do "install"; where you put binaries is your concern.  The
code seems to build just fine with -O turned on now, despite a comment in the
original bellcore Makefile.

By default, libskey.a is not built, but there is a makefile target for it if
you need it to build something else.

Most of the stuff wouldn't build on an old SunOS 4.0.x because its library
doesn't have an strftime().  One could be supplied, I suppose...

Executables are linked static wherever possible.  I only had gcc to test
Solaris stuff with, the reasons for same being the subject of an entirely
different rant, but several things wouldn't link static there.

Some of the major things to do are:

Directly support more platforms, although finding testbeds isn't easy.
Important ones: 386bsd/freebsd, irix, hpux, osf/1, maybe SCO.  Access to
testbeds will be gratefully accepted!

Use a consistent set of #defines to identify platforms and dependencies,
instead of stupid crap like USE_STD_LIB vs HASSTDLIBH, MSDOS vs __MSDOS__,
SVR4 vs __svr4__ vs (SYSV == 4).  Bring all of this in line with the same
"generic.h" scheme used with L5.

Fix up numerous inefficiencies, cosmetics, unused code and defines, syslog
levels, use of stdout vs stderr, misspellings, misnomers, you name it.

Either prototype or don't prototype, across ALL source files, but make a
decision already.  Leaning toward NOT prototyping; old machines need security
too...

Improve backspace() and call it in readpass().  Don't use readpass() for
authenticating, since echoing during authentication is helpful for the typist.

Make hex output a runtime option.  [I think someone's already done this]

Change skey_checkpass() or whatever it is to do f(key), compare, and return
yea or nay but NOT update the file, with appropriate caveats about leaving
small windows open after giving away a still-valid password.  This has its
uses, if two things need to effectively do one authentication check in quick
succession.

Add paranoia to skeyinit, such that if a user already has an skey, demand the
next one before allowing a new skeyinit.  This is much more secure and
appropriate than Chasin's demand-the-password scheme.  Not sure what to do
about users that don't have an skey yet; it is nice if they can initialize
themselves the first time without admin intervention unless they blow it
somehow.

Put shadow password support [for *which* of about eight different schemes, you
ask?!] back in, maybe, for platforms that keep stuff like lastlog dates there?

Perhaps handle other bizarre login stuff, such as aix's /etc/security/lastlog
stanzas, or figure out how aix's "secondary authentication" stuff works and how
s/key can be used there.  This perhaps slightly less important, considering
that "skeyin" does fairly copious logging.  This path leads to featuritis,
anyways, so I'm not too sure about it.

Grub several more of those suggested improvements and diffs out of the
skey-users archive.

Do I sound just a wee bit disgusted?  I am.

_H*



Current thread: