KTH-krb
*******

Introduction
************

This is an attempt at documenting the Kerberos 4 distribution from
Kungliga Tekniska Högskolan (the Royal Institute of Technology in
Stockholm, Sweden).  This distribution is based on eBones, but has been
improved in many ways. It is more portable, and several new features
have been added. It currently runs on the following systems:

   * AIX 4.1, 4.2

   * BSD/OS 2.0, 2.1

   * Digital UNIX 3.2, 4.0

   * HP-UX 9, 10

   * IRIX 4.0, 5.2, 5.3, 6.1, 6.2, 6.3, 6.4

   * Linux 1.3, 2.0

   * NetBSD 1.2

   * FreeBSD 2.2

   * SunOS 4.1

   * SunOS 5.4/5.5 (aka Solaris 2.4/2.5)

   * Ultrix 4.4

   * Cray UNICOS 9.

   * Fujitsu UXP/V 4.1.

Some part compile and work on:

   * OS/2 with EMX

   * Windows 95/NT with gnu-win32 (with the proper amount of magic the
     libraries should compile with Microsoft C as well)

It should work on anything that is almost POSIX, has an ANSI C
compiler, a dbm library (for the server side), and BSD Sockets.

A web-page is available at `http://www.pdc.kth.se/kth-krb/'.

Bug reports
===========

If you cannot build the programs or they do not behave as you think they
should, please send us a bug report.  The bug report should be sent to
`<kth-krb-bugs@nada.kth.se>'.  Please include information on what
machine and operating system (including version) you are running, what
you are trying to do, what happens, what you think should have happened,
an example for us to repeat, the output you get when trying the example,
and a patch for the problem if you have one.  Please make any patches
with `diff -u' or `diff -c'.  The more detailed the bug report is, the
easier it will be for us to reproduce, understand, and fix it.

Suggestions, comments and other non bug reports are welcome.  Send them
to `<kth-krb@nada.kth.se>'.

What is Kerberos?
*****************

     Now this Cerberus had three heads of dogs,
             the tail of a dragon, and on his back the
             heads of all sorts of snakes.
             -- Pseudo-Apollodorus Library 2.5.12

Kerberos is a system for authenticating users and services on a network.
It is built upon the assumption that the network is "unsafe".  For
example, data sent over the network can be eavesdropped and altered, and
addresses can also be faked.  Therefore they cannot be used for
authentication purposes.

Kerberos is a trusted third-party service.  That means that there is a
third party (the kerberos server) that is trusted by all the entities on
the network (users and services, usually called "principals").  All
principals share a secret password (or key) with the kerberos server and
this enables principals to verify that the messages from the kerberos
server are authentic.  Thus trusting the kerberos server, users and
services can authenticate each other.

Basic mechanism
===============

In Kerberos, principals use "tickets" to prove that they are who they
claim to be. In the following example, A is the initiator of the
authentication exchange, usually a user, and B is the service that A
wishes to use.

To obtain a ticket for a specific service, A sends a ticket request to
the kerberos server. The request basically contains A's and B's names.
The kerberos server checks that both A and B are valid principals.

Having verified the validity of the principals, it creates a packet
containing A's and B's names, A's network address (A<ADDR>), the
current time (T<ISSUE>), the lifetime of the ticket (LIFE), and a
secret "session key" (K<AB>). This packet is encrypted with B's secret
key (K<B>).  The actual ticket (T<AB>) looks like this: ({A, B,
A<ADDR>, T<ISSUE>, LIFE, K<AB>}K<B>).

The reply to A consists of the ticket (T<AB>), B's name, the current
time, the lifetime of the ticket, and the session key, all encrypted in
A's secret key ({B, T<ISSUE>, LIFE, K<AB>, T<AB>}K<A>). A decrypts the
reply and retains it for later use.

Before sending a message to B, A creates an authenticator consisting of
A's name, A's address, the current time, and a "checksum" chosen by A,
all encrypted with the secret session key ({A, A<ADDR>, T<CURRENT>,
CHECKSUM}K<AB>). This is sent together with the ticket received from
the kerberos server to B.  Upon reception, B decrypts the ticket using
B's secret key.  Since the ticket contains the session key that the
authenticator was encrypted with, B can now also decrypt the
authenticator. To verify that A really is A, B now has to compare the
contents of the ticket with that of the authenticator. If everything
matches, B now considers A as properly authenticated.

Different attacks
=================

Impersonating A
---------------

An impostor, C could steal the authenticator and the ticket as it is
transmitted across the network, and use them to impersonate A. The
address in the ticket and the authenticator was added to make it more
difficult to perform this attack.  To succeed C will have to either use
the same machine as A or fake the source addresses of the packets. By
including the time stamp in the authenticator, C does not have much
time in which to mount the attack.

Impersonating B
---------------

C can masquerade B's network address, and when A sends her credentials,
C just pretend to verify them. C can't be sure that she is talking to A.

Defense strategies
==================

It would be possible to add a "replay cache" to the server side.  The
idea is to save the authenticators sent during the last few minutes, so
that B can detect when someone is trying to retransmit an already used
message. This is somewhat impractical (mostly regarding efficiency),
and is not part of Kerberos 4; MIT Kerberos 5 contains it.

To authenticate B, A might request that B sends something back that
proves that B has access to the session key. An example of this is the
checksum that A sent as part of the authenticator. One typical
procedure is to add one to the checksum, encrypt it with the session
key and send it back to A.  This is called "mutual authentication".

The session key can also be used to add cryptographic checksums to the
messages sent between A and B (known as "message integrity").
Encryption can also be added ("message confidentiality"). This is
probably the best approach in all cases.

Further reading
===============

The original paper on Kerberos from 1988 is `Kerberos: An
Authentication Service for Open Network Systems', by Jennifer Steiner,
Clifford Neuman and Jeffrey I. Schiller.

A less technical description can be found in `Designing an
Authentication System: a Dialogue in Four Scenes' by Bill Bryant, also
from 1988.

These and several other documents can be found on our web-page.

Installing programs
*******************

You have a choise to either build the distribution from source code or
to install binaries, if they are available for your machine.

We recommend building from sources, but using pre-compiled binaries
might be easier.  If there are no binaries available for your machine or
you want to do some specific configuration, you will have to compile
from source.

Installing from source
======================

To build this software un-tar the distribution and run the `configure'
script.

To compile successfully, you will need an ANSI C compiler, such as
`gcc'. Other compilers might also work, but setting the "ANSI
compliance" too high, might break in parts of the code, not to mention
the standard include files.

To build in a separate build tree, run `configure' in the directory
where the tree should reside.  You will need a Make that understands
VPATH correctly.  GNU Make works fine.

After building everything (which will take anywhere from a few minutes
to a long time), you can install everything in `/usr/athena' with `make
install' (running as root). It is possible to install in some other
place, but it isn't recommended. To do this you will have to run
`configure' with `--prefix=/my/path'.

If you need to change the default behavior, configure understands the
following options:

`--with-shared'
     Create shared versions of the Kerberos libraries. Not really
     recommended and might not work on all systems.

`--with-cracklib='DIR
     Use cracklib for password quality control in `kadmind'. This
     option requires cracklib with the patch from
     `ftp://ftp.pdc.kth.se/pub/krb/src/cracklib.patch'.

`--with-dictpath='DICTPATH
     This is the dictionary that cracklib should use.

`--with-socks='DIR
     If you have to traverse a firewall and it uses the SocksV5 protocol
     (`RFC 1928'), you can build with socks-support.  Point DIR to the
     directory where you have socks5 installed.  For more information
     about socks see `http://www.socks.nec.com/'.

`--with-readline='DIR
     To enable history/line editing in `ftp' and `kadmin', any present
     version of readline will be used.  If you have readline installed
     but in a place where configure does not managed to find it, you
     can use this option.  The code also looks for `libedit'.  If there
     is no library at all, the bundled version of `editline' will be
     used.

`--with-mailspool='DIR
     The configuration process tries to determine where your machine
     stores its incoming mail.  This is typically `/usr/spool/mail' or
     `/var/mail'.  If it does not work or you store your mail in some
     unusual directory, this option can be used to specify where the
     mail spool directory is located.  This directory is only accessed
     by `popper', and the mail check in `login'.

`--with-mkey='FILE
     Put the master key here, the default is `/.k'.

`--without-berkeley-db'
     If you have Berkeley DB installed, it is preferred over dbm. If
     you already are running Kerberos this option might be useful,
     since there currently isn't an easy way to convert a dbm database
     to a db one (you have to dump the old database and then load it
     with the new binaries).

Installing a binary distribution
================================

The binary distribution is supposed to be installed in `/usr/athena',
installing in some other place may work but is not recommended.  A
symlink from `/usr/athena' to the install directory should be fine.

Finishing the installation
==========================

The only program that needs to be installed setuid to root is `su'.

If `rlogin' and `rsh' are setuid to root they will fall back to
non-kerberised protocols if the kerberised ones fail for some reason.
The old protocols use reserved ports as security, and therefore the
programs have to be setuid to root. If you don't need this
functionality consider turning off the setuid bit.

`login' does not have to be setuid, as it is always run by root (users
should use `su' rather than `login').  It will print a helpful message
when not setuid to root and run by a user.

The programs intended to be run by users are located in
`/usr/athena/bin'.  Inform your users to include `/usr/athena/bin' in
their paths, or copy or symlink the binaries to some good place.  The
programs that you will want to use are: `kauth'/`kinit', `klist',
`kdestroy', `kpasswd', `ftp', `telnet', `rcp', `rsh', `rlogin', `su',
`rxtelnet', `tenletxr', `rxterm', and `xnlock'. If you are using AFS,
`afslog' and `pagsh' might also be useful.  Administrators will want to
use `kadmin' and `ksrvutil', which are located in `/usr/athena/sbin'.

`telnetd' and `rlogind' assume that `login' is located in
`/usr/athena/bin' (or whatever path you used as `--prefix'). If for
some reason you want to move `login', you will have to specify the new
location with the `-L' switch when configuring telnetd and rlogind in
`inetd.conf'.

It should be possible to replace the system's default `login' with the
kerberised `login'.  However some systems assume that login performs
some serious amount of magic that our login might not do (although
we've tried to do our best). So before replacing it on every machine,
try and see what happens.  Another thing to try is to use one of the
authentication modules (see Authentication modules) supplied.

The `login' program that we use was in an earlier life the standard
login program from NetBSD. In order to use it with a lot of weird
systems, it has been "enhanced" with features from many other logins
(Solaris, SunOS, IRIX, AIX, and others).  Some of these features are
actually useful and you might want to use them even on other systems.

`/etc/fbtab'
`/etc/logindevperm'
     Allows you to chown some devices when a user logs in on a certain
     terminal.  Commonly used to change the ownership of `/dev/mouse',
     `/dev/kbd', and other devices when someone logs in on
     `/dev/console'.

     `/etc/fbtab' is the SunOS file name and it is tried first.  If
     there is no such file then the Solaris file name
     `/etc/logindevperm' is tried.

`/etc/environment'
     This file specifies what environment variables should be set when
     a user logs in. (AIX-style)

`/etc/default/login'
     Almost the same as `/etc/environment', but the System V style.

`/etc/login.access'
     Can be used to control who is allowed to login from where and on
     what ttys. (From Wietse Venema)

Authentication modules
======================

The problem of having different authentication mechanisms has been
recognised by several vendors, and several solutions has appeared. In
most cases these solutions involve some kind of shared modules that are
loaded at run-time.  Modules for some of these systems can be found in
`lib/auth'.  Presently there are modules for Digital's SIA, Linux' PAM
(might also work on Solaris, when PAM gets supported), and IRIX'
`login' and `xdm' (in `lib/auth/afskauthlib').

Digital SIA
-----------

To install the SIA module you will have to do the following:

   * Make sure `libsia_krb4.so' is available in `/usr/athena/lib'. If
     `/usr/athena' is not on local disk, you might want to put it in
     `/usr/shlib' or someplace else. If you do, you'll have to edit
     `krb4_matrix.conf' to reflect the new location (you will also have
     to do this if you installed in some other directory than
     `/usr/athena').

   * Copy (your possibly edited) `krb4_matrix.conf' to `/etc/sia'.

   * Apply `security.patch' to `/sbin/init.d/security'.

   * Turn on KRB4 security by issuing `rcmgr set SECURITY KRB4' and
     `rcmgr set KRB4_MATRIX_CONF krb4_matrix.conf'.

   * Digital thinks you should reboot your machine, but that really
     shouldn't be necessary.  It's usually sufficient just to run
     `/sbin/init.d/security start'.

Users with local passwords (like `root') should be able to login safely.

When using Digital's xdm the `KRBTKFILE' environment variable isn't
passed along as it should (since xdm zaps the environment). Instead you
have to set `KRBTKFILE' to the correct value in
`/usr/lib/X11/xdm/Xsession'. Add a line similar to
     KRBTKFILE=/tmp/tkt`id -u`_`ps -o ppid= -p $$`; export KRBTKFILE

There is currently no support for changing passwords. Use `kpasswd'
instead.

Notes to users with Enhanced security
.....................................

Digital's `ENHANCED' (C2) security, and Kerberos solves two different
problems. C2 deals with local security, adds better control of who can
do what, auditing, and similar things. Kerberos deals with network
security.

To make C2 security work with Kerberos you will have to do the
following.

   * Replace all occurencies of `krb4_matrix.conf' with
     `krb4+c2_matrix.conf' in the directions above.

   * You must enable "vouching" in the `default' database.  This will
     make the OSFC2 module trust other SIA modules, so you can login
     without giving your C2 password. To do this use `edauth' to edit
     the default entry `/usr/tcb/bin/edauth -dd default', and add a
     `d_accept_alternate_vouching' capability, if not already present.

   * For each user that does *not* have a local C2 password, you should
     set the password expiration field to zero. You can do this for each
     user, or in the `default' table. To to this use `edauth' to set
     (or change) the `u_exp' capability to `u_exp#0'.

   * You should make sure that you use Digital's login rather than the
     one distributed by us. The easiest way to do this is to replace
     `/usr/athena/bin/login' with `/bin/login'.

At present `su' does not accept the vouching flag, so it will not work
as expected.

Also, kerberised ftp will not work with C2 passwords. You can solve this
by using both Digital's ftpd and our on different ports.

*Remember*, if you do these changes you will get a system that most
certainly does *not* fulfill the requirements of a C2 system. If C2 is
what you want, for instance if someone else is forcing you to use it,
you're out of luck.  If you use enhanced security because you want a
system that is more secure than it would otherwise be, you probably got
an even more secure system. Passwords will not be sent in the clear,
for instance.

IRIX
----

The IRIX support is a module that is compatible with Transarc's
`afskauthlib.so'.  It should work with all programs that use this
library, this should include `login' and `xdm'.

The interface is not very documented but it seems that you have to copy
`libkafs.so', `libkrb.so', and `libdes.so' to `/usr/lib', or build your
`afskauthlib.so' statically.

The `afskauthlib.so' itself is able to reside in `/usr/vice/etc',
`/usr/afsws/lib', or the current directory (wherever that is).

Appart from this it should "just work", there are no configuration
files.

PAM
---

The PAM module was written more out of curiosity that anything else. It
has not been updated for quite a while, since none of us are using
Linux, and Solaris does not support PAM yet.  We've had positive reports
from at least one person using the module, though.

To use this module you should:

   * Make sure `pam_krb4.so' is available in `/usr/athena/lib'. You
     might actually want it on local disk, so `/lib/security' might be a
     better place if `/usr/athena' is not local.

   * Look at `pam.conf.add' for examples of what to add to
     `/etc/pam.conf'.

There is currently no support for changing kerberos passwords. Use
kpasswd instead.

See also Derrick J Brashear's `<shadow@dementia.org>' Kerberos PAM
module at `ftp://ftp.dementia.org/pub/pam'. It has a lot more features,
and it is also more in line with other PAM modules.

How to set up a realm
*********************

     	Who willed you? or whose will stands but mine?
     	There's none protector of the realm but I.
     	Break up the gates, I'll be your warrantize.
     	Shall I be flouted thus by dunghill grooms?
             -- King Henry VI, 6.1

How to set up the kerberos server
=================================

Choose a realm name
-------------------

A realm is an administrative domain.  Kerberos realms are usually
written in uppercase and consist of a Internet domain name(1).  Call
your realm the same as your Internet domain name if you do not have
strong reasons for not doing so.  It will make life easier for you and
everyone else.

---------- Footnotes ----------

(1)  Using lowercase characters in the realm name might break in
mysterious ways. This really should have been fixed, but has not.

Choose a kerberos server
------------------------

You need to choose a machine to run the kerberos server program.  If
the kerberos database residing on this host is compromised, your entire
realm will be compromised.  Therefore, this machine must be as secure
as possible.  Preferably it should not run any services other than
Kerberos.  The secure-minded administrator might only allow logins on
the console.

This machine has also to be reliable.  If it is down, you will not be
able to use any kerberised services unless you have also configured a
slave server (see Install a slave kerberos server).

Running the kerberos server requires very little CPU power and a small
amount of disk. An old PC with some hundreds of megabytes of free disk
space should do fine. Most of the disk space will be used for various
logs.

Install the configuration files
-------------------------------

There are two important configuration files: `/etc/krb.conf' and
`/etc/krb.realms'.

The `krb.conf' file determines which machines are servers for different
realms.  The format of this file is:

     THIS.REALM
     THIS.REALM              kerberos.this.realm admin server
     THIS.REALM              kerberos-1.this.realm
     ANOTHER.REALM           kerberos.another.realm

The first line defines the name of the local realm. Line two defines the
name of the master kerberos server and the database administration
server for this realm.  You can define any number of kerberos slave
servers similar to the one defined in line three.  The clients will try
to contact the servers in the order they are defined in `krb.conf'.

The `admin server' clause at the first entry states that this is the
master server (the one to contact when modifying the database, such as
changing passwords). There should be only one such entry for each realm.

In the original MIT Kerberos 4 (as in most others), the server
specification could only take the form of a host-name. To facilitate
having kerberos servers in odd places (such as behind a firewall),
support has been added for ports other than the default (750), and
protocols other than UDP.

The formal syntax for an entry is now `[PROTO/]HOST[:PORT]'. PROTO is
either `udp' or `tcp', and PORT is the port to talk to. Default value
for PROTO is `udp' and for PORT whatever `kerberos-iv' is defined to be
in `/etc/services' or 750 if undefined.

You can also talk HTTP with your KDC, in that case you specify an URL,
like `http://HOST[:PORT]'. If you for some reason need to use a HTTP
proxy, you can specify the proxy in the `krb4_proxy' environment
variable, also in URL format. The default for port in this case is 80.

If the information about a realm is missing from the `krb.conf' file,
or if the information is wrong, the following methods will be tried in
order.

  1. If you have an SRV-record (`RFC 2052') for your realm it will be
     used. This record should be of the form
     `kerberos-iv.PROTOCOL.REALM', where PROTO is either `udp' or
     `tcp'. (Note: the current implementation does not look at priority
     or weight when deciding which server to talk to.)

  2. If there isn't any SRV-record, it tries to find a TXT-record for
     the same domain. The contents of the record should have the same
     format as the host specification in `krb.conf'. (Note: this is a
     temporary solution if your name server doesn't support SRV
     records. The clients should work fine with SRV records, so if your
     name server supports them, they are very much preferred.)

  3. If no valid kerberos server is found, it will try to talk udp to
     the service `kerberos-iv' with fall-back to port 750 with
     `kerberos.REALM' (which is also assumed to be the master server),
     and then `kerberos-1.REALM', `kerberos-2.REALM', and so on.

We strongly recommend that you add a CNAME `kerberos.REALM' pointing to
your kerberos master server.

The `krb.realms' file is used to find out what realm a particular host
belongs to.  An example of this file could look like:

     this.realm            THIS.REALM
     .this.realm           THIS.REALM
     foo.com               SOME.OTHER.REALM
     www.foo.com           A.STRANGE.REALM
     .foo.com              FOO.REALM

Entries starting with a dot are taken as the name of a domain. Entries
not starting with a dot are taken as a host-name. The first entry
matched is used. The entry for `this.realm' is only necessary if there
is a host named `this.realm'.

If no matching realm is found in `krb.realms', DNS is searched for the
correct realm. For example, if we are looking for host `a.b.c',
`krb4-realm.a.b.c' is first tried and then `krb4-realm.b.c' and so on.
The entry should be a TXT record containing the name of the realm, such
as:

     krb4-realm.pdc.kth.se.  7200    TXT     "NADA.KTH.SE"

If this didn't help the domain name sans the first part in uppercase is
tried.

The plain vanilla version of Kerberos doesn't have any fancy methods of
getting realms and servers so it is generally a good idea to keep
`krb.conf' and `krb.realms' up to date.

Updating /etc/services
----------------------

You should append or merge the contents of `services.append' to your
`/etc/services' files or NIS-map. Remove any unused factory installed
kerberos port definitions to avoid possible conflicts.

Most of the programs will fall back to the default ports if the port
numbers are not found in `/etc/services', but it is convenient to have
them there anyway.

Install the kerberos server
---------------------------

You should have already chosen the machine where you want to run the
kerberos server and the realm name.  The machine should also be as
secure as possible (see Choose a kerberos server) before installing
the kerberos server.  In this example, we will install a kerberos server
for the realm `FOO.SE' on a machine called `hemlig.foo.se'.

Setup the server
----------------

Login as root on the console of the kerberos server.  Add
`/usr/athena/bin' and `/usr/athena/sbin' to your path.  Run `kdb_init':

     hemlig# kdb_init
     Realm name [default  FOO.SE ]:
     You will be prompted for the database Master Password.
     It is important that you NOT FORGET this password.

     Enter Kerberos master password:
     Verifying password
     Enter Kerberos master password:

If you have set up the configuration files correctly, `kdb_init' should
choose the correct realm as the default, otherwise a (good) guess is
made.  Enter the master password.

This password will only be used for encrypting the kerberos database on
disk and for generating new random keys.  You will not have to remember
it, only to type it again when you run `kstash'.  Choose something long
and random.  Now run `kstash' using the same password:

     hemlig# kstash

     Enter Kerberos master password:

     Current Kerberos master key version is 1.

     Master key entered.  BEWARE!
     Wrote master key to /.k

After entering the same master password it will be saved in the file
`/.k' and the kerberos server will read it when needed. Write down the
master password and put it in a sealed envelope in a safe, you might
need it if your disk crashes or should you want to set up a slave
server.

`kdb_init' initializes the database with a few entries:

`krbtgt.REALM'
     The key used for authenticating to the kerberos server.

`changepw.kerberos'
     The key used for authenticating to the administrative server, i.e.
     when adding users, changing passwords, and so on.

`default'
     This entry is copied to new items when these are added.  Enter
     here the values you want new entries to have, particularly the
     expiry date.

`K.M'
     This is the master key and it is only used to verify that the
     master key that is saved un-encrypted in `/.k' is correct and
     corresponds to this database.

`kstash' only reads the master password and writes it to `/.k'.  This
enables the kerberos server to start without you having to enter the
master password.  This file (`/.k') is only readable by root and
resides on a "secure" machine.

Add a few important principals
------------------------------

Now the kerberos database has been created, containing only a few
principals.  The next step is to add a few more so that you can test
that it works properly and so that you can administer your realm without
having to use the console on the kerberos server.  Use `kdb_edit' to
edit the kerberos database directly on the server.

`kdb_edit' is intended as a bootstrapping and fall-back mechanism for
editing the database.  For normal purposes, use the `kadmin' program
(see Add users to the database).

The following example shows the adding of the principal `nisse.admin'
into the kerberos database.  This principal is used by `nisse' when
administrating the kerberos database.  Later on the normal principal
for `nisse' will be created.  Replace `nisse' and `password' with your
own username and password.

     hemlig# kdb_edit -n
     Opening database...
     Current Kerberos master key version is 1.

     Master key entered.  BEWARE!
     Previous or default values are in [brackets] ,
     enter return to leave the same, or new value.

     Principal name: <nisse>
     Instance: <admin>

     <Not found>, Create [y] ? <>

     Principal: nisse, Instance: admin, kdc_key_ver: 1
     New Password: <password>
     Verifying password
     New Password: <password>

     Principal's new key version = 1
     Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ? <>
     Max ticket lifetime (*5 minutes) [ 255 ] ? <>
     Attributes [ 0 ] ? <>
     Edit O.K.
     Principal name: <>

`kdb_edit' will loop until you hit the `return' key at the "Principal
name" prompt. Now you have added nisse as an administrator.

Start the server
----------------

     hemlig# /usr/athena/libexec/kerberos &
     Kerberos server starting
     Sleep forever on error
     Log file is /var/log/kerberos.log
     Current Kerberos master key version is 1.

     Master key entered.  BEWARE!

     Current Kerberos master key version is 1
     Local realm: FOO.SE

Try to get tickets
------------------

You can now verify that these principals have been added and that the
server is working correctly.

     hemlig# kinit
     eBones International (hemlig.foo.se)
     Kerberos Initialization
     Kerberos name: <nisse.admin>
     Password: <password>

If you do not get any error message from `kinit', then everything is
working (otherwise, see Common error messages).  Use `klist' to
verify the tickets you acquired with `kinit':

     hemlig# klist
     Ticket file:    /tmp/tkt0
     Principal:      nisse.admin@FOO.SE

     Issued           Expires          Principal
     May 24 21:06:03  May 25 07:06:03  krbtgt.FOO.SE@FOO.SE

Create initial ACL for the admin server
---------------------------------------

The admin server, `kadmind', uses a series of files to determine who has
the right to perform certain operations.  The files are:
`admin_acl.add', `admin_acl.get', `admin_acl.del', and `admin_acl.mod'.
Create these with `nisse.admin@FOO.SE' as the contents.

     hemlig# echo "nisse.admin@FOO.SE" >> /var/kerberos/admin_acl.add
     hemlig# echo "nisse.admin@FOO.SE" >> /var/kerberos/admin_acl.get
     hemlig# echo "nisse.admin@FOO.SE" >> /var/kerberos/admin_acl.mod
     hemlig# echo "nisse.admin@FOO.SE" >> /var/kerberos/admin_acl.del

Later on you may wish to add more users with administration privileges.
Make sure that you create both the administration principals and add
them to the admin server ACL.

Start the admin server
----------------------

     hemlig# /usr/athena/libexec/kadmind &
     KADM Server KADM0.0A initializing
     Please do not use 'kill -9' to kill this job, use a
     regular kill instead

     Current Kerberos master key version is 1.

     Master key entered.  BEWARE!

Add users to the database
-------------------------

Use the `kadmin' client to add users to the database:

     hemlig# kadmin -u nisse.admin -m
     Welcome to the Kerberos Administration Program, version 2
     Type "help" if you need it.
     admin:  <add nisse>
     Admin password: <nisse.admin's password>
     Maximum ticket lifetime?  (255)  [Forever]
     Attributes?  [0x00]
     Expiration date (enter yyyy-mm-dd) ?  [Sat Jan  1 05:59:00 2000]
     Password for nisse:
     Verifying password Password for nisse:
     nisse added to database.

Add whatever other users you want to have in the same way.  Verify that
a user is in the database and check the database entry for that user:

     admin:  <get nisse>
     Info in Database for nisse.:
     Max Life: 255 (Forever)   Exp Date: Sat Jan  1 05:59:59 2000

     Attribs: 00  key: 0 0
     admin:  <^D>
     Cleaning up and exiting.

Automate the startup of the servers
-----------------------------------

Add the lines that were used to start the kerberos server and the admin
server to your startup scripts (`/etc/rc' or similar).

Install the client programs
===========================

Making a machine a kerberos client only requires a few steps.  First you
might need to change the configuration files as with the kerberos
server.  (see Install the configuration files and Install the /etc/services.)
Also you need to make the programs in
`/usr/athena/bin' available.  This can be done by adding the
`/usr/athena/bin' directory to the users' paths, by making symbolic
links, or even by copying the programs.

You should also verify that the local time on the client is synchronised
with the time on the kerberos server by some means. The maximum allowed
time difference between the participating servers and a client is 5
minutes.  One good way to synchronize the time is NTP (Network Time
Protocol), see `http://www.eecis.udel.edu/~ntp/'.

If you need to run the client programs on a machine where you do not
have root-access, you can hopefully just use the binaries and no
configuration will be needed.  The heuristics used are mentioned above
(see Install the configuration files).  If this is not the case
and you need to have `krb.conf' and/or `krb.realms', you can copy them
into a directory of your choice and set the environment variable
KRBCONFDIR to point at this directory.

To test the client functionality, run the `kinit' program:

     foo$ kinit
     eBones International (foo.foo.se)
     Kerberos Initialization
     Kerberos name: <nisse>
     Password: <password>

     foo$ klist
     Ticket file:    /tmp/tkt4711
     Principal:      nisse@FOO.SE

     Issued           Expires          Principal
     May 24 21:06:03  May 25 07:06:03  krbtgt.FOO.SE@FOO.SE

Install the kerberised services
===============================

These includes `rsh', `rlogin', `telnet', `ftp', `rxtelnet', and so on.

First follow the steps mentioned in the prior section to make it a
client and verify its operation.  Change `inetd.conf' next to use the
new daemons.  Look at the file `etc/inetd.conf.changes' to see the
changes that we recommend you perform on `inetd.conf'.

You should at this point decide what services you want to run on each
machine.

rsh, rlogin, and rcp
--------------------

These exist in kerberised versions and "old-style" versions.  The
different versions use different port numbers, so you can choose none,
one, or both.  If you do not want to use "old-style" r* services, you
can let the programs output the text "Remote host requires Kerberos
authentication" instead of just refusing connections to that port.
This is enabled with the `-v' option.  The kerberised services exist in
encrypted and non-encrypted versions.  The encrypted services have an
"e" prepended to the name and the programs take `-x' as an option
indicating encryption.

Our recommendation is to only use the kerberised services and give
explanation messages for the old ports.

telnet
------

The telnet service always uses the same port and negotiates as to which
authentication method should be used.  The `telnetd' program has an
option "-a user" that only allows kerberised and authenticated
connections.  If this is not included, it falls back to using clear text
passwords.  For obvious reasons, we recommend that you enable this
option.  If you want to use one-time passwords (see One-Time Passwords)
you can use the "-a otp" option which will allow OTPs or
kerberised connections.

ftp
---

The ftp service works as telnet does, with just one port being used.  By
default only kerberos authenticated connections are allowed.  You can
specify additional levels that are thus allowed with these options:

`-a otp'
     Allow one-time passwords (see One-Time Passwords).

`-a ftp'
     Allow anonymous login (as user "ftp" or "anonymous").

`-a safe'
     The same as `-a ftp', for backwards compatibility.

`-a plain'
     Allow clear-text passwords.

`-a none'
     The same as `-a ftp -a plain'.

`-a user'
     A no-op, also there for backwards compatibility reasons.

When running anonymous ftp you should read the man page on `ftpd' which
explains how to set it up.

pop
---

The Post Office Protocol (POP) is used to retrieve mail from the mail
hub.  The `popper' program implements the standard POP3 protocol and
the kerberised KPOP.  Use the `-k' option to run the kerberos version
of the protocol. This service should only be run on your mail hub.

kx
--

`kx' allows you to run X over a kerberos-authenticated and encrypted
connection.  This program is used by `rxtelnet', `tenletxr', and
`rxterm'.

If you have some strange kind of operating system with X libraries that
do not allow you to use unix-sockets, you need to specify the `-t'
option to `kxd'.  Otherwise it should be sufficient by adding the
daemon in `inetd.conf'.

kauth
-----

This service allows you to create tickets on a remote host.  To enable
it just insert the corresponding line in `inetd.conf'.

srvtabs
=======

In the same way every user needs to have a password registered with the
kerberos server, every service needs to have a shared key with the
kerberos server.  The service keys are stored in a file, usually called
`/etc/srvtab'.  This file should not be readable to anyone but root, in
order to keep the key from being divulged.  The name of this principal
in the kerberos database is usually the service and the host.  The key
for the pop service is called `pop.HOSTNAME'.  The one for
rsh/rlogin/telnet is named `rcmd.HOSTNAME'.  (rcmd comes from "remote
command").  To create these keys you will use the the `ksrvutil'
program.  Perform the following:

     bar# ksrvutil -p nisse.admin get
     Name [rcmd]: <>
     Instance [bar]: <>
     Realm [FOO.SE]: <>
     Is this correct? (y,n) [y] <>
     Add more keys? (y,n) [n] <>
     Password for nisse.admin@FOO.SE: <nisse.admin's password>
     Written rcmd.bar
     rcmd.bar@FOO.SE
     Old keyfile in /etc/srvtab.old.

Complete test of the kerberised services
----------------------------------------

Obtain a ticket on one machine (`foo') and use it to login with a
kerberised service to a second machine (`bar').  The test should look
like this if successful:

     foo$ kinit nisse
     eBones International (foo.foo.se)
     Kerberos Initialization for "nisse"
     Password: <nisse's password>
     foo$ klist
     Ticket file:    /tmp/tkt4711
     Principal:      nisse@FOO.SE

     Issued           Expires          Principal
     May 30 13:48:03  May 30 23:48:03  krbtgt.FOO.SE@FOO.SE
     foo$ telnet bar
     Trying 17.17.17.17...
     Connected to bar.foo.se
     Escape character is '^]'.
     [ Trying mutual KERBEROS4 ... ]
     [ Kerberos V4 accepts you ]
     [ Kerberos V4 challenge successful ]
     bar$

You can also try with `rsh', `rcp', `rlogin', `rlogin -x', and some
other commands to see that everything is working all right.

Install a slave kerberos server
===============================

It is desirable to have at least one backup (slave) server in case the
master server fails. It is possible to have any number of such slave
servers but more than three usually doesn't buy much more redundancy.

First select a good server machine.  See Choose a kerberos server.
Since the master and slave servers will use copies of the same
database, they need to use the same master key.

On the master, add a `rcmd.kerberos' principal (using `ksrvutil get').
The `kprop' program, running on the master, will use this when
authenticating to the `kpropd' daemons running on the slave servers.

On your master server, create a file, e.g. `/var/kerberos/slaves', that
contains the hostnames of your kerberos slave servers.

Start `kpropd' with `kpropd -i' on your slave servers.

On your master server, create a dump of the database with `kdb_util
slave_dump /var/kerberos/slave_dump', and then run `kprop'.

You should now have copies of the database on your slave servers. You
can verify this by issuing `kdb_util dump FILE' on your slave servers,
and comparing with the original file on the master server. Note that
the entries will not be in the same order.

This procedure should be automated with a script run regularly by cron,
for instance once an hour.

To start the kerberos server on slaves, you first have to copy the
master key from the master server. You can do this either by remembering
the master password and issuing `kstash', or you can just copy the
keyfile. Remember that if you copy the file, do so on a safe media, not
over the network. Good means include floppy or paper. Paper is better,
since it is easier to swallow afterwards.

The kerberos server should be started with `-s' on the slave servers.
This enables sanity checks, for example checking the time since the
last update from the master.

All changes to the database are made by `kadmind' at the master, and
then propagated to the slaves, so you should *not* run `kadmind' on the
slaves.

Finally add the slave servers to `/etc/krb.conf'. The clients will ask
the servers in the order specified by that file.

Consider adding CNAMEs to your slave servers, see Install the configuration files.

Cross-realm functionality
=========================

Suppose you are residing in the realm `MY.REALM', how do you
authenticate to a server in `OTHER.REALM'? Having valid tickets in
`MY.REALM' allows you to communicate with kerberised services in that
realm. However, the computer in the other realm does not have a secret
key shared with the kerberos server in your realm.

It is possible to add a shared key between two realms that trust each
other. When a client program, such as `telnet', finds that the other
computer is in a different realm, it will try to get a ticket granting
ticket for that other realm, but from the local kerberos server. With
that ticket granting ticket, it will then obtain service tickets from
the kerberos server in the other realm.

To add this functionality you have to add a principal to each realm. The
principals should be `krbtgt.OTHER.REALM' in `MY.REALM', and
`krbtgt.MY.REALM' in `OTHER.REALM'. The two different principals should
have the same key (and key version number).  Remember to transfer this
key in a safe manner. This is all that is required.

     blubb$ klist
     Ticket file:    /tmp/tkt3008
     Principal:      joda@NADA.KTH.SE

       Issued           Expires          Principal
     Jun  7 02:26:23  Jun  7 12:26:23  krbtgt.NADA.KTH.SE@NADA.KTH.SE
     blubb$ telnet agat.e.kth.se
     Trying 130.237.48.12...
     Connected to agat.e.kth.se.
     Escape character is '^]'.
     [ Trying mutual KERBEROS4 ... ]
     [ Kerberos V4 accepts you ]
     [ Kerberos V4 challenge successful ]
     Last login: Sun Jun  2 20:51:50 from emma.pdc.kth.se

     agat$ exit
     Connection closed by foreign host.
     blubb$ klist
     Ticket file:    /tmp/tkt3008
     Principal:      joda@NADA.KTH.SE

       Issued           Expires          Principal
     Jun  7 02:26:23  Jun  7 12:26:23  krbtgt.NADA.KTH.SE@NADA.KTH.SE
     Jun  7 02:26:50  Jun  7 12:26:50  krbtgt.E.KTH.SE@NADA.KTH.SE
     Jun  7 02:26:51  Jun  7 12:26:51  rcmd.agat@E.KTH.SE

One-Time Passwords
******************

There is also support for using "one time passwords" (OTP) in this
package.  Specifically `login', `ftpd', and `popper' have support for
using them.

What are one time passwords?
============================

One time passwords are, as the name implies, passwords that can only be
used once.  This means that even if someone is eavesdropping on the
network, they will not be able to make use of the passwords they steal.

The OTPs used in this package support `RFC 1938'.  This standard is
also backwards compatible with the well-known S/Key.  There are lots of
programs for generating these on everything from HP 48's to Crays.

When to use one time passwords?
===============================

Why would you want to use OTPs instead of Kerberos?  The advantage of
OTPs is that they don't require a computer to operate.  You can print
out a list of passwords and take with you, or you could use your
calculator or hand-held computer to generate them.

The downside is that they only protect you against passive attacks.
Only the initial connection is authenticated.  After that, anyone can
eavesdrop on your session, so you should not send or view any sensitive
data (e.g. passwords) over a OTP-initiated link.  You are also
vulnerable to active attacks where intruders try to take over your
TCP-session and/or introduce data in the middle of it.  In other words,
they provide initial authentication, but neither integrity nor
confidentiality.

The OTPs are generated from the tuple (SEED, SEQUENCE NUMBER,
PASS-PHRASE).  The seed and the sequence number will be printed as part
of the "challenge" and you will have to generate the corresponding
password or pick it from a list.

In conclusion, they are simple and can be used everywhere but don't
protect against all threats that Kerberos does.  Use them when you can't
use Kerberos.

Configuring OTPs
================

Initializing
============

To initialize your OTPs use the `otp' program.  This program will write
an entry in a local file on this host with your current password (in
this case the 100th) and the corresponding seed (`foobar').

     datan:>otp 100 foobar
     Pass-phrase: <pass-phrase>
     Verifying password Pass-phrase: <pass-phrase>

Generating
==========

To print out a list of them there is a program called `otpprint'.

     datan:>otpprint 100 foobar
     Pass-phrase: <pass-phrase>
     91: SLAM BUY SUP DUSK SKY BEST
     92: DEEM SIGH ROB RASH JUG MAT
     93: DUET FISK HERS AREA TOLL SUP
     94: WOW RAIN LEAK SARA MARK WING
     95: COG YELL MILK CART ABE BAWL
     96: GROW SILK GIST OMEN CAM ANNE
     97: JAG QUAD NUT BEAT BHOY MAGI
     98: ADAM USED GENE NIP EYE SIS
     99: MY SUNG HERO AT DASH RAKE
     100: CORN KNIT BOTH TOGO SOUL BOG

Using the OTPs
==============

When you try to use one and have initialized a series of one-time
passwords for yourself you will get a challenge with the algorithm
being used, the sequence number, and the seed.  Enter those in your
generator or find the corresponding password in your list.

     login: assar
     assar's [ otp-md5 99 foobar ] Password: <MY SUNG HERO AT DASH RAKE>

The sequence number of the password will start at one less that the
number you gave to `otp' and decrease by one every time you use it.
You should try to keep track of which should be the current one so that
you can be assured that nobody has stolen some of your passwords and
used them.  When the number has reached zero you need to acquire a new
series of passwords.

Once you have initialized your series of passwords, you can always use
them at any password prompt where you get the challenge as shown above.

Configuring servers
===================

`ftpd', `telnetd', and `popper' can be configured to require one-time
passwords when the connection has not been kerberos authenticated.
Check the man pages for these programs for the correct options.

Resolving frequent problems
***************************

Problems compiling Kerberos
===========================

Many compilers require a switch to become ANSI compliant. Since kth-krb
is written in ANSI C it is necessary to specify the name of the compiler
to be used and the required switch to make it ANSI compliant. This is
most easily done when running configure using the `env' command. For
instance to build under HP-UX using the native compiler do:

     datan$ env CC="cc -Ae" ./configure

In general `gcc' works. The following combinations have also been
verified to successfully compile the distribution:

`HP-UX'
     `cc -Ae'

`Digital UNIX'
     `cc -std1'

`AIX'
     `xlc'

`Solaris 2.x'
     `cc' (unbundled one)

`IRIX'
     `cc'

Linux problems
--------------

Some systems have lost `/usr/include/ndbm.h' which is necessary to
build kth-krb correctly. There is a `ndbm.h.Linux' right next to the
source distribution.

There has been reports of non-working `libdb' on some Linux
distributions.  If that happens, use the `--without-berkeley-db' when
configuring.

HP-UX problems
--------------

The shared library `/usr/lib/libndbm.sl' doesn't exist on all systems.
To make problems even worse, there is never an archive version for
static linking either. Therefore, when building "truly portable"
binaries first install GNU gdbm or Berkeley DB, and make sure that you
are linking against that library.

Cray problems
-------------

`rlogind' won't work on Crays until `forkpty()' has been ported, in the
mean time use `telnetd'.

AIX problems
------------

`gcc' version 2.7.2.1 has a bug which makes it miscompile
`appl/telnet/telnetd/sys_term.c' (and possibily `appl/bsd/forkpty.c'),
if used with too much optimization.

C2 problems
-----------

The programs that checks passwords works with `passwd', OTP, and
Kerberos paswords. This is problem if you use C2 security (or use some
other password database), that normally keeps passwords in some obscure
place. If you want to use Kerberos with C2 security you will have to
think about what kind of changes are necessary. See also the discussion
about Digital's SIA and C2 security, see Digital SIA.

Common error messages
=====================

These are some of the more obscure error messages you might encounter:

`Time is out of bounds'
     The time on your machine differs from the time on either the
     kerberos server or the machine you are trying to login to. If it
     isn't obvious that this is the case, remember that all times are
     compared in UTC.

     On unix systems you usually can find out what the local time is by
     doing `telnet machine daytime'. This time (again, usually is the
     keyword) is with correction for time-zone and daylight savings.

     If you have problem keeping your clocks synchronized, consider
     using a time keeping system such as NTP (see also the discussion in
     Install the client programs).

`Ticket issue date too far in the future'
     The time on the kerberos server is more than five minutes ahead of
     the time on the server.

`Can't decode authenticator'
     This means that there is a mismatch between the service key in the
     kerberos server and the service key file on the specific machine.
     Either:
        * the server couldn't find a service key matching the request

        * the service key (or version number) does not match the key
          the packet was encrypted with

`Incorrect network address'
     The address in the ticket does not match the address you sent the
     request from. This happens on systems with more than one network
     address, either physically or logically. You can list addresses
     which should be considered equal in `/etc/krb.equiv' on your
     servers.

     A note to programmers: a server should not pass `*' as the instance
     to `krb_rd_req'. It should try to figure out on which interface the
     request was received, for instance by using `k_getsockinst'.

     If you change addresses on your computer you invalidate any
     tickets you might have. The easiest way to fix this is to get new
     tickets with the new address.

`Message integrity error'
     The packet is broken in some way:
        * the lengths does not match the size of the packet, or

        * the checksum does not match the contents of the packet

`Can't send request'
     There is some problem contacting the kerberos server. Either the
     server is down, or it is using the wrong port (compare the entries
     for `kerberos-iv' in `/etc/services'). The client might also have
     failed to guess what kerberos server to talk to (check
     `/etc/krb.conf' and `/etc/krb.realms').

`kerberos: socket: Unable to open socket...'
     The kerberos server has to open four sockets for each interface.
     If you have a machine with lots of virtual interfaces, you run the
     risk of running out of file descriptors.  If that happens you will
     get this error message.

`ftp: User foo access denied'
     This usually happens because the user's shell is not listed in
     `/etc/shells'.  Note that `ftpd' checks this file even on systems
     where the system version does not and there is no `/etc/shells'.

`Generic kerberos error'
     This is a generic catch-all error message.

Acknowledgments
***************

People from the MIT Athena project wrote the original code that this is
based on. Kerberos 4 patch-level 9 was stripped of both the encryption
functions and the calls to them. This was exported from the US as the
"Bones" release.  Eric Young put back the calls and hooked in his
libdes, thereby creating the "eBones" release.

The "rcmd" programs where initially developed at the University of
California at Berkeley and then hacked on by the FreeBSD and NetBSD
projects.

Berkeley also wrote `ftp', `ftpd', `telnet', and `telnetd'.  The
authentication and encryption code of `telnet' and `telnetd' was added
by David Borman (then of Cray Research, Inc).  The encryption code was
removed when this was exported and then added back by Juha Eskelinen,
`<esc@magic.fi>'.

The `popper' was also a Berkeley program initially.

The `login' has the same origins but has received code written by
Wietse Venema at Eindhoven University of Technology, The Netherlands.

`movemail' was (at least partially) written by Jonathan Kamens,
`<jik@security.ov.com>', and is Copyright (C) 1986, 1991, 1992, 1993,
1994 Free Software Foundation, Inc.

`xnlock' was originally written by Dan Heller in 1985 for sunview.  The
X version was written by him in 1990.

Some of the functions in `libroken' also come from Berkeley by the way
of NetBSD/FreeBSD.

The code to handle the dynamic loading of the AFS module for AIX is
copyright (C) 1992 HELIOS Software GmbH 30159 Hannover, Germany.

`editline' was written by Simmule Turner and Rich Salz.

Bugfixes and code has been contributed by:
Derrick J Brashear
     `<shadow@dementia.org>'

Anders Gertz
     `<gertz@lysator.liu.se>'

Dejan Ilic
     `<svedja@lysator.liu.se>'

Kent Engström
     `<kent@lysator.liu.se>'

Simon Josefsson
     `<jas@pdc.kth.se>'

Robert Malmgren
     `<rom@incolumitas.se>'

Fredrik Ljungberg
     `<flag@it.kth.se>'

Lars Malinowsky
     `<lama@pdc.kth.se>'

Fabien Coelho
     `<coelho@cri.ensmp.fr>'

and we hope that those not mentioned here will forgive us.
Ian Marsh `<ianm@sics.se>' removed the worst abuses of the English
language from this text.

Ilja Hallberg `<iha@incolumitas.se>' is still promising to help us
finish the documentation.

This work was supported in part by SUNET and the Centre for Parallel
Computers at KTH.

The port to Windows 95/NT was supported by the Computer Council at KTH
and done by Jörgen Karlsson `<d93-jka@nada.kth.se>'.

All the bugs were introduced by ourselves.