1*0a6a1f1dSLionel Sambuc /* $NetBSD: doxygen.c,v 1.1.1.2 2014/04/24 12:45:50 pettai Exp $ */ 2ebfedea0SLionel Sambuc 3ebfedea0SLionel Sambuc /* 4ebfedea0SLionel Sambuc * Copyright (c) 2007-2008 Kungliga Tekniska Högskolan 5ebfedea0SLionel Sambuc * (Royal Institute of Technology, Stockholm, Sweden). 6ebfedea0SLionel Sambuc * All rights reserved. 7ebfedea0SLionel Sambuc * 8ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without 9ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions 10ebfedea0SLionel Sambuc * are met: 11ebfedea0SLionel Sambuc * 12ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright 13ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer. 14ebfedea0SLionel Sambuc * 15ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright 16ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in the 17ebfedea0SLionel Sambuc * documentation and/or other materials provided with the distribution. 18ebfedea0SLionel Sambuc * 19ebfedea0SLionel Sambuc * 3. Neither the name of the Institute nor the names of its contributors 20ebfedea0SLionel Sambuc * may be used to endorse or promote products derived from this software 21ebfedea0SLionel Sambuc * without specific prior written permission. 22ebfedea0SLionel Sambuc * 23ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24ebfedea0SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25ebfedea0SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26ebfedea0SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27ebfedea0SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28ebfedea0SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29ebfedea0SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30ebfedea0SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31ebfedea0SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32ebfedea0SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33ebfedea0SLionel Sambuc * SUCH DAMAGE. 34ebfedea0SLionel Sambuc */ 35ebfedea0SLionel Sambuc 36ebfedea0SLionel Sambuc #include "krb5_locl.h" 37ebfedea0SLionel Sambuc 38ebfedea0SLionel Sambuc /** 39ebfedea0SLionel Sambuc * 40ebfedea0SLionel Sambuc */ 41ebfedea0SLionel Sambuc 42ebfedea0SLionel Sambuc /*! @mainpage Heimdal Kerberos 5 library 43ebfedea0SLionel Sambuc * 44ebfedea0SLionel Sambuc * @section intro Introduction 45ebfedea0SLionel Sambuc * 46ebfedea0SLionel Sambuc * Heimdal libkrb5 library is a implementation of the Kerberos 47ebfedea0SLionel Sambuc * protocol. 48ebfedea0SLionel Sambuc * 49ebfedea0SLionel Sambuc * Kerberos is a system for authenticating users and services on a 50ebfedea0SLionel Sambuc * network. It is built upon the assumption that the network is 51ebfedea0SLionel Sambuc * ``unsafe''. For example, data sent over the network can be 52ebfedea0SLionel Sambuc * eavesdropped and altered, and addresses can also be faked. 53ebfedea0SLionel Sambuc * Therefore they cannot be used for authentication purposes. 54ebfedea0SLionel Sambuc * 55ebfedea0SLionel Sambuc * 56ebfedea0SLionel Sambuc * - @ref krb5_introduction 57ebfedea0SLionel Sambuc * - @ref krb5_principal_intro 58ebfedea0SLionel Sambuc * - @ref krb5_ccache_intro 59ebfedea0SLionel Sambuc * - @ref krb5_keytab_intro 60ebfedea0SLionel Sambuc * 61ebfedea0SLionel Sambuc * If you want to know more about the file formats that is used by 62ebfedea0SLionel Sambuc * Heimdal, please see: @ref krb5_fileformats 63ebfedea0SLionel Sambuc * 64ebfedea0SLionel Sambuc * The project web page: http://www.h5l.org/ 65ebfedea0SLionel Sambuc * 66ebfedea0SLionel Sambuc */ 67ebfedea0SLionel Sambuc 68ebfedea0SLionel Sambuc /** @defgroup krb5 Heimdal Kerberos 5 library */ 69ebfedea0SLionel Sambuc /** @defgroup krb5_address Heimdal Kerberos 5 address functions */ 70ebfedea0SLionel Sambuc /** @defgroup krb5_principal Heimdal Kerberos 5 principal functions */ 71ebfedea0SLionel Sambuc /** @defgroup krb5_ccache Heimdal Kerberos 5 credential cache functions */ 72ebfedea0SLionel Sambuc /** @defgroup krb5_crypto Heimdal Kerberos 5 cryptography functions */ 73ebfedea0SLionel Sambuc /** @defgroup krb5_credential Heimdal Kerberos 5 credential handing functions */ 74ebfedea0SLionel Sambuc /** @defgroup krb5_deprecated Heimdal Kerberos 5 deprecated functions */ 75ebfedea0SLionel Sambuc /** @defgroup krb5_digest Heimdal Kerberos 5 digest service */ 76ebfedea0SLionel Sambuc /** @defgroup krb5_error Heimdal Kerberos 5 error reporting functions */ 77ebfedea0SLionel Sambuc /** @defgroup krb5_keytab Heimdal Kerberos 5 keytab handling functions */ 78ebfedea0SLionel Sambuc /** @defgroup krb5_ticket Heimdal Kerberos 5 ticket functions */ 79ebfedea0SLionel Sambuc /** @defgroup krb5_pac Heimdal Kerberos 5 PAC handling functions */ 80ebfedea0SLionel Sambuc /** @defgroup krb5_v4compat Heimdal Kerberos 4 compatiblity functions */ 81ebfedea0SLionel Sambuc /** @defgroup krb5_storage Heimdal Kerberos 5 storage functions */ 82ebfedea0SLionel Sambuc /** @defgroup krb5_support Heimdal Kerberos 5 support functions */ 83ebfedea0SLionel Sambuc /** @defgroup krb5_auth Heimdal Kerberos 5 authentication functions */ 84ebfedea0SLionel Sambuc 85ebfedea0SLionel Sambuc 86ebfedea0SLionel Sambuc /** 87ebfedea0SLionel Sambuc * @page krb5_introduction Introduction to the Kerberos 5 API 88ebfedea0SLionel Sambuc * @section api_overview Kerberos 5 API Overview 89ebfedea0SLionel Sambuc * 90ebfedea0SLionel Sambuc * All functions are documented in manual pages. This section tries 91ebfedea0SLionel Sambuc * to give an overview of the major components used in Kerberos 92ebfedea0SLionel Sambuc * library, and point to where to look for a specific function. 93ebfedea0SLionel Sambuc * 94ebfedea0SLionel Sambuc * @subsection intro_krb5_context Kerberos context 95ebfedea0SLionel Sambuc * 96ebfedea0SLionel Sambuc * A kerberos context (krb5_context) holds all per thread state. All 97ebfedea0SLionel Sambuc * global variables that are context specific are stored in this 98ebfedea0SLionel Sambuc * structure, including default encryption types, credential cache 99ebfedea0SLionel Sambuc * (for example, a ticket file), and default realms. 100ebfedea0SLionel Sambuc * 101ebfedea0SLionel Sambuc * The internals of the structure should never be accessed directly, 102ebfedea0SLionel Sambuc * functions exist for extracting information. 103ebfedea0SLionel Sambuc * 104ebfedea0SLionel Sambuc * See the manual page for krb5_init_context() how to create a context 105ebfedea0SLionel Sambuc * and module @ref krb5 for more information about the functions. 106ebfedea0SLionel Sambuc * 107ebfedea0SLionel Sambuc * @subsection intro_krb5_auth_context Kerberos authentication context 108ebfedea0SLionel Sambuc * 109ebfedea0SLionel Sambuc * Kerberos authentication context (krb5_auth_context) holds all 110ebfedea0SLionel Sambuc * context related to an authenticated connection, in a similar way to 111ebfedea0SLionel Sambuc * the kerberos context that holds the context for the thread or 112ebfedea0SLionel Sambuc * process. 113ebfedea0SLionel Sambuc * 114ebfedea0SLionel Sambuc * The krb5_auth_context is used by various functions that are 115ebfedea0SLionel Sambuc * directly related to authentication between the 116ebfedea0SLionel Sambuc * server/client. Example of data that this structure contains are 117ebfedea0SLionel Sambuc * various flags, addresses of client and server, port numbers, 118ebfedea0SLionel Sambuc * keyblocks (and subkeys), sequence numbers, replay cache, and 119ebfedea0SLionel Sambuc * checksum types. 120ebfedea0SLionel Sambuc * 121ebfedea0SLionel Sambuc * @subsection intro_krb5_principal Kerberos principal 122ebfedea0SLionel Sambuc * 123ebfedea0SLionel Sambuc * The Kerberos principal is the structure that identifies a user or 124ebfedea0SLionel Sambuc * service in Kerberos. The structure that holds the principal is the 125ebfedea0SLionel Sambuc * krb5_principal. There are function to extract the realm and 126ebfedea0SLionel Sambuc * elements of the principal, but most applications have no reason to 127ebfedea0SLionel Sambuc * inspect the content of the structure. 128ebfedea0SLionel Sambuc * 129ebfedea0SLionel Sambuc * The are several ways to create a principal (with different degree of 130ebfedea0SLionel Sambuc * portability), and one way to free it. 131ebfedea0SLionel Sambuc * 132ebfedea0SLionel Sambuc * See also the page @ref krb5_principal_intro for more information and also 133ebfedea0SLionel Sambuc * module @ref krb5_principal. 134ebfedea0SLionel Sambuc * 135ebfedea0SLionel Sambuc * @subsection intro_krb5_ccache Credential cache 136ebfedea0SLionel Sambuc * 137ebfedea0SLionel Sambuc * A credential cache holds the tickets for a user. A given user can 138ebfedea0SLionel Sambuc * have several credential caches, one for each realm where the user 139ebfedea0SLionel Sambuc * have the initial tickets (the first krbtgt). 140ebfedea0SLionel Sambuc * 141ebfedea0SLionel Sambuc * The credential cache data can be stored internally in different 142ebfedea0SLionel Sambuc * way, each of them for different proposes. File credential (FILE) 143ebfedea0SLionel Sambuc * caches and processes based (KCM) caches are for permanent 144ebfedea0SLionel Sambuc * storage. While memory caches (MEMORY) are local caches to the local 145ebfedea0SLionel Sambuc * process. 146ebfedea0SLionel Sambuc * 147ebfedea0SLionel Sambuc * Caches are opened with krb5_cc_resolve() or created with 148ebfedea0SLionel Sambuc * krb5_cc_new_unique(). 149ebfedea0SLionel Sambuc * 150ebfedea0SLionel Sambuc * If the cache needs to be opened again (using krb5_cc_resolve()) 151ebfedea0SLionel Sambuc * krb5_cc_close() will close the handle, but not the remove the 152ebfedea0SLionel Sambuc * cache. krb5_cc_destroy() will zero out the cache, remove the cache 153ebfedea0SLionel Sambuc * so it can no longer be referenced. 154ebfedea0SLionel Sambuc * 155ebfedea0SLionel Sambuc * See also @ref krb5_ccache_intro and @ref krb5_ccache . 156ebfedea0SLionel Sambuc * 157ebfedea0SLionel Sambuc * @subsection intro_krb5_error_code Kerberos errors 158ebfedea0SLionel Sambuc * 159ebfedea0SLionel Sambuc * Kerberos errors are based on the com_err library. All error codes are 160ebfedea0SLionel Sambuc * 32-bit signed numbers, the first 24 bits define what subsystem the 161ebfedea0SLionel Sambuc * error originates from, and last 8 bits are 255 error codes within the 162ebfedea0SLionel Sambuc * library. Each error code have fixed string associated with it. For 163ebfedea0SLionel Sambuc * example, the error-code -1765328383 have the symbolic name 164ebfedea0SLionel Sambuc * KRB5KDC_ERR_NAME_EXP, and associated error string ``Client's entry in 165ebfedea0SLionel Sambuc * database has expired''. 166ebfedea0SLionel Sambuc * 167ebfedea0SLionel Sambuc * This is a great improvement compared to just getting one of the unix 168ebfedea0SLionel Sambuc * error-codes back. However, Heimdal have an extention to pass back 169ebfedea0SLionel Sambuc * customised errors messages. Instead of getting ``Key table entry not 170ebfedea0SLionel Sambuc * found'', the user might back ``failed to find 171ebfedea0SLionel Sambuc * host/host.example.com\@EXAMLE.COM(kvno 3) in keytab /etc/krb5.keytab 172ebfedea0SLionel Sambuc * (des-cbc-crc)''. This improves the chance that the user find the 173ebfedea0SLionel Sambuc * cause of the error so you should use the customised error message 174ebfedea0SLionel Sambuc * whenever it's available. 175ebfedea0SLionel Sambuc * 176ebfedea0SLionel Sambuc * See also module @ref krb5_error . 177ebfedea0SLionel Sambuc * 178ebfedea0SLionel Sambuc * 179ebfedea0SLionel Sambuc * @subsection intro_krb5_keytab Keytab management 180ebfedea0SLionel Sambuc * 181ebfedea0SLionel Sambuc * A keytab is a storage for locally stored keys. Heimdal includes keytab 182ebfedea0SLionel Sambuc * support for Kerberos 5 keytabs, Kerberos 4 srvtab, AFS-KeyFile's, 183ebfedea0SLionel Sambuc * and for storing keys in memory. 184ebfedea0SLionel Sambuc * 185ebfedea0SLionel Sambuc * Keytabs are used for servers and long-running services. 186ebfedea0SLionel Sambuc * 187ebfedea0SLionel Sambuc * See also @ref krb5_keytab_intro and @ref krb5_keytab . 188ebfedea0SLionel Sambuc * 189ebfedea0SLionel Sambuc * @subsection intro_krb5_crypto Kerberos crypto 190ebfedea0SLionel Sambuc * 191ebfedea0SLionel Sambuc * Heimdal includes a implementation of the Kerberos crypto framework, 192ebfedea0SLionel Sambuc * all crypto operations. To create a crypto context call krb5_crypto_init(). 193ebfedea0SLionel Sambuc * 194ebfedea0SLionel Sambuc * See also module @ref krb5_crypto . 195ebfedea0SLionel Sambuc * 196ebfedea0SLionel Sambuc * @section kerberos5_client Walkthrough of a sample Kerberos 5 client 197ebfedea0SLionel Sambuc * 198ebfedea0SLionel Sambuc * This example contains parts of a sample TCP Kerberos 5 clients, if you 199ebfedea0SLionel Sambuc * want a real working client, please look in appl/test directory in 200ebfedea0SLionel Sambuc * the Heimdal distribution. 201ebfedea0SLionel Sambuc * 202ebfedea0SLionel Sambuc * All Kerberos error-codes that are returned from kerberos functions in 203ebfedea0SLionel Sambuc * this program are passed to krb5_err, that will print a 204ebfedea0SLionel Sambuc * descriptive text of the error code and exit. Graphical programs can 205ebfedea0SLionel Sambuc * convert error-code to a human readable error-string with the 206ebfedea0SLionel Sambuc * krb5_get_error_message() function. 207ebfedea0SLionel Sambuc * 208ebfedea0SLionel Sambuc * Note that you should not use any Kerberos function before 209ebfedea0SLionel Sambuc * krb5_init_context() have completed successfully. That is the 210ebfedea0SLionel Sambuc * reason err() is used when krb5_init_context() fails. 211ebfedea0SLionel Sambuc * 212ebfedea0SLionel Sambuc * First the client needs to call krb5_init_context to initialise 213ebfedea0SLionel Sambuc * the Kerberos 5 library. This is only needed once per thread 214ebfedea0SLionel Sambuc * in the program. If the function returns a non-zero value it indicates 215ebfedea0SLionel Sambuc * that either the Kerberos implementation is failing or it's disabled on 216ebfedea0SLionel Sambuc * this host. 217ebfedea0SLionel Sambuc * 218ebfedea0SLionel Sambuc * @code 219ebfedea0SLionel Sambuc * #include <krb5/krb5.h> 220ebfedea0SLionel Sambuc * 221ebfedea0SLionel Sambuc * int 222ebfedea0SLionel Sambuc * main(int argc, char **argv) 223ebfedea0SLionel Sambuc * { 224ebfedea0SLionel Sambuc * krb5_context context; 225ebfedea0SLionel Sambuc * 226ebfedea0SLionel Sambuc * if (krb5_init_context(&context)) 227ebfedea0SLionel Sambuc * errx (1, "krb5_context"); 228ebfedea0SLionel Sambuc * @endcode 229ebfedea0SLionel Sambuc * 230ebfedea0SLionel Sambuc * Now the client wants to connect to the host at the other end. The 231ebfedea0SLionel Sambuc * preferred way of doing this is using getaddrinfo (for 232ebfedea0SLionel Sambuc * operating system that have this function implemented), since getaddrinfo 233ebfedea0SLionel Sambuc * is neutral to the address type and can use any protocol that is available. 234ebfedea0SLionel Sambuc * 235ebfedea0SLionel Sambuc * @code 236ebfedea0SLionel Sambuc * struct addrinfo *ai, *a; 237ebfedea0SLionel Sambuc * struct addrinfo hints; 238ebfedea0SLionel Sambuc * int error; 239ebfedea0SLionel Sambuc * 240ebfedea0SLionel Sambuc * memset (&hints, 0, sizeof(hints)); 241ebfedea0SLionel Sambuc * hints.ai_socktype = SOCK_STREAM; 242ebfedea0SLionel Sambuc * hints.ai_protocol = IPPROTO_TCP; 243ebfedea0SLionel Sambuc * 244ebfedea0SLionel Sambuc * error = getaddrinfo (hostname, "pop3", &hints, &ai); 245ebfedea0SLionel Sambuc * if (error) 246ebfedea0SLionel Sambuc * errx (1, "%s: %s", hostname, gai_strerror(error)); 247ebfedea0SLionel Sambuc * 248ebfedea0SLionel Sambuc * for (a = ai; a != NULL; a = a->ai_next) { 249ebfedea0SLionel Sambuc * int s; 250ebfedea0SLionel Sambuc * 251ebfedea0SLionel Sambuc * s = socket (a->ai_family, a->ai_socktype, a->ai_protocol); 252ebfedea0SLionel Sambuc * if (s < 0) 253ebfedea0SLionel Sambuc * continue; 254ebfedea0SLionel Sambuc * if (connect (s, a->ai_addr, a->ai_addrlen) < 0) { 255ebfedea0SLionel Sambuc * warn ("connect(%s)", hostname); 256ebfedea0SLionel Sambuc * close (s); 257ebfedea0SLionel Sambuc * continue; 258ebfedea0SLionel Sambuc * } 259ebfedea0SLionel Sambuc * freeaddrinfo (ai); 260ebfedea0SLionel Sambuc * ai = NULL; 261ebfedea0SLionel Sambuc * } 262ebfedea0SLionel Sambuc * if (ai) { 263ebfedea0SLionel Sambuc * freeaddrinfo (ai); 264ebfedea0SLionel Sambuc * errx ("failed to contact %s", hostname); 265ebfedea0SLionel Sambuc * } 266ebfedea0SLionel Sambuc * @endcode 267ebfedea0SLionel Sambuc * 268ebfedea0SLionel Sambuc * Before authenticating, an authentication context needs to be 269ebfedea0SLionel Sambuc * created. This context keeps all information for one (to be) authenticated 270ebfedea0SLionel Sambuc * connection (see krb5_auth_context). 271ebfedea0SLionel Sambuc * 272ebfedea0SLionel Sambuc * @code 273ebfedea0SLionel Sambuc * status = krb5_auth_con_init (context, &auth_context); 274ebfedea0SLionel Sambuc * if (status) 275ebfedea0SLionel Sambuc * krb5_err (context, 1, status, "krb5_auth_con_init"); 276ebfedea0SLionel Sambuc * @endcode 277ebfedea0SLionel Sambuc * 278ebfedea0SLionel Sambuc * For setting the address in the authentication there is a help function 279ebfedea0SLionel Sambuc * krb5_auth_con_setaddrs_from_fd() that does everything that is needed 280ebfedea0SLionel Sambuc * when given a connected file descriptor to the socket. 281ebfedea0SLionel Sambuc * 282ebfedea0SLionel Sambuc * @code 283ebfedea0SLionel Sambuc * status = krb5_auth_con_setaddrs_from_fd (context, 284ebfedea0SLionel Sambuc * auth_context, 285ebfedea0SLionel Sambuc * &sock); 286ebfedea0SLionel Sambuc * if (status) 287ebfedea0SLionel Sambuc * krb5_err (context, 1, status, 288ebfedea0SLionel Sambuc * "krb5_auth_con_setaddrs_from_fd"); 289ebfedea0SLionel Sambuc * @endcode 290ebfedea0SLionel Sambuc * 291ebfedea0SLionel Sambuc * The next step is to build a server principal for the service we want 292ebfedea0SLionel Sambuc * to connect to. (See also krb5_sname_to_principal().) 293ebfedea0SLionel Sambuc * 294ebfedea0SLionel Sambuc * @code 295ebfedea0SLionel Sambuc * status = krb5_sname_to_principal (context, 296ebfedea0SLionel Sambuc * hostname, 297ebfedea0SLionel Sambuc * service, 298ebfedea0SLionel Sambuc * KRB5_NT_SRV_HST, 299ebfedea0SLionel Sambuc * &server); 300ebfedea0SLionel Sambuc * if (status) 301ebfedea0SLionel Sambuc * krb5_err (context, 1, status, "krb5_sname_to_principal"); 302ebfedea0SLionel Sambuc * @endcode 303ebfedea0SLionel Sambuc * 304ebfedea0SLionel Sambuc * The client principal is not passed to krb5_sendauth() 305ebfedea0SLionel Sambuc * function, this causes the krb5_sendauth() function to try to figure it 306ebfedea0SLionel Sambuc * out itself. 307ebfedea0SLionel Sambuc * 308ebfedea0SLionel Sambuc * The server program is using the function krb5_recvauth() to 309ebfedea0SLionel Sambuc * receive the Kerberos 5 authenticator. 310ebfedea0SLionel Sambuc * 311ebfedea0SLionel Sambuc * In this case, mutual authentication will be tried. That means that the server 312ebfedea0SLionel Sambuc * will authenticate to the client. Using mutual authentication 313ebfedea0SLionel Sambuc * is good since it enables the user to verify that they are talking to the 314ebfedea0SLionel Sambuc * right server (a server that knows the key). 315ebfedea0SLionel Sambuc * 316ebfedea0SLionel Sambuc * If you are using a non-blocking socket you will need to do all work of 317ebfedea0SLionel Sambuc * krb5_sendauth() yourself. Basically you need to send over the 318ebfedea0SLionel Sambuc * authenticator from krb5_mk_req() and, in case of mutual 319ebfedea0SLionel Sambuc * authentication, verifying the result from the server with 320ebfedea0SLionel Sambuc * krb5_rd_rep(). 321ebfedea0SLionel Sambuc * 322ebfedea0SLionel Sambuc * @code 323ebfedea0SLionel Sambuc * status = krb5_sendauth (context, 324ebfedea0SLionel Sambuc * &auth_context, 325ebfedea0SLionel Sambuc * &sock, 326ebfedea0SLionel Sambuc * VERSION, 327ebfedea0SLionel Sambuc * NULL, 328ebfedea0SLionel Sambuc * server, 329ebfedea0SLionel Sambuc * AP_OPTS_MUTUAL_REQUIRED, 330ebfedea0SLionel Sambuc * NULL, 331ebfedea0SLionel Sambuc * NULL, 332ebfedea0SLionel Sambuc * NULL, 333ebfedea0SLionel Sambuc * NULL, 334ebfedea0SLionel Sambuc * NULL, 335ebfedea0SLionel Sambuc * NULL); 336ebfedea0SLionel Sambuc * if (status) 337ebfedea0SLionel Sambuc * krb5_err (context, 1, status, "krb5_sendauth"); 338ebfedea0SLionel Sambuc * @endcode 339ebfedea0SLionel Sambuc * 340ebfedea0SLionel Sambuc * Once authentication has been performed, it is time to send some 341ebfedea0SLionel Sambuc * data. First we create a krb5_data structure, then we sign it with 342ebfedea0SLionel Sambuc * krb5_mk_safe() using the auth_context that contains the 343ebfedea0SLionel Sambuc * session-key that was exchanged in the 344ebfedea0SLionel Sambuc * krb5_sendauth()/krb5_recvauth() authentication 345ebfedea0SLionel Sambuc * sequence. 346ebfedea0SLionel Sambuc * 347ebfedea0SLionel Sambuc * @code 348ebfedea0SLionel Sambuc * data.data = "hej"; 349ebfedea0SLionel Sambuc * data.length = 3; 350ebfedea0SLionel Sambuc * 351ebfedea0SLionel Sambuc * krb5_data_zero (&packet); 352ebfedea0SLionel Sambuc * 353ebfedea0SLionel Sambuc * status = krb5_mk_safe (context, 354ebfedea0SLionel Sambuc * auth_context, 355ebfedea0SLionel Sambuc * &data, 356ebfedea0SLionel Sambuc * &packet, 357ebfedea0SLionel Sambuc * NULL); 358ebfedea0SLionel Sambuc * if (status) 359ebfedea0SLionel Sambuc * krb5_err (context, 1, status, "krb5_mk_safe"); 360ebfedea0SLionel Sambuc * @endcode 361ebfedea0SLionel Sambuc * 362ebfedea0SLionel Sambuc * And send it over the network. 363ebfedea0SLionel Sambuc * 364ebfedea0SLionel Sambuc * @code 365ebfedea0SLionel Sambuc * len = packet.length; 366ebfedea0SLionel Sambuc * net_len = htonl(len); 367ebfedea0SLionel Sambuc * 368ebfedea0SLionel Sambuc * if (krb5_net_write (context, &sock, &net_len, 4) != 4) 369ebfedea0SLionel Sambuc * err (1, "krb5_net_write"); 370ebfedea0SLionel Sambuc * if (krb5_net_write (context, &sock, packet.data, len) != len) 371ebfedea0SLionel Sambuc * err (1, "krb5_net_write"); 372ebfedea0SLionel Sambuc * @endcode 373ebfedea0SLionel Sambuc * 374ebfedea0SLionel Sambuc * To send encrypted (and signed) data krb5_mk_priv() should be 375ebfedea0SLionel Sambuc * used instead. krb5_mk_priv() works the same way as 376ebfedea0SLionel Sambuc * krb5_mk_safe(), with the exception that it encrypts the data 377ebfedea0SLionel Sambuc * in addition to signing it. 378ebfedea0SLionel Sambuc * 379ebfedea0SLionel Sambuc * @code 380ebfedea0SLionel Sambuc * data.data = "hemligt"; 381ebfedea0SLionel Sambuc * data.length = 7; 382ebfedea0SLionel Sambuc * 383ebfedea0SLionel Sambuc * krb5_data_free (&packet); 384ebfedea0SLionel Sambuc * 385ebfedea0SLionel Sambuc * status = krb5_mk_priv (context, 386ebfedea0SLionel Sambuc * auth_context, 387ebfedea0SLionel Sambuc * &data, 388ebfedea0SLionel Sambuc * &packet, 389ebfedea0SLionel Sambuc * NULL); 390ebfedea0SLionel Sambuc * if (status) 391ebfedea0SLionel Sambuc * krb5_err (context, 1, status, "krb5_mk_priv"); 392ebfedea0SLionel Sambuc * @endcode 393ebfedea0SLionel Sambuc * 394ebfedea0SLionel Sambuc * And send it over the network. 395ebfedea0SLionel Sambuc * 396ebfedea0SLionel Sambuc * @code 397ebfedea0SLionel Sambuc * len = packet.length; 398ebfedea0SLionel Sambuc * net_len = htonl(len); 399ebfedea0SLionel Sambuc * 400ebfedea0SLionel Sambuc * if (krb5_net_write (context, &sock, &net_len, 4) != 4) 401ebfedea0SLionel Sambuc * err (1, "krb5_net_write"); 402ebfedea0SLionel Sambuc * if (krb5_net_write (context, &sock, packet.data, len) != len) 403ebfedea0SLionel Sambuc * err (1, "krb5_net_write"); 404ebfedea0SLionel Sambuc * 405ebfedea0SLionel Sambuc * @endcode 406ebfedea0SLionel Sambuc * 407ebfedea0SLionel Sambuc * The server is using krb5_rd_safe() and 408ebfedea0SLionel Sambuc * krb5_rd_priv() to verify the signature and decrypt the packet. 409ebfedea0SLionel Sambuc * 410ebfedea0SLionel Sambuc * @section intro_krb5_verify_user Validating a password in an application 411ebfedea0SLionel Sambuc * 412ebfedea0SLionel Sambuc * See the manual page for krb5_verify_user(). 413ebfedea0SLionel Sambuc * 414ebfedea0SLionel Sambuc * @section mit_differences API differences to MIT Kerberos 415ebfedea0SLionel Sambuc * 416ebfedea0SLionel Sambuc * This section is somewhat disorganised, but so far there is no overall 417ebfedea0SLionel Sambuc * structure to the differences, though some of the have their root in 418ebfedea0SLionel Sambuc * that Heimdal uses an ASN.1 compiler and MIT doesn't. 419ebfedea0SLionel Sambuc * 420ebfedea0SLionel Sambuc * @subsection mit_krb5_principal Principal and realms 421ebfedea0SLionel Sambuc * 422ebfedea0SLionel Sambuc * Heimdal stores the realm as a krb5_realm, that is a char *. 423ebfedea0SLionel Sambuc * MIT Kerberos uses a krb5_data to store a realm. 424ebfedea0SLionel Sambuc * 425ebfedea0SLionel Sambuc * In Heimdal krb5_principal doesn't contain the component 426ebfedea0SLionel Sambuc * name_type; it's instead stored in component 427ebfedea0SLionel Sambuc * name.name_type. To get and set the nametype in Heimdal, use 428ebfedea0SLionel Sambuc * krb5_principal_get_type() and 429ebfedea0SLionel Sambuc * krb5_principal_set_type(). 430ebfedea0SLionel Sambuc * 431ebfedea0SLionel Sambuc * For more information about principal and realms, see 432ebfedea0SLionel Sambuc * krb5_principal. 433ebfedea0SLionel Sambuc * 434ebfedea0SLionel Sambuc * @subsection mit_krb5_error_code Error messages 435ebfedea0SLionel Sambuc * 436ebfedea0SLionel Sambuc * To get the error string, Heimdal uses 437ebfedea0SLionel Sambuc * krb5_get_error_message(). This is to return custom error messages 438ebfedea0SLionel Sambuc * (like ``Can't find host/datan.example.com\@CODE.COM in 439ebfedea0SLionel Sambuc * /etc/krb5.conf.'' instead of a ``Key table entry not found'' that 440ebfedea0SLionel Sambuc * error_message returns. 441ebfedea0SLionel Sambuc * 442ebfedea0SLionel Sambuc * Heimdal uses a threadsafe(r) version of the com_err interface; the 443ebfedea0SLionel Sambuc * global com_err table isn't initialised. Then 444ebfedea0SLionel Sambuc * error_message returns quite a boring error string (just 445ebfedea0SLionel Sambuc * the error code itself). 446ebfedea0SLionel Sambuc * 447ebfedea0SLionel Sambuc * 448ebfedea0SLionel Sambuc */ 449ebfedea0SLionel Sambuc 450ebfedea0SLionel Sambuc /** 451ebfedea0SLionel Sambuc * 452ebfedea0SLionel Sambuc * 453ebfedea0SLionel Sambuc * @page krb5_fileformats File formats 454ebfedea0SLionel Sambuc * 455ebfedea0SLionel Sambuc * @section fileformats File formats 456ebfedea0SLionel Sambuc * 457ebfedea0SLionel Sambuc * This section documents the diffrent file formats that are used in 458ebfedea0SLionel Sambuc * Heimdal and other Kerberos implementations. 459ebfedea0SLionel Sambuc * 460ebfedea0SLionel Sambuc * @subsection file_keytab keytab 461ebfedea0SLionel Sambuc * 462ebfedea0SLionel Sambuc * The keytab binary format is not a standard format. The format has 463ebfedea0SLionel Sambuc * evolved and may continue to. It is however understood by several 464ebfedea0SLionel Sambuc * Kerberos implementations including Heimdal, MIT, Sun's Java ktab and 465ebfedea0SLionel Sambuc * are created by the ktpass.exe utility from Windows. So it has 466ebfedea0SLionel Sambuc * established itself as the defacto format for storing Kerberos keys. 467ebfedea0SLionel Sambuc * 468ebfedea0SLionel Sambuc * The following C-like structure definitions illustrate the MIT keytab 469ebfedea0SLionel Sambuc * file format. All values are in network byte order. All text is ASCII. 470ebfedea0SLionel Sambuc * 471ebfedea0SLionel Sambuc * @code 472ebfedea0SLionel Sambuc * keytab { 473ebfedea0SLionel Sambuc * uint16_t file_format_version; # 0x502 474ebfedea0SLionel Sambuc * keytab_entry entries[*]; 475ebfedea0SLionel Sambuc * }; 476ebfedea0SLionel Sambuc * 477ebfedea0SLionel Sambuc * keytab_entry { 478ebfedea0SLionel Sambuc * int32_t size; 479ebfedea0SLionel Sambuc * uint16_t num_components; # subtract 1 if version 0x501 480ebfedea0SLionel Sambuc * counted_octet_string realm; 481ebfedea0SLionel Sambuc * counted_octet_string components[num_components]; 482ebfedea0SLionel Sambuc * uint32_t name_type; # not present if version 0x501 483ebfedea0SLionel Sambuc * uint32_t timestamp; 484ebfedea0SLionel Sambuc * uint8_t vno8; 485ebfedea0SLionel Sambuc * keyblock key; 486ebfedea0SLionel Sambuc * uint32_t vno; #only present if >= 4 bytes left in entry 487ebfedea0SLionel Sambuc * uint32_t flags; #only present if >= 4 bytes left in entry 488ebfedea0SLionel Sambuc * }; 489ebfedea0SLionel Sambuc * 490ebfedea0SLionel Sambuc * counted_octet_string { 491ebfedea0SLionel Sambuc * uint16_t length; 492ebfedea0SLionel Sambuc * uint8_t data[length]; 493ebfedea0SLionel Sambuc * }; 494ebfedea0SLionel Sambuc * 495ebfedea0SLionel Sambuc * keyblock { 496ebfedea0SLionel Sambuc * uint16_t type; 497ebfedea0SLionel Sambuc * counted_octet_string; 498ebfedea0SLionel Sambuc * }; 499ebfedea0SLionel Sambuc * @endcode 500ebfedea0SLionel Sambuc * 501ebfedea0SLionel Sambuc * All numbers are stored in network byteorder (big endian) format. 502ebfedea0SLionel Sambuc * 503ebfedea0SLionel Sambuc * The keytab file format begins with the 16 bit file_format_version which 504ebfedea0SLionel Sambuc * at the time this document was authored is 0x502. The format of older 505ebfedea0SLionel Sambuc * keytabs is described at the end of this document. 506ebfedea0SLionel Sambuc * 507ebfedea0SLionel Sambuc * The file_format_version is immediately followed by an array of 508ebfedea0SLionel Sambuc * keytab_entry structures which are prefixed with a 32 bit size indicating 509ebfedea0SLionel Sambuc * the number of bytes that follow in the entry. Note that the size should be 510ebfedea0SLionel Sambuc * evaluated as signed. This is because a negative value indicates that the 511ebfedea0SLionel Sambuc * entry is in fact empty (e.g. it has been deleted) and that the negative 512ebfedea0SLionel Sambuc * value of that negative value (which is of course a positive value) is 513ebfedea0SLionel Sambuc * the offset to the next keytab_entry. Based on these size values alone 514ebfedea0SLionel Sambuc * the entire keytab file can be traversed. 515ebfedea0SLionel Sambuc * 516ebfedea0SLionel Sambuc * The size is followed by a 16 bit num_components field indicating the 517ebfedea0SLionel Sambuc * number of counted_octet_string components in the components array. 518ebfedea0SLionel Sambuc * 519ebfedea0SLionel Sambuc * The num_components field is followed by a counted_octet_string 520ebfedea0SLionel Sambuc * representing the realm of the principal. 521ebfedea0SLionel Sambuc * 522ebfedea0SLionel Sambuc * A counted_octet_string is simply an array of bytes prefixed with a 16 523ebfedea0SLionel Sambuc * bit length. For the realm and name components, the counted_octet_string 524ebfedea0SLionel Sambuc * bytes are ASCII encoded text with no zero terminator. 525ebfedea0SLionel Sambuc * 526ebfedea0SLionel Sambuc * Following the realm is the components array that represents the name of 527ebfedea0SLionel Sambuc * the principal. The text of these components may be joined with slashs 528ebfedea0SLionel Sambuc * to construct the typical SPN representation. For example, the service 529ebfedea0SLionel Sambuc * principal HTTP/www.foo.net\@FOO.NET would consist of name components 530ebfedea0SLionel Sambuc * "HTTP" followed by "www.foo.net". 531ebfedea0SLionel Sambuc * 532ebfedea0SLionel Sambuc * Following the components array is the 32 bit name_type (e.g. 1 is 533ebfedea0SLionel Sambuc * KRB5_NT_PRINCIPAL, 2 is KRB5_NT_SRV_INST, 5 is KRB5_NT_UID, etc). In 534ebfedea0SLionel Sambuc * practice the name_type is almost certainly 1 meaning KRB5_NT_PRINCIPAL. 535ebfedea0SLionel Sambuc * 536ebfedea0SLionel Sambuc * The 32 bit timestamp indicates the time the key was established for that 537ebfedea0SLionel Sambuc * principal. The value represents the number of seconds since Jan 1, 1970. 538ebfedea0SLionel Sambuc * 539ebfedea0SLionel Sambuc * The 8 bit vno8 field is the version number of the key. This value is 540ebfedea0SLionel Sambuc * overridden by the 32 bit vno field if it is present. The vno8 field is 541ebfedea0SLionel Sambuc * filled with the lower 8 bits of the 32 bit protocol kvno field. 542ebfedea0SLionel Sambuc * 543ebfedea0SLionel Sambuc * The keyblock structure consists of a 16 bit value indicating the 544ebfedea0SLionel Sambuc * encryption type and is a counted_octet_string containing the key. The 545ebfedea0SLionel Sambuc * encryption type is the same as the Kerberos standard (e.g. 3 is 546ebfedea0SLionel Sambuc * des-cbc-md5, 23 is arcfour-hmac-md5, etc). 547ebfedea0SLionel Sambuc * 548ebfedea0SLionel Sambuc * The last field of the keytab_entry structure is optional. If the size of 549ebfedea0SLionel Sambuc * the keytab_entry indicates that there are at least 4 bytes remaining, 550ebfedea0SLionel Sambuc * a 32 bit value representing the key version number is present. This 551ebfedea0SLionel Sambuc * value supersedes the 8 bit vno8 value preceeding the keyblock. 552ebfedea0SLionel Sambuc * 553ebfedea0SLionel Sambuc * Older keytabs with a file_format_version of 0x501 are different in 554ebfedea0SLionel Sambuc * three ways: 555ebfedea0SLionel Sambuc * 556ebfedea0SLionel Sambuc * - All integers are in host byte order [1]. 557ebfedea0SLionel Sambuc * - The num_components field is 1 too large (i.e. after decoding, decrement by 1). 558ebfedea0SLionel Sambuc * - The 32 bit name_type field is not present. 559ebfedea0SLionel Sambuc * 560ebfedea0SLionel Sambuc * [1] The file_format_version field should really be treated as two 561ebfedea0SLionel Sambuc * separate 8 bit quantities representing the major and minor version 562ebfedea0SLionel Sambuc * number respectively. 563ebfedea0SLionel Sambuc * 564ebfedea0SLionel Sambuc * @subsection file_hdb_dump Heimdal database dump file 565ebfedea0SLionel Sambuc * 566ebfedea0SLionel Sambuc * Format of the Heimdal text dump file as of Heimdal 0.6.3: 567ebfedea0SLionel Sambuc * 568ebfedea0SLionel Sambuc * Each line in the dump file is one entry in the database. 569ebfedea0SLionel Sambuc * 570ebfedea0SLionel Sambuc * Each field of a line is separated by one or more spaces, with the 571ebfedea0SLionel Sambuc * exception of fields consisting of principals containing spaces, where 572ebfedea0SLionel Sambuc * space can be quoted with \ and \ is quoted by \. 573ebfedea0SLionel Sambuc * 574ebfedea0SLionel Sambuc * Fields and their types are: 575ebfedea0SLionel Sambuc * 576ebfedea0SLionel Sambuc * @code 577ebfedea0SLionel Sambuc * Quoted princial (quote character is \) [string] 578ebfedea0SLionel Sambuc * Keys [keys] 579ebfedea0SLionel Sambuc * Created by [event] 580ebfedea0SLionel Sambuc * Modified by [event optional] 581ebfedea0SLionel Sambuc * Valid start time [time optional] 582ebfedea0SLionel Sambuc * Valid end time [time optional] 583ebfedea0SLionel Sambuc * Password end valid time [time optional] 584ebfedea0SLionel Sambuc * Max lifetime of ticket [time optional] 585ebfedea0SLionel Sambuc * Max renew time of ticket [integer optional] 586ebfedea0SLionel Sambuc * Flags [hdb flags] 587ebfedea0SLionel Sambuc * Generation number [generation optional] 588ebfedea0SLionel Sambuc * Extensions [extentions optional] 589ebfedea0SLionel Sambuc * @endcode 590ebfedea0SLionel Sambuc * 591ebfedea0SLionel Sambuc * Fields following these silently are ignored. 592ebfedea0SLionel Sambuc * 593ebfedea0SLionel Sambuc * All optional fields will be skipped if they fail to parse (or comprise 594ebfedea0SLionel Sambuc * the optional field marker of "-", w/o quotes). 595ebfedea0SLionel Sambuc * 596ebfedea0SLionel Sambuc * Example: 597ebfedea0SLionel Sambuc * 598ebfedea0SLionel Sambuc * @code 599ebfedea0SLionel Sambuc * 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 - 600ebfedea0SLionel Sambuc * @endcode 601ebfedea0SLionel Sambuc * 602ebfedea0SLionel Sambuc * Encoding of types are as follows: 603ebfedea0SLionel Sambuc * 604ebfedea0SLionel Sambuc * - keys 605ebfedea0SLionel Sambuc * 606ebfedea0SLionel Sambuc * @code 607ebfedea0SLionel Sambuc * kvno:[masterkvno:keytype:keydata:salt]{zero or more separated by :} 608ebfedea0SLionel Sambuc * @endcode 609ebfedea0SLionel Sambuc * 610ebfedea0SLionel Sambuc * kvno is the key version number. 611ebfedea0SLionel Sambuc * 612ebfedea0SLionel Sambuc * keydata is hex-encoded 613ebfedea0SLionel Sambuc * 614ebfedea0SLionel Sambuc * masterkvno is the kvno of the database master key. If this field is 615ebfedea0SLionel Sambuc * empty, the kadmin load and merge operations will encrypt the key data 616ebfedea0SLionel Sambuc * with the master key if there is one. Otherwise the key data will be 617ebfedea0SLionel Sambuc * imported asis. 618ebfedea0SLionel Sambuc * 619ebfedea0SLionel Sambuc * salt is encoded as "-" (no/default salt) or 620ebfedea0SLionel Sambuc * 621ebfedea0SLionel Sambuc * @code 622ebfedea0SLionel Sambuc * salt-type / 623ebfedea0SLionel Sambuc * salt-type / "string" 624ebfedea0SLionel Sambuc * salt-type / hex-encoded-data 625ebfedea0SLionel Sambuc * @endcode 626ebfedea0SLionel Sambuc * 627ebfedea0SLionel Sambuc * keytype is the protocol enctype number; see enum ENCTYPE in 628ebfedea0SLionel Sambuc * include/krb5_asn1.h for values. 629ebfedea0SLionel Sambuc * 630ebfedea0SLionel Sambuc * Example: 631ebfedea0SLionel Sambuc * @code 632ebfedea0SLionel Sambuc * 27:1:16:e8b4c8fc7e60b9e641dcf4cff3f08a701d982a2f89ba373733d26ca59ba6c789666f6b8bfcf169412bb1e5dceb9b33cda29f3412:-:1:3:4498a933881178c744f4232172dcd774c64e81fa6d05ecdf643a7e390624a0ebf3c7407a:-:1:2:b01934b13eb795d76f3a80717d469639b4da0cfb644161340ef44fdeb375e54d684dbb85:-:1:1:ea8e16d8078bf60c781da90f508d4deccba70595258b9d31888d33987cd31af0c9cced2e:- 633ebfedea0SLionel Sambuc * @endcode 634ebfedea0SLionel Sambuc * 635ebfedea0SLionel Sambuc * 636ebfedea0SLionel Sambuc * @code 637ebfedea0SLionel Sambuc * kvno=27,{key: masterkvno=1,keytype=des3-cbc-sha1,keydata=..., default salt}... 638ebfedea0SLionel Sambuc * @endcode 639ebfedea0SLionel Sambuc * 640ebfedea0SLionel Sambuc * - time 641ebfedea0SLionel Sambuc * 642ebfedea0SLionel Sambuc * Format of the time is: YYYYmmddHHMMSS, corresponding to strftime 643ebfedea0SLionel Sambuc * format "%Y%m%d%k%M%S". 644ebfedea0SLionel Sambuc * 645ebfedea0SLionel Sambuc * Time is expressed in UTC. 646ebfedea0SLionel Sambuc * 647ebfedea0SLionel Sambuc * Time can be optional (using -), when the time 0 is used. 648ebfedea0SLionel Sambuc * 649ebfedea0SLionel Sambuc * Example: 650ebfedea0SLionel Sambuc * 651ebfedea0SLionel Sambuc * @code 652ebfedea0SLionel Sambuc * 20041221112428 653ebfedea0SLionel Sambuc * @endcode 654ebfedea0SLionel Sambuc * 655ebfedea0SLionel Sambuc * - event 656ebfedea0SLionel Sambuc * 657ebfedea0SLionel Sambuc * @code 658ebfedea0SLionel Sambuc * time:principal 659ebfedea0SLionel Sambuc * @endcode 660ebfedea0SLionel Sambuc * 661ebfedea0SLionel Sambuc * time is as given in format time 662ebfedea0SLionel Sambuc * 663ebfedea0SLionel Sambuc * principal is a string. Not quoting it may not work in earlier 664ebfedea0SLionel Sambuc * versions of Heimdal. 665ebfedea0SLionel Sambuc * 666ebfedea0SLionel Sambuc * Example: 667ebfedea0SLionel Sambuc * @code 668ebfedea0SLionel Sambuc * 20041221112428:bloggs\@CODE.COM 669ebfedea0SLionel Sambuc * @endcode 670ebfedea0SLionel Sambuc * 671ebfedea0SLionel Sambuc * - hdb flags 672ebfedea0SLionel Sambuc * 673ebfedea0SLionel Sambuc * Integer encoding of HDB flags, see HDBFlags in lib/hdb/hdb.asn1. Each 674ebfedea0SLionel Sambuc * bit in the integer is the same as the bit in the specification. 675ebfedea0SLionel Sambuc * 676ebfedea0SLionel Sambuc * - generation: 677ebfedea0SLionel Sambuc * 678ebfedea0SLionel Sambuc * @code 679ebfedea0SLionel Sambuc * time:usec:gen 680ebfedea0SLionel Sambuc * @endcode 681ebfedea0SLionel Sambuc * 682ebfedea0SLionel Sambuc * 683ebfedea0SLionel Sambuc * usec is a the microsecond, integer. 684ebfedea0SLionel Sambuc * gen is generation number, integer. 685ebfedea0SLionel Sambuc * 686ebfedea0SLionel Sambuc * The generation can be defaulted (using '-') or the empty string 687ebfedea0SLionel Sambuc * 688ebfedea0SLionel Sambuc * - extensions: 689ebfedea0SLionel Sambuc * 690ebfedea0SLionel Sambuc * @code 691ebfedea0SLionel Sambuc * first-hex-encoded-HDB-Extension[:second-...] 692ebfedea0SLionel Sambuc * @endcode 693ebfedea0SLionel Sambuc * 694ebfedea0SLionel Sambuc * HDB-extension is encoded the DER encoded HDB-Extension from 695ebfedea0SLionel Sambuc * lib/hdb/hdb.asn1. Consumers HDB extensions should be aware that 696ebfedea0SLionel Sambuc * unknown entires needs to be preserved even thought the ASN.1 data 697ebfedea0SLionel Sambuc * content might be unknown. There is a critical flag in the data to show 698ebfedea0SLionel Sambuc * to the KDC that the entry MUST be understod if the entry is to be 699ebfedea0SLionel Sambuc * used. 700ebfedea0SLionel Sambuc * 701ebfedea0SLionel Sambuc * 702ebfedea0SLionel Sambuc */ 703