[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Draft IPv6 Security API for BSD Sockets



I'm not very happy with some aspects of the draft.  My two main
areas of concern are the nature of the interface and the error-reporting
mechanisms proposed.

The latter is easier to explain.  I don't think that, in general,
it's at all a good idea to send errors to a security-aware application
simply because bogus (or damaged) packets are received.  If nothing
else, it opens us up to easy denial of service attacks -- an attacker
can spew out bogus packets, he or she can cause these sessions to
abort.  While security error statistics should be maintained,
certainly on a system- wide basis and probably on a per-SAID or
per-connection basis, it isn't at all clear to me that most
applications -- even security-aware ones -- need to be told about
these at all times.  I'd suggest a more tunable approach -- the
process specifies a threshold, which defaults to infinity, for
errors; when the the threshold is exceeded, a process-specified
signal (or maybe SIGSECURITY or SIGHACK) could be raised.

My problem with the mechanisms for specifying security levels is that
I think the proposal is too low-level.  It isn't clear to me that
setsockopt() is the best way to proceed.  I'd rather see a more
POSIX-like approach, where a subroutine interface is used.  Thus,
instead of saying setsockopt(fd, IP_SECLEVEL, ...), a process would
say setsecuritylevel(fd, ...).

There are two advantages to this approach.  First, it's more portable
to other architectures than a straight 4.2bsd-like socket interface.
A streams-based TCP would have more trouble with a setsockopt, since
stream modules are much more isolated than is a monolithic Berkeley-
type kernel.  This becomes more apparent when we look at the next
requirement, which is mentioned in the draft:  per-user SAIDs.

My mental model for this function is a Kerberos-like interface.  (There's
a lot more involved in doing it right than just Kerberos, but I won't
go into that now.)  The user process obtains some credentials for
a connection; these credentials are bound to a pair of SAIDs, one for
each end.  These credentials must then be passed to the kernel for
use with one or more IP connections.  But obtaining these authorizations
is not something that's easily done in the kernel.  A Berkeley-like
kernel could, in principle, contact a credentials daemon on behalf
of the current user, if no explicit credentials are supplied; that's
much harder with streams, since a streams module does not have access
to the user's u. or proc structures, and cannot easily sleep().

Note that my model supports host-pair SAID granularity as well.  When
the setsecuritylevel() call is done, if no suitable SAID exists, the
subroutine can initiate negotiations, using whatever privileged components
are available.  If the system supports user-level granularity, then
the existing user-level Kerberos tickets are used.  But that's transparent
to the user, though we'd probably want a getpeerprincipal() call.

I'm rambling a bit, and I'm probably not being very clear.  I'd like
to hear other comments.

		--Steve Bellovin


Follow-Ups: