
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@22546 ec53bebd-3082-4978-b11e-865c3cabbd6b
687 lines
23 KiB
C
687 lines
23 KiB
C
/*
|
|
* Copyright (c) 2007-2008 Kungliga Tekniska Högskolan
|
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of the Institute nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
#include "krb5_locl.h"
|
|
RCSID("$Id$");
|
|
|
|
/**
|
|
*
|
|
*/
|
|
|
|
/*! @mainpage Heimdal Kerberos 5 library
|
|
*
|
|
* @section intro Introduction
|
|
*
|
|
* Heimdal libkrb5 library is a implementation of the Kerberos
|
|
* protocol.
|
|
*
|
|
* 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.
|
|
*
|
|
*
|
|
* - @ref page_introduction
|
|
* - @ref page_fileformats
|
|
*
|
|
* The project web page:\n
|
|
* http://www.h5l.org/
|
|
*
|
|
*/
|
|
|
|
/** @defgroup krb5 Heimdal Kerberos 5 library */
|
|
/** @defgroup krb5_address Heimdal Kerberos 5 address functions */
|
|
/** @defgroup krb5_ccache Heimdal Kerberos 5 credential cache functions */
|
|
/** @defgroup krb5_credential Heimdal Kerberos 5 credential handing functions */
|
|
/** @defgroup krb5_deprecated Heimdal Kerberos 5 deprecated functions */
|
|
/** @defgroup krb5_digest Heimdal Kerberos 5 digest service */
|
|
/** @defgroup krb5_error Heimdal Kerberos 5 error reporting functions */
|
|
/** @defgroup krb5_v4compat Heimdal Kerberos 4 compatiblity functions */
|
|
/** @defgroup krb5_support Heimdal Kerberos 5 support functions */
|
|
|
|
|
|
/*!
|
|
|
|
@page page_introduction Introduction to the Kerberos 5 API
|
|
|
|
@section api_overview Kerberos 5 API Overview
|
|
|
|
All functions are documented in manual pages. This section tries to
|
|
give an overview of the major components used in Kerberos library, and
|
|
point to where to look for a specific function.
|
|
|
|
@subsection krb5_context Kerberos context
|
|
|
|
A kerberos context (krb5_init_context()) holds all per thread state. All global variables that
|
|
are context specific are stored in this structure, including default
|
|
encryption types, credential cache (for example, a ticket file), and default realms.
|
|
|
|
See the manual pages for krb5_init_context().
|
|
|
|
@subsection krb5_auth_context Kerberos authentication context
|
|
|
|
Kerberos authentication context (krb5_auth_context) holds all
|
|
context related to an authenticated connection, in a similar way to the
|
|
kerberos context that holds the context for the thread or process.
|
|
|
|
The krb5_auth_context is used by various functions that are
|
|
directly related to authentication between the server/client. Example of
|
|
data that this structure contains are various flags, addresses of client
|
|
and server, port numbers, keyblocks (and subkeys), sequence numbers,
|
|
replay cache, and checksum types.
|
|
|
|
@subsection krb5_principal Kerberos principal
|
|
|
|
The Kerberos principal is the structure that identifies a user or
|
|
service in Kerberos. The structure that holds the principal is the
|
|
krb5_principal. There are function to extract the realm and
|
|
elements of the principal, but most applications have no reason to
|
|
inspect the content of the structure.
|
|
|
|
The are several ways to create a principal (with different degree of
|
|
portability), and one way to free it.
|
|
|
|
See manual page for krb5_principal for more information
|
|
about the functions.
|
|
|
|
@subsection krb5_ccache Credential cache
|
|
|
|
A credential cache holds the tickets for a user. A given user can have
|
|
several credential caches, one for each realm where the user have the
|
|
initial tickets (the first krbtgt).
|
|
|
|
The credential cache data can be stored internally in different way, each of them for
|
|
different proposes. File credential (FILE) caches and processes based
|
|
(KCM) caches are for permanent storage. While memory caches (MEMORY)
|
|
are local caches to the local process.
|
|
|
|
Caches are opened with krb5_cc_resolve() or created with
|
|
krb5_cc_gen_unique.
|
|
|
|
If the cache needs to be opened again (using
|
|
krb5_cc_resolve()) krb5_cc_close() will close the
|
|
handle, but not the remove the cache. krb5_cc_destroy() will
|
|
zero out the cache, remove the cache so it can no longer be
|
|
referenced.
|
|
|
|
See also manual page for krb5_ccache.
|
|
|
|
@subsection krb5_error_code Kerberos errors
|
|
|
|
Kerberos errors are based on the com_err library. All error codes are
|
|
32-bit signed numbers, the first 24 bits define what subsystem the
|
|
error originates from, and last 8 bits are 255 error codes within the
|
|
library. Each error code have fixed string associated with it. For
|
|
example, the error-code -1765328383 have the symbolic name
|
|
KRB5KDC_ERR_NAME_EXP, and associated error string ``Client's entry in
|
|
database has expired''.
|
|
|
|
This is a great improvement compared to just getting one of the unix
|
|
error-codes back. However, Heimdal have an extention to pass back
|
|
customised errors messages. Instead of getting ``Key table entry not
|
|
found'', the user might back ``failed to find
|
|
host/host.example.com\@EXAMLE.COM(kvno 3) in keytab /etc/krb5.keytab
|
|
(des-cbc-crc)''. This improves the chance that the user find the
|
|
cause of the error so you should use the customised error message
|
|
whenever it's available.
|
|
|
|
See also manual page for krb5_get_error_string and
|
|
krb5_get_err_text.
|
|
|
|
@subsection krb5_keytab Keytab management
|
|
|
|
A keytab is a storage for locally stored keys. Heimdal includes keytab
|
|
support for Kerberos 5 keytabs, Kerberos 4 srvtab, AFS-KeyFile's,
|
|
and for storing keys in memory.
|
|
|
|
Keytabs are used for servers and long-running services.
|
|
|
|
See also manual page for krb5_kt_resolve().
|
|
|
|
@subsection krb5_crypto Kerberos crypto
|
|
|
|
Heimdal includes a implementation of the Kerberos crypto framework,
|
|
all crypto operations.
|
|
|
|
See also manual page for krb5_crypto_init(), krb5_create_checksum(),
|
|
and krb5_encrypt().
|
|
|
|
@section kerberos5_client Walkthrough of a sample Kerberos 5 client
|
|
|
|
This example contains parts of a sample TCP Kerberos 5 clients, if you
|
|
want a real working client, please look in appl/test directory in
|
|
the Heimdal distribution.
|
|
|
|
All Kerberos error-codes that are returned from kerberos functions in
|
|
this program are passed to krb5_err, that will print a
|
|
descriptive text of the error code and exit. Graphical programs can
|
|
convert error-code to a human readable error-string with the
|
|
krb5_get_err_text function.
|
|
|
|
Note that you should not use any Kerberos function before
|
|
krb5_init_context() have completed successfully. That is the
|
|
reason err() is used when krb5_init_context() fails.
|
|
|
|
First the client needs to call krb5_init_context to initialise
|
|
the Kerberos 5 library. This is only needed once per thread
|
|
in the program. If the function returns a non-zero value it indicates
|
|
that either the Kerberos implementation is failing or it's disabled on
|
|
this host.
|
|
|
|
@code
|
|
#include <krb5.h>
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
krb5_context context;
|
|
|
|
if (krb5_context(&context))
|
|
errx (1, "krb5_context");
|
|
@endcode
|
|
|
|
Now the client wants to connect to the host at the other end. The
|
|
preferred way of doing this is using getaddrinfo (for
|
|
operating system that have this function implemented), since getaddrinfo
|
|
is neutral to the address type and can use any protocol that is available.
|
|
|
|
@code
|
|
struct addrinfo *ai, *a;
|
|
struct addrinfo hints;
|
|
int error;
|
|
|
|
memset (&hints, 0, sizeof(hints));
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
hints.ai_protocol = IPPROTO_TCP;
|
|
|
|
error = getaddrinfo (hostname, "pop3", &hints, &ai);
|
|
if (error)
|
|
errx (1, "%s: %s", hostname, gai_strerror(error));
|
|
|
|
for (a = ai; a != NULL; a = a->ai_next) {
|
|
int s;
|
|
|
|
s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
|
|
if (s < 0)
|
|
continue;
|
|
if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
|
|
warn ("connect(%s)", hostname);
|
|
close (s);
|
|
continue;
|
|
}
|
|
freeaddrinfo (ai);
|
|
ai = NULL;
|
|
}
|
|
if (ai) {
|
|
freeaddrinfo (ai);
|
|
errx ("failed to contact %s", hostname);
|
|
}
|
|
@endcode
|
|
|
|
Before authenticating, an authentication context needs to be
|
|
created. This context keeps all information for one (to be) authenticated
|
|
connection (see krb5_auth_context).
|
|
|
|
@code
|
|
status = krb5_auth_con_init (context, &auth_context);
|
|
if (status)
|
|
krb5_err (context, 1, status, "krb5_auth_con_init");
|
|
@endcode
|
|
|
|
For setting the address in the authentication there is a help function
|
|
krb5_auth_con_setaddrs_from_fd that does everything that is needed
|
|
when given a connected file descriptor to the socket.
|
|
|
|
@code
|
|
status = krb5_auth_con_setaddrs_from_fd (context,
|
|
auth_context,
|
|
&sock);
|
|
if (status)
|
|
krb5_err (context, 1, status,
|
|
"krb5_auth_con_setaddrs_from_fd");
|
|
@endcode
|
|
|
|
The next step is to build a server principal for the service we want
|
|
to connect to. (See also krb5_sname_to_principal.)
|
|
|
|
@code
|
|
status = krb5_sname_to_principal (context,
|
|
hostname,
|
|
service,
|
|
KRB5_NT_SRV_HST,
|
|
&server);
|
|
if (status)
|
|
krb5_err (context, 1, status, "krb5_sname_to_principal");
|
|
@endcode
|
|
|
|
The client principal is not passed to krb5_sendauth
|
|
function, this causes the krb5_sendauth function to try to figure it
|
|
out itself.
|
|
|
|
The server program is using the function krb5_recvauth to
|
|
receive the Kerberos 5 authenticator.
|
|
|
|
In this case, mutual authentication will be tried. That means that the server
|
|
will authenticate to the client. Using mutual authentication
|
|
is good since it enables the user to verify that they are talking to the
|
|
right server (a server that knows the key).
|
|
|
|
If you are using a non-blocking socket you will need to do all work of
|
|
krb5_sendauth yourself. Basically you need to send over the
|
|
authenticator from krb5_mk_req and, in case of mutual
|
|
authentication, verifying the result from the server with
|
|
krb5_rd_rep.
|
|
|
|
@code
|
|
status = krb5_sendauth (context,
|
|
&auth_context,
|
|
&sock,
|
|
VERSION,
|
|
NULL,
|
|
server,
|
|
AP_OPTS_MUTUAL_REQUIRED,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
if (status)
|
|
krb5_err (context, 1, status, "krb5_sendauth");
|
|
@endcode
|
|
|
|
Once authentication has been performed, it is time to send some
|
|
data. First we create a krb5_data structure, then we sign it with
|
|
krb5_mk_safe using the auth_context that contains the
|
|
session-key that was exchanged in the
|
|
krb5_sendauth/krb5_recvauth authentication
|
|
sequence.
|
|
|
|
@code
|
|
data.data = "hej";
|
|
data.length = 3;
|
|
|
|
krb5_data_zero (&packet);
|
|
|
|
status = krb5_mk_safe (context,
|
|
auth_context,
|
|
&data,
|
|
&packet,
|
|
NULL);
|
|
if (status)
|
|
krb5_err (context, 1, status, "krb5_mk_safe");
|
|
@endcode
|
|
|
|
And send it over the network.
|
|
|
|
@code
|
|
len = packet.length;
|
|
net_len = htonl(len);
|
|
|
|
if (krb5_net_write (context, &sock, &net_len, 4) != 4)
|
|
err (1, "krb5_net_write");
|
|
if (krb5_net_write (context, &sock, packet.data, len) != len)
|
|
err (1, "krb5_net_write");
|
|
@endcode
|
|
|
|
To send encrypted (and signed) data krb5_mk_priv should be
|
|
used instead. krb5_mk_priv works the same way as
|
|
krb5_mk_safe, with the exception that it encrypts the data
|
|
in addition to signing it.
|
|
|
|
@code
|
|
data.data = "hemligt";
|
|
data.length = 7;
|
|
|
|
krb5_data_free (&packet);
|
|
|
|
status = krb5_mk_priv (context,
|
|
auth_context,
|
|
&data,
|
|
&packet,
|
|
NULL);
|
|
if (status)
|
|
krb5_err (context, 1, status, "krb5_mk_priv");
|
|
@endcode
|
|
|
|
And send it over the network.
|
|
|
|
@code
|
|
len = packet.length;
|
|
net_len = htonl(len);
|
|
|
|
if (krb5_net_write (context, &sock, &net_len, 4) != 4)
|
|
err (1, "krb5_net_write");
|
|
if (krb5_net_write (context, &sock, packet.data, len) != len)
|
|
err (1, "krb5_net_write");
|
|
|
|
@endcode
|
|
|
|
The server is using krb5_rd_safe and
|
|
krb5_rd_priv to verify the signature and decrypt the packet.
|
|
|
|
@section krb5_verify_user Validating a password in an application
|
|
|
|
See the manual page for krb5_verify_user.
|
|
|
|
@section mit_differences API differences to MIT Kerberos
|
|
|
|
This section is somewhat disorganised, but so far there is no overall
|
|
structure to the differences, though some of the have their root in
|
|
that Heimdal uses an ASN.1 compiler and MIT doesn't.
|
|
|
|
@subsection mit_krb5_principal Principal and realms
|
|
|
|
Heimdal stores the realm as a krb5_realm, that is a char *.
|
|
MIT Kerberos uses a krb5_data to store a realm.
|
|
|
|
In Heimdal krb5_principal doesn't contain the component
|
|
name_type; it's instead stored in component
|
|
name.name_type. To get and set the nametype in Heimdal, use
|
|
krb5_principal_get_type and
|
|
krb5_principal_set_type.
|
|
|
|
For more information about principal and realms, see
|
|
krb5_principal.
|
|
|
|
@subsection mit_krb5_error_code Error messages
|
|
|
|
To get the error string, Heimdal uses
|
|
krb5_get_error_string or, if NULL is returned,
|
|
krb5_get_err_text. This is to return custom error messages
|
|
(like ``Can't find host/datan.example.com\@CODE.COM in
|
|
/etc/krb5.conf.'' instead of a ``Key table entry not found'' that
|
|
error_message returns.
|
|
|
|
Heimdal uses a threadsafe(r) version of the com_err interface; the
|
|
global com_err table isn't initialised. Then
|
|
error_message returns quite a boring error string (just
|
|
the error code itself).
|
|
|
|
|
|
*/
|
|
|
|
|
|
/*!
|
|
|
|
|
|
@page page_fileformats File formats
|
|
|
|
@section fileformats File formats
|
|
|
|
This section documents the diffrent file formats that are used in
|
|
Heimdal and other Kerberos implementations.
|
|
|
|
@subsection file_keytab keytab
|
|
|
|
The keytab binary format is not a standard format. The format has
|
|
evolved and may continue to. It is however understood by several
|
|
Kerberos implementations including Heimdal, MIT, Sun's Java ktab and
|
|
are created by the ktpass.exe utility from Windows. So it has
|
|
established itself as the defacto format for storing Kerberos keys.
|
|
|
|
The following C-like structure definitions illustrate the MIT keytab
|
|
file format. All values are in network byte order. All text is ASCII.
|
|
|
|
@code
|
|
keytab {
|
|
uint16_t file_format_version; # 0x502
|
|
keytab_entry entries[*];
|
|
};
|
|
|
|
keytab_entry {
|
|
int32_t size;
|
|
uint16_t num_components; # subtract 1 if version 0x501
|
|
counted_octet_string realm;
|
|
counted_octet_string components[num_components];
|
|
uint32_t name_type; # not present if version 0x501
|
|
uint32_t timestamp;
|
|
uint8_t vno8;
|
|
keyblock key;
|
|
uint32_t vno; #only present if >= 4 bytes left in entry
|
|
};
|
|
|
|
counted_octet_string {
|
|
uint16_t length;
|
|
uint8_t data[length];
|
|
};
|
|
|
|
keyblock {
|
|
uint16_t type;
|
|
counted_octet_string;
|
|
};
|
|
@endcode
|
|
|
|
All numbers are stored in network byteorder (big endian) format.
|
|
|
|
The keytab file format begins with the 16 bit file_format_version which
|
|
at the time this document was authored is 0x502. The format of older
|
|
keytabs is described at the end of this document.
|
|
|
|
The file_format_version is immediately followed by an array of
|
|
keytab_entry structures which are prefixed with a 32 bit size indicating
|
|
the number of bytes that follow in the entry. Note that the size should be
|
|
evaluated as signed. This is because a negative value indicates that the
|
|
entry is in fact empty (e.g. it has been deleted) and that the negative
|
|
value of that negative value (which is of course a positive value) is
|
|
the offset to the next keytab_entry. Based on these size values alone
|
|
the entire keytab file can be traversed.
|
|
|
|
The size is followed by a 16 bit num_components field indicating the
|
|
number of counted_octet_string components in the components array.
|
|
|
|
The num_components field is followed by a counted_octet_string
|
|
representing the realm of the principal.
|
|
|
|
A counted_octet_string is simply an array of bytes prefixed with a 16
|
|
bit length. For the realm and name components, the counted_octet_string
|
|
bytes are ASCII encoded text with no zero terminator.
|
|
|
|
Following the realm is the components array that represents the name of
|
|
the principal. The text of these components may be joined with slashs
|
|
to construct the typical SPN representation. For example, the service
|
|
principal HTTP/www.foo.net\@FOO.NET would consist of name components
|
|
"HTTP" followed by "www.foo.net".
|
|
|
|
Following the components array is the 32 bit name_type (e.g. 1 is
|
|
KRB5_NT_PRINCIPAL, 2 is KRB5_NT_SRV_INST, 5 is KRB5_NT_UID, etc). In
|
|
practice the name_type is almost certainly 1 meaning KRB5_NT_PRINCIPAL.
|
|
|
|
The 32 bit timestamp indicates the time the key was established for that
|
|
principal. The value represents the number of seconds since Jan 1, 1970.
|
|
|
|
The 8 bit vno8 field is the version number of the key. This value is
|
|
overridden by the 32 bit vno field if it is present. The vno8 field is
|
|
filled with the lower 8 bits of the 32 bit protocol kvno field.
|
|
|
|
The keyblock structure consists of a 16 bit value indicating the
|
|
encryption type and is a counted_octet_string containing the key. The
|
|
encryption type is the same as the Kerberos standard (e.g. 3 is
|
|
des-cbc-md5, 23 is arcfour-hmac-md5, etc).
|
|
|
|
The last field of the keytab_entry structure is optional. If the size of
|
|
the keytab_entry indicates that there are at least 4 bytes remaining,
|
|
a 32 bit value representing the key version number is present. This
|
|
value supersedes the 8 bit vno8 value preceeding the keyblock.
|
|
|
|
Older keytabs with a file_format_version of 0x501 are different in
|
|
three ways:
|
|
|
|
- All integers are in host byte order [1].
|
|
- The num_components field is 1 too large (i.e. after decoding, decrement by 1).
|
|
- The 32 bit name_type field is not present.
|
|
|
|
[1] The file_format_version field should really be treated as two
|
|
separate 8 bit quantities representing the major and minor version
|
|
number respectively.
|
|
|
|
@subsection file_hdb_dump Heimdal database dump file
|
|
|
|
Format of the Heimdal text dump file as of Heimdal 0.6.3:
|
|
|
|
Each line in the dump file is one entry in the database.
|
|
|
|
Each field of a line is separated by one or more spaces, with the
|
|
exception of fields consisting of principals containing spaces, where
|
|
space can be quoted with \ and \ is quoted by \.
|
|
|
|
Fields and their types are:
|
|
|
|
@code
|
|
Quoted princial (quote character is \) [string]
|
|
Keys [keys]
|
|
Created by [event]
|
|
Modified by [event optional]
|
|
Valid start time [time optional]
|
|
Valid end time [time optional]
|
|
Password end valid time [time optional]
|
|
Max lifetime of ticket [time optional]
|
|
Max renew time of ticket [integer optional]
|
|
Flags [hdb flags]
|
|
Generation number [generation optional]
|
|
Extensions [extentions optional]
|
|
@endcode
|
|
|
|
Fields following these silently are ignored.
|
|
|
|
All optional fields will be skipped if they fail to parse (or comprise
|
|
the optional field marker of "-", w/o quotes).
|
|
|
|
Example:
|
|
|
|
@code
|
|
fred\@CODE.COM 27:1:16:e8b4c8fc7e60b9e641dcf4cff3f08a701d982a2f89ba373733d26ca59ba6c789666f6b8bfcf169412bb1e5dceb9b33cda29f3412:-:1:3:4498a933881178c744f4232172dcd774c64e81fa6d05ecdf643a7e390624a0ebf3c7407a:-:1:2:b01934b13eb795d76f3a80717d469639b4da0cfb644161340ef44fdeb375e54d684dbb85:-:1:1:ea8e16d8078bf60c781da90f508d4deccba70595258b9d31888d33987cd31af0c9cced2e:- 20020415130120:admin\@CODE.COM 20041221112428:fred\@CODE.COM - - - 86400 604800 126 20020415130120:793707:28 -
|
|
@endcode
|
|
|
|
Encoding of types are as follows:
|
|
|
|
- keys
|
|
|
|
@code
|
|
kvno:[masterkvno:keytype:keydata:salt]{zero or more separated by :}
|
|
@endcode
|
|
|
|
kvno is the key version number.
|
|
|
|
keydata is hex-encoded
|
|
|
|
masterkvno is the kvno of the database master key. If this field is
|
|
empty, the kadmin load and merge operations will encrypt the key data
|
|
with the master key if there is one. Otherwise the key data will be
|
|
imported asis.
|
|
|
|
salt is encoded as "-" (no/default salt) or
|
|
|
|
@code
|
|
salt-type /
|
|
salt-type / "string"
|
|
salt-type / hex-encoded-data
|
|
@endcode
|
|
|
|
keytype is the protocol enctype number; see enum ENCTYPE in
|
|
include/krb5_asn1.h for values.
|
|
|
|
Example:
|
|
@code
|
|
27:1:16:e8b4c8fc7e60b9e641dcf4cff3f08a701d982a2f89ba373733d26ca59ba6c789666f6b8bfcf169412bb1e5dceb9b33cda29f3412:-:1:3:4498a933881178c744f4232172dcd774c64e81fa6d05ecdf643a7e390624a0ebf3c7407a:-:1:2:b01934b13eb795d76f3a80717d469639b4da0cfb644161340ef44fdeb375e54d684dbb85:-:1:1:ea8e16d8078bf60c781da90f508d4deccba70595258b9d31888d33987cd31af0c9cced2e:-
|
|
@endcode
|
|
|
|
|
|
@code
|
|
kvno=27,{key: masterkvno=1,keytype=des3-cbc-sha1,keydata=..., default salt}...
|
|
@endcode
|
|
|
|
- time
|
|
|
|
Format of the time is: YYYYmmddHHMMSS, corresponding to strftime
|
|
format "%Y%m%d%k%M%S".
|
|
|
|
Time is expressed in UTC.
|
|
|
|
Time can be optional (using -), when the time 0 is used.
|
|
|
|
Example:
|
|
|
|
@code
|
|
20041221112428
|
|
@endcode
|
|
|
|
- event
|
|
|
|
@code
|
|
time:principal
|
|
@endcode
|
|
|
|
time is as given in format time
|
|
|
|
principal is a string. Not quoting it may not work in earlier
|
|
versions of Heimdal.
|
|
|
|
Example:
|
|
@code
|
|
20041221112428:bloggs\@CODE.COM
|
|
@endcode
|
|
|
|
- hdb flags
|
|
|
|
Integer encoding of HDB flags, see HDBFlags in lib/hdb/hdb.asn1. Each
|
|
bit in the integer is the same as the bit in the specification.
|
|
|
|
- generation:
|
|
|
|
@code
|
|
time:usec:gen
|
|
@endcode
|
|
|
|
|
|
usec is a the microsecond, integer.
|
|
gen is generation number, integer.
|
|
|
|
The generation can be defaulted (using '-') or the empty string
|
|
|
|
- extensions:
|
|
|
|
@code
|
|
first-hex-encoded-HDB-Extension[:second-...]
|
|
@endcode
|
|
|
|
HDB-extension is encoded the DER encoded HDB-Extension from
|
|
lib/hdb/hdb.asn1. Consumers HDB extensions should be aware that
|
|
unknown entires needs to be preserved even thought the ASN.1 data
|
|
content might be unknown. There is a critical flag in the data to show
|
|
to the KDC that the entry MUST be understod if the entry is to be
|
|
used.
|
|
|
|
*/
|