.. _gssapi:

=================================
Configuring GSSAPI and Cyrus SASL
=================================

This document was contributed by `Ken Hornstein <kenh@cmf.nrl.navy.mil>`_ and updated
by `Alexey Melnikov <Alexey.Melnikov@isode.com>`_.

A couple of people have asked me privately, "Hey, how did you get the
GSSAPI mechanism to work?  I tried, but the sample apps kept failing".
(The short answer: I'm a tenacious bastard).

I figured that it couldn't hurt to give a quick explanation as to
how you get GSSAPI working with the sample apps, since it wasn't
obvious to me, and I consider myself not completely ignorant of GSSAPI
and Kerberos.

Compile Cyrus SASL with GSSAPI
==============================

Compile the Cyrus-SASL distribution with the GSSAPI plugin
for your favorite GSS-API mechanism.  I personally use the GSSAPI
libraries included with the `MIT Kerberos 5 distribution <http://web.mit.edu/kerberos/www/>`_;
`Heimdal <http://www.pdc.kth.se/heimdal/>`_
and `CyberSafe <http://www.cybersafe.com>`_ work as well.

Start sample server
===================

The command-line used for
sample-server needs to specify the GSSAPI service name and the
location of the plug-ins.

* On Unix: ``./sample-server -s host -p ../plugins/.libs``
* On Windows: ``sample-server -s host -p ..\plugins``

In this example, I am using "host", which already exists on my
machine, but only root can read it, so I an running this as root.
If you want to use an alternate service name, you will need to
create that service in Kerberos, place it in a keytab readable by
you, and point your Kerberos library at it.

* On Unix: Unix: both MIT Kerberos and Heimdal, use ``/etc/krb5.keytab`` on Unix by default, but this can be changed
  by setting the ``KRB5_KTNAME`` environment variable; the default
  for CyberSafe Kerberos is ``/krb5/v5srvtab`` for UNIX systems and can be
  changed by setting the ``CSFC5KTNAME`` environment variable.
* On Windows: the default service key table location for CyberSafe is
  ``C:\Program Files\CyberSafe\v5srvtab``, unless the
  CyberSafe registry setting for the KeyTab key is set to an
  alternate path. MIT Kerberos on Windows uses the keytab filename
  krb5kt.

You should get a response similar to:

::

   Generating client mechanism list...
   Sending list of 3 mechanism(s)
   S: R1NTQVBJIFBMQUlOIEFOT05ZTU9VUw==

Note that later on (assuming everything works) you might need to paste
in lines that are longer than canonical input processing buffer on your
system.  You can get around that by messing around with stty; while
the details vary from system to system, on Solaris you can do something
like:

::

   ( stty -icanon min 1 time 0 ; ./sample-server -s host -p ../plugins/.libs )

Obtain Kerberos ticket
======================

Obtain a Kerberos ticket for the user you want to authenticate as.

::

   kinit kenh

Start up sample client
======================

You need to specify the service
name, the hostname, and the userid.  An example might be

::

   ./sample-client -s host -n your.fqdn.here -u kenh -p ../plugins/.libs

You should get a response similar to this:

::

   Waiting for mechanism list from server...

Connect Server to Client
========================

Cut-and-paste the initial mechanism line from the server process
(this includes the `` S: `` ) into the client process.  You
should get something similar to:


::

   S: R1NTQVBJIFBMQUlOIEFOT05ZTU9VUw==
   Choosing best mechanism from: GSSAPI PLAIN ANONYMOUS
   Using mechanism GSSAPI
   Preparing initial.
   Sending initial response...
   C: <.... lots of base 64 data ...>
   Waiting for server reply...

If GSSAPI isn't selected as the mechanism, there is a few things that
might have gone wrong:

* The mechanism might not have been offered by the server.  The decoded
  mechanism list offered by the server appears in the "``Choosing best
  mechanism``" line.  If GSSAPI didn't appear in that list, then
  something is wrong on the server.  Make sure that you specified the
  correct plugins directory.  If the plugin directory is correct, but
  the library fails to load, you might be running across a bug
  in libtool on some platforms.  If you have your Kerberos/gssapi
  libraries not installed in the system library path, those libraries
  are likely not able to be found when the SASL GSSAPI plugin loads.

  The solution varies from system to system; what I did was take
  the linker line generated by libtool and run it by hand, adding
  a ``-R/path/to/kerberos/libraries`` switch (this was on Solaris).
  You can check with a system call tracer to see exactly what it is
  trying to do.

* The client doesn't know about the mechanism.  The reasons for this
  happening are the same as the server: check the -p switch, check
  to make sure the correct libraries are being loaded with the GSSAPI
  plugin.

  You can turn on a healthy amount of debugging information by changing
  the definition in config.h of the VL macro to (and recompiling libsasl):

::

   #define VL(foo) printf foo;

There is a possibility
you might get an error that looks like this:

  ::

      sample-client: Starting SASL negotiation: generic failure

This can mean that you didn't provide all of the required information
to the sample-client (did you provide a service name with -s, the
hostname of the service with -n, and a username with -u ?), or that
GSSAPI has failed (unfortunately, on the client you cannot find out
the internal GSSAPI error; you will need to break out the debugger
for that).

Connect Client to Server
========================

Cut and paste the client response (The *entire* line that begins
with C:, including the initial ``C:`` ) to the server
process.  You should get a response back that starts with ``S:`` .
Cut and paste that to the client, and continue this
exchange until you either get ``Negotiation complete``, or an error.

If you get an error on the server you should get a complete error
message (including the GSSAPI error string); on the client you
unfortunately will only probably get ``generic failure``, which will
again require the use of a debugger (but the VL macro should help
with this).

One common thing that happens is that on your server you might see
the error:

::

        sample-server: Performing SASL negotiation: authentication failure
	    (Requested identity not authenticated identity)

This comes from not having a requested identity (the -u option) that
matches the identity that you were authenticated to via the GSSAPI.
This is of course mechanism specific, but if for example you're using
Kerberos, the Cyrus SASL library strips out the @REALM from your
identity if you are in the same realm as the server.  So if your
Kerberos identity is user\@SOME.REALM and the server is in SOME.REALM,
you need to specify "user" to the -u flag of the client.  If you're
accessing a server in a foreign realm, you need to pass the full
principal name via the -u option to make this work correctly.

If you complete the negotiation successfully, you should see something
that looks like (on both the client and server):

::

   Negotiation complete
   Username: kenh
   sample-server: realm: can't request info until later in exchange
   SSF: 56

If you get to that, then you've done it, and GSSAPI works successfully!
