Skip to content

Commit

Permalink
Add server-side otp preauth plugin
Browse files Browse the repository at this point in the history
This plugin implements the proposal for providing OTP support by
proxying requests to RADIUS. Details can be found inside the
provided documentation as well as on the project page.

http://k5wiki.kerberos.org/wiki/Projects/OTPOverRADIUS

ticket: 7678
  • Loading branch information
npmccallum authored and greghudson committed Jul 11, 2013
1 parent 8b8f031 commit 4b5dd8b
Show file tree
Hide file tree
Showing 14 changed files with 1,528 additions and 0 deletions.
66 changes: 66 additions & 0 deletions doc/admin/conf_files/kdc_conf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,72 @@ administrative server will be appended to the file
admin_server = DEVICE=/dev/tty04


.. _otp:

[otp]
~~~~~

Each subsection of [otp] is the name of an OTP token type. The tags
within the subsection define the configuration required to forward a
One Time Password request to a RADIUS server.

For each token type, the following tags may be specified:

**server**
This is the server to send the RADIUS request to. It can be a
hostname with optional port, an ip address with optional port, or
a Unix domain socket address. The default is
|kdcdir|\ ``/<name>.socket``.

**secret**
This tag indicates a filename (which may be relative to |kdcdir|)
containing the secret used to encrypt the RADIUS packets. The
secret should appear in the first line of the file by itself;
leading and trailing whitespace on the line will be removed. If
the value of **server** is a Unix domain socket address, this tag
is optional, and an empty secret will be used if it is not
specified. Otherwise, this tag is required.

**timeout**
An integer which specifies the time in seconds during which the
KDC should attempt to contact the RADIUS server. This tag is the
total time across all retries and should be less than the time
which an OTP value remains valid for. The default is 5 seconds.

**retries**
This tag specifies the number of retries to make to the RADIUS
server. The default is 3 retries (4 tries).

**strip_realm**
If this tag is ``true``, the principal without the realm will be
passed to the RADIUS server. Otherwise, the realm will be
included. The default value is ``true``.

In the following example, requests are sent to a remote server via UDP.

::

[otp]
MyRemoteTokenType = {
server = radius.mydomain.com:1812
secret = SEmfiajf42$
timeout = 15
retries = 5
strip_realm = true
}

An implicit default token type named ``DEFAULT`` is defined for when
the per-principal configuration does not specify a token type. Its
configuration is shown below. You may override this token type to
something applicable for your situation.

::

[otp]
DEFAULT = {
strip_realm = false
}

PKINIT options
--------------

Expand Down
1 change: 1 addition & 0 deletions doc/admin/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ For administrators
host_config.rst
backup_host.rst
pkinit.rst
otp.rst
princ_dns.rst
enctypes.rst

Expand Down
85 changes: 85 additions & 0 deletions doc/admin/otp.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
OTP Preauthentication
=====================

OTP is a preauthentication mechanism for Kerberos 5 which uses One
Time Passwords (OTP) to authenticate the client to the KDC. The OTP
is passed to the KDC over an encrypted FAST channel in clear-text.
The KDC uses the password along with per-user configuration to proxy
the request to a third-party RADIUS system. This enables
out-of-the-box compatibility with a large number of already widely
deployed proprietary systems.

Additionally, our implementation of the OTP system allows for the
passing of RADIUS requests over a UNIX domain stream socket. This
permits the use of a local companion daemon which can handle the
details of authentication.


Defining token types
--------------------

Token types are defined in either krb5.conf or kdc.conf according to
the following format::

[otp]
<name> = {
server = <host:port or filename> (default: $KDCDIR/<name>.socket)
secret = <filename>
timeout = <integer> (default: 5 [seconds])
retries = <integer> (default: 3)
strip_realm = <boolean> (default: true)
}

If the server field begins with '/', it will be interpreted as a UNIX
socket. Otherwise, it is assumed to be in the format host:port. When
a UNIX domain socket is specified, the secret field is optional and an
empty secret is used by default.

When forwarding the request over RADIUS, by default the principal is
used in the User-Name attribute of the RADIUS packet. The strip_realm
parameter controls whether the principal is forwarded with or without
the realm portion.


The default token type
----------------------

A default token type is used internally when no token type is specified for a
given user. It is defined as follows::

[otp]
DEFAULT = {
strip_realm = false
}

The administrator may override the internal ``DEFAULT`` token type
simply by defining a configuration with the same name.


Token instance configuration
----------------------------

To enable OTP for a client principal, the administrator must define
the **otp** string attribute for that principal. The **otp** user
string is a JSON string of the format::

[{
"type": <string>,
"username": <string>
}, ...]

This is an array of token objects. Both fields of token objects are
optional. The **type** field names the token type of this token; if
not specified, it defaults to ``DEFAULT``. The **username** field
specifies the value to be sent in the User-Name RADIUS attribute. If
not specified, the principal name is sent, with or without realm as
defined in the token type.

For ease of configuration, an empty array (``[]``) is treated as
equivalent to one DEFAULT token (``[{}]``).


Other considerations
--------------------

#. FAST is required for OTP to work.
1 change: 1 addition & 0 deletions src/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ SUBDIRS=util include lib \
plugins/pwqual/test \
plugins/kdb/db2 \
@ldap_plugin_dir@ \
plugins/preauth/otp \
plugins/preauth/pkinit \
kdc kadmin slave clients appl tests \
config-files build-tools man doc @po@
Expand Down
1 change: 1 addition & 0 deletions src/configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -1371,6 +1371,7 @@ dnl ccapi ccapi/lib ccapi/lib/unix ccapi/server ccapi/server/unix ccapi/test
plugins/kdb/db2/libdb2/test
plugins/kdb/hdb
plugins/preauth/cksum_body
plugins/preauth/otp
plugins/preauth/securid_sam2
plugins/preauth/wpse
plugins/authdata/greet
Expand Down
2 changes: 2 additions & 0 deletions src/kdc/kdc_preauth.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ get_plugin_vtables(krb5_context context,
/* Auto-register encrypted challenge and (if possible) pkinit. */
k5_plugin_register_dyn(context, PLUGIN_INTERFACE_KDCPREAUTH, "pkinit",
"preauth");
k5_plugin_register_dyn(context, PLUGIN_INTERFACE_KDCPREAUTH, "otp",
"preauth");
k5_plugin_register(context, PLUGIN_INTERFACE_KDCPREAUTH,
"encrypted_challenge",
kdcpreauth_encrypted_challenge_initvt);
Expand Down
31 changes: 31 additions & 0 deletions src/plugins/preauth/otp/Makefile.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
mydir=plugins$(S)preauth$(S)otp
BUILDTOP=$(REL)..$(S)..$(S)..
MODULE_INSTALL_DIR = $(KRB5_PA_MODULE_DIR)

LIBBASE=otp
LIBMAJOR=0
LIBMINOR=0
RELDIR=../plugins/preauth/otp

SHLIB_EXPDEPS = $(VERTO_DEPLIBS) $(KRB5_BASE_DEPLIBS) \
$(TOPLIBD)/libkrad$(SHLIBEXT)

SHLIB_EXPLIBS= -lkrad $(VERTO_LIBS) $(KRB5_BASE_LIBS)

STLIBOBJS = \
otp_state.o \
main.o

SRCS = \
$(srcdir)/otp_state.c \
$(srcdir)/main.c

all-unix:: all-liblinks
install-unix:: install-libs
clean-unix:: clean-liblinks clean-libs clean-libobjs

clean::
$(RM) lib$(LIBBASE)$(SO_EXT)

@libnover_frag@
@libobj_frag@
26 changes: 26 additions & 0 deletions src/plugins/preauth/otp/deps
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#
# Generated makefile dependencies follow.
#
otp_state.so otp_state.po $(OUTPRE)otp_state.$(OBJEXT): \
$(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
$(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
$(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
$(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
$(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-json.h \
$(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
$(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
$(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
$(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
$(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
otp_state.c otp_state.h
main.so main.po $(OUTPRE)main.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
$(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
$(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
$(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
$(top_srcdir)/include/k5-json.h $(top_srcdir)/include/k5-platform.h \
$(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
$(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
$(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
$(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \
$(top_srcdir)/include/socket-utils.h main.c otp_state.h

0 comments on commit 4b5dd8b

Please sign in to comment.