1178825Sdfr/* 2233294Sstas * Copyright (c) 2007-2008 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 5178825Sdfr * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 9178825Sdfr * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 12178825Sdfr * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 16178825Sdfr * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 20178825Sdfr * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 32178825Sdfr */ 33178825Sdfr 34178825Sdfr#include "krb5_locl.h" 35178825Sdfr 36178825Sdfr/** 37233294Sstas * 38178825Sdfr */ 39178825Sdfr 40233294Sstas/*! @mainpage Heimdal Kerberos 5 library 41178825Sdfr * 42233294Sstas * @section intro Introduction 43178825Sdfr * 44178825Sdfr * Heimdal libkrb5 library is a implementation of the Kerberos 45178825Sdfr * protocol. 46233294Sstas * 47178825Sdfr * Kerberos is a system for authenticating users and services on a 48178825Sdfr * network. It is built upon the assumption that the network is 49178825Sdfr * ``unsafe''. For example, data sent over the network can be 50178825Sdfr * eavesdropped and altered, and addresses can also be faked. 51178825Sdfr * Therefore they cannot be used for authentication purposes. 52178825Sdfr * 53178825Sdfr * 54233294Sstas * - @ref krb5_introduction 55233294Sstas * - @ref krb5_principal_intro 56233294Sstas * - @ref krb5_ccache_intro 57233294Sstas * - @ref krb5_keytab_intro 58233294Sstas * 59233294Sstas * If you want to know more about the file formats that is used by 60233294Sstas * Heimdal, please see: @ref krb5_fileformats 61233294Sstas * 62233294Sstas * The project web page: http://www.h5l.org/ 63233294Sstas * 64178825Sdfr */ 65178825Sdfr 66178825Sdfr/** @defgroup krb5 Heimdal Kerberos 5 library */ 67178825Sdfr/** @defgroup krb5_address Heimdal Kerberos 5 address functions */ 68233294Sstas/** @defgroup krb5_principal Heimdal Kerberos 5 principal functions */ 69178825Sdfr/** @defgroup krb5_ccache Heimdal Kerberos 5 credential cache functions */ 70233294Sstas/** @defgroup krb5_crypto Heimdal Kerberos 5 cryptography functions */ 71178825Sdfr/** @defgroup krb5_credential Heimdal Kerberos 5 credential handing functions */ 72178825Sdfr/** @defgroup krb5_deprecated Heimdal Kerberos 5 deprecated functions */ 73178825Sdfr/** @defgroup krb5_digest Heimdal Kerberos 5 digest service */ 74178825Sdfr/** @defgroup krb5_error Heimdal Kerberos 5 error reporting functions */ 75233294Sstas/** @defgroup krb5_keytab Heimdal Kerberos 5 keytab handling functions */ 76233294Sstas/** @defgroup krb5_ticket Heimdal Kerberos 5 ticket functions */ 77233294Sstas/** @defgroup krb5_pac Heimdal Kerberos 5 PAC handling functions */ 78178825Sdfr/** @defgroup krb5_v4compat Heimdal Kerberos 4 compatiblity functions */ 79233294Sstas/** @defgroup krb5_storage Heimdal Kerberos 5 storage functions */ 80178825Sdfr/** @defgroup krb5_support Heimdal Kerberos 5 support functions */ 81233294Sstas/** @defgroup krb5_auth Heimdal Kerberos 5 authentication functions */ 82233294Sstas 83233294Sstas 84233294Sstas/** 85233294Sstas * @page krb5_introduction Introduction to the Kerberos 5 API 86233294Sstas * @section api_overview Kerberos 5 API Overview 87233294Sstas * 88233294Sstas * All functions are documented in manual pages. This section tries 89233294Sstas * to give an overview of the major components used in Kerberos 90233294Sstas * library, and point to where to look for a specific function. 91233294Sstas * 92233294Sstas * @subsection intro_krb5_context Kerberos context 93233294Sstas * 94233294Sstas * A kerberos context (krb5_context) holds all per thread state. All 95233294Sstas * global variables that are context specific are stored in this 96233294Sstas * structure, including default encryption types, credential cache 97233294Sstas * (for example, a ticket file), and default realms. 98233294Sstas * 99233294Sstas * The internals of the structure should never be accessed directly, 100233294Sstas * functions exist for extracting information. 101233294Sstas * 102233294Sstas * See the manual page for krb5_init_context() how to create a context 103233294Sstas * and module @ref krb5 for more information about the functions. 104233294Sstas * 105233294Sstas * @subsection intro_krb5_auth_context Kerberos authentication context 106233294Sstas * 107233294Sstas * Kerberos authentication context (krb5_auth_context) holds all 108233294Sstas * context related to an authenticated connection, in a similar way to 109233294Sstas * the kerberos context that holds the context for the thread or 110233294Sstas * process. 111233294Sstas * 112233294Sstas * The krb5_auth_context is used by various functions that are 113233294Sstas * directly related to authentication between the 114233294Sstas * server/client. Example of data that this structure contains are 115233294Sstas * various flags, addresses of client and server, port numbers, 116233294Sstas * keyblocks (and subkeys), sequence numbers, replay cache, and 117233294Sstas * checksum types. 118233294Sstas * 119233294Sstas * @subsection intro_krb5_principal Kerberos principal 120233294Sstas * 121233294Sstas * The Kerberos principal is the structure that identifies a user or 122233294Sstas * service in Kerberos. The structure that holds the principal is the 123233294Sstas * krb5_principal. There are function to extract the realm and 124233294Sstas * elements of the principal, but most applications have no reason to 125233294Sstas * inspect the content of the structure. 126233294Sstas * 127233294Sstas * The are several ways to create a principal (with different degree of 128233294Sstas * portability), and one way to free it. 129233294Sstas * 130233294Sstas * See also the page @ref krb5_principal_intro for more information and also 131233294Sstas * module @ref krb5_principal. 132233294Sstas * 133233294Sstas * @subsection intro_krb5_ccache Credential cache 134233294Sstas * 135233294Sstas * A credential cache holds the tickets for a user. A given user can 136233294Sstas * have several credential caches, one for each realm where the user 137233294Sstas * have the initial tickets (the first krbtgt). 138233294Sstas * 139233294Sstas * The credential cache data can be stored internally in different 140233294Sstas * way, each of them for different proposes. File credential (FILE) 141233294Sstas * caches and processes based (KCM) caches are for permanent 142233294Sstas * storage. While memory caches (MEMORY) are local caches to the local 143233294Sstas * process. 144233294Sstas * 145233294Sstas * Caches are opened with krb5_cc_resolve() or created with 146233294Sstas * krb5_cc_new_unique(). 147233294Sstas * 148233294Sstas * If the cache needs to be opened again (using krb5_cc_resolve()) 149233294Sstas * krb5_cc_close() will close the handle, but not the remove the 150233294Sstas * cache. krb5_cc_destroy() will zero out the cache, remove the cache 151233294Sstas * so it can no longer be referenced. 152233294Sstas * 153233294Sstas * See also @ref krb5_ccache_intro and @ref krb5_ccache . 154233294Sstas * 155233294Sstas * @subsection intro_krb5_error_code Kerberos errors 156233294Sstas * 157233294Sstas * Kerberos errors are based on the com_err library. All error codes are 158233294Sstas * 32-bit signed numbers, the first 24 bits define what subsystem the 159233294Sstas * error originates from, and last 8 bits are 255 error codes within the 160233294Sstas * library. Each error code have fixed string associated with it. For 161233294Sstas * example, the error-code -1765328383 have the symbolic name 162233294Sstas * KRB5KDC_ERR_NAME_EXP, and associated error string ``Client's entry in 163233294Sstas * database has expired''. 164233294Sstas * 165233294Sstas * This is a great improvement compared to just getting one of the unix 166233294Sstas * error-codes back. However, Heimdal have an extention to pass back 167233294Sstas * customised errors messages. Instead of getting ``Key table entry not 168233294Sstas * found'', the user might back ``failed to find 169233294Sstas * host/host.example.com\@EXAMLE.COM(kvno 3) in keytab /etc/krb5.keytab 170233294Sstas * (des-cbc-crc)''. This improves the chance that the user find the 171233294Sstas * cause of the error so you should use the customised error message 172233294Sstas * whenever it's available. 173233294Sstas * 174233294Sstas * See also module @ref krb5_error . 175233294Sstas * 176233294Sstas * 177233294Sstas * @subsection intro_krb5_keytab Keytab management 178233294Sstas * 179233294Sstas * A keytab is a storage for locally stored keys. Heimdal includes keytab 180233294Sstas * support for Kerberos 5 keytabs, Kerberos 4 srvtab, AFS-KeyFile's, 181233294Sstas * and for storing keys in memory. 182233294Sstas * 183233294Sstas * Keytabs are used for servers and long-running services. 184233294Sstas * 185233294Sstas * See also @ref krb5_keytab_intro and @ref krb5_keytab . 186233294Sstas * 187233294Sstas * @subsection intro_krb5_crypto Kerberos crypto 188233294Sstas * 189233294Sstas * Heimdal includes a implementation of the Kerberos crypto framework, 190233294Sstas * all crypto operations. To create a crypto context call krb5_crypto_init(). 191233294Sstas * 192233294Sstas * See also module @ref krb5_crypto . 193233294Sstas * 194233294Sstas * @section kerberos5_client Walkthrough of a sample Kerberos 5 client 195233294Sstas * 196233294Sstas * This example contains parts of a sample TCP Kerberos 5 clients, if you 197233294Sstas * want a real working client, please look in appl/test directory in 198233294Sstas * the Heimdal distribution. 199233294Sstas * 200233294Sstas * All Kerberos error-codes that are returned from kerberos functions in 201233294Sstas * this program are passed to krb5_err, that will print a 202233294Sstas * descriptive text of the error code and exit. Graphical programs can 203233294Sstas * convert error-code to a human readable error-string with the 204233294Sstas * krb5_get_error_message() function. 205233294Sstas * 206233294Sstas * Note that you should not use any Kerberos function before 207233294Sstas * krb5_init_context() have completed successfully. That is the 208233294Sstas * reason err() is used when krb5_init_context() fails. 209233294Sstas * 210233294Sstas * First the client needs to call krb5_init_context to initialise 211233294Sstas * the Kerberos 5 library. This is only needed once per thread 212233294Sstas * in the program. If the function returns a non-zero value it indicates 213233294Sstas * that either the Kerberos implementation is failing or it's disabled on 214233294Sstas * this host. 215233294Sstas * 216233294Sstas * @code 217233294Sstas * #include <krb5.h> 218233294Sstas * 219233294Sstas * int 220233294Sstas * main(int argc, char **argv) 221233294Sstas * { 222233294Sstas * krb5_context context; 223233294Sstas * 224233294Sstas * if (krb5_init_context(&context)) 225233294Sstas * errx (1, "krb5_context"); 226233294Sstas * @endcode 227233294Sstas * 228233294Sstas * Now the client wants to connect to the host at the other end. The 229233294Sstas * preferred way of doing this is using getaddrinfo (for 230233294Sstas * operating system that have this function implemented), since getaddrinfo 231233294Sstas * is neutral to the address type and can use any protocol that is available. 232233294Sstas * 233233294Sstas * @code 234233294Sstas * struct addrinfo *ai, *a; 235233294Sstas * struct addrinfo hints; 236233294Sstas * int error; 237233294Sstas * 238233294Sstas * memset (&hints, 0, sizeof(hints)); 239233294Sstas * hints.ai_socktype = SOCK_STREAM; 240233294Sstas * hints.ai_protocol = IPPROTO_TCP; 241233294Sstas * 242233294Sstas * error = getaddrinfo (hostname, "pop3", &hints, &ai); 243233294Sstas * if (error) 244233294Sstas * errx (1, "%s: %s", hostname, gai_strerror(error)); 245233294Sstas * 246233294Sstas * for (a = ai; a != NULL; a = a->ai_next) { 247233294Sstas * int s; 248233294Sstas * 249233294Sstas * s = socket (a->ai_family, a->ai_socktype, a->ai_protocol); 250233294Sstas * if (s < 0) 251233294Sstas * continue; 252233294Sstas * if (connect (s, a->ai_addr, a->ai_addrlen) < 0) { 253233294Sstas * warn ("connect(%s)", hostname); 254233294Sstas * close (s); 255233294Sstas * continue; 256233294Sstas * } 257233294Sstas * freeaddrinfo (ai); 258233294Sstas * ai = NULL; 259233294Sstas * } 260233294Sstas * if (ai) { 261233294Sstas * freeaddrinfo (ai); 262233294Sstas * errx ("failed to contact %s", hostname); 263233294Sstas * } 264233294Sstas * @endcode 265233294Sstas * 266233294Sstas * Before authenticating, an authentication context needs to be 267233294Sstas * created. This context keeps all information for one (to be) authenticated 268233294Sstas * connection (see krb5_auth_context). 269233294Sstas * 270233294Sstas * @code 271233294Sstas * status = krb5_auth_con_init (context, &auth_context); 272233294Sstas * if (status) 273233294Sstas * krb5_err (context, 1, status, "krb5_auth_con_init"); 274233294Sstas * @endcode 275233294Sstas * 276233294Sstas * For setting the address in the authentication there is a help function 277233294Sstas * krb5_auth_con_setaddrs_from_fd() that does everything that is needed 278233294Sstas * when given a connected file descriptor to the socket. 279233294Sstas * 280233294Sstas * @code 281233294Sstas * status = krb5_auth_con_setaddrs_from_fd (context, 282233294Sstas * auth_context, 283233294Sstas * &sock); 284233294Sstas * if (status) 285233294Sstas * krb5_err (context, 1, status, 286233294Sstas * "krb5_auth_con_setaddrs_from_fd"); 287233294Sstas * @endcode 288233294Sstas * 289233294Sstas * The next step is to build a server principal for the service we want 290233294Sstas * to connect to. (See also krb5_sname_to_principal().) 291233294Sstas * 292233294Sstas * @code 293233294Sstas * status = krb5_sname_to_principal (context, 294233294Sstas * hostname, 295233294Sstas * service, 296233294Sstas * KRB5_NT_SRV_HST, 297233294Sstas * &server); 298233294Sstas * if (status) 299233294Sstas * krb5_err (context, 1, status, "krb5_sname_to_principal"); 300233294Sstas * @endcode 301233294Sstas * 302233294Sstas * The client principal is not passed to krb5_sendauth() 303233294Sstas * function, this causes the krb5_sendauth() function to try to figure it 304233294Sstas * out itself. 305233294Sstas * 306233294Sstas * The server program is using the function krb5_recvauth() to 307233294Sstas * receive the Kerberos 5 authenticator. 308233294Sstas * 309233294Sstas * In this case, mutual authentication will be tried. That means that the server 310233294Sstas * will authenticate to the client. Using mutual authentication 311233294Sstas * is good since it enables the user to verify that they are talking to the 312233294Sstas * right server (a server that knows the key). 313233294Sstas * 314233294Sstas * If you are using a non-blocking socket you will need to do all work of 315233294Sstas * krb5_sendauth() yourself. Basically you need to send over the 316233294Sstas * authenticator from krb5_mk_req() and, in case of mutual 317233294Sstas * authentication, verifying the result from the server with 318233294Sstas * krb5_rd_rep(). 319233294Sstas * 320233294Sstas * @code 321233294Sstas * status = krb5_sendauth (context, 322233294Sstas * &auth_context, 323233294Sstas * &sock, 324233294Sstas * VERSION, 325233294Sstas * NULL, 326233294Sstas * server, 327233294Sstas * AP_OPTS_MUTUAL_REQUIRED, 328233294Sstas * NULL, 329233294Sstas * NULL, 330233294Sstas * NULL, 331233294Sstas * NULL, 332233294Sstas * NULL, 333233294Sstas * NULL); 334233294Sstas * if (status) 335233294Sstas * krb5_err (context, 1, status, "krb5_sendauth"); 336233294Sstas * @endcode 337233294Sstas * 338233294Sstas * Once authentication has been performed, it is time to send some 339233294Sstas * data. First we create a krb5_data structure, then we sign it with 340233294Sstas * krb5_mk_safe() using the auth_context that contains the 341233294Sstas * session-key that was exchanged in the 342233294Sstas * krb5_sendauth()/krb5_recvauth() authentication 343233294Sstas * sequence. 344233294Sstas * 345233294Sstas * @code 346233294Sstas * data.data = "hej"; 347233294Sstas * data.length = 3; 348233294Sstas * 349233294Sstas * krb5_data_zero (&packet); 350233294Sstas * 351233294Sstas * status = krb5_mk_safe (context, 352233294Sstas * auth_context, 353233294Sstas * &data, 354233294Sstas * &packet, 355233294Sstas * NULL); 356233294Sstas * if (status) 357233294Sstas * krb5_err (context, 1, status, "krb5_mk_safe"); 358233294Sstas * @endcode 359233294Sstas * 360233294Sstas * And send it over the network. 361233294Sstas * 362233294Sstas * @code 363233294Sstas * len = packet.length; 364233294Sstas * net_len = htonl(len); 365233294Sstas * 366233294Sstas * if (krb5_net_write (context, &sock, &net_len, 4) != 4) 367233294Sstas * err (1, "krb5_net_write"); 368233294Sstas * if (krb5_net_write (context, &sock, packet.data, len) != len) 369233294Sstas * err (1, "krb5_net_write"); 370233294Sstas * @endcode 371233294Sstas * 372233294Sstas * To send encrypted (and signed) data krb5_mk_priv() should be 373233294Sstas * used instead. krb5_mk_priv() works the same way as 374233294Sstas * krb5_mk_safe(), with the exception that it encrypts the data 375233294Sstas * in addition to signing it. 376233294Sstas * 377233294Sstas * @code 378233294Sstas * data.data = "hemligt"; 379233294Sstas * data.length = 7; 380233294Sstas * 381233294Sstas * krb5_data_free (&packet); 382233294Sstas * 383233294Sstas * status = krb5_mk_priv (context, 384233294Sstas * auth_context, 385233294Sstas * &data, 386233294Sstas * &packet, 387233294Sstas * NULL); 388233294Sstas * if (status) 389233294Sstas * krb5_err (context, 1, status, "krb5_mk_priv"); 390233294Sstas * @endcode 391233294Sstas * 392233294Sstas * And send it over the network. 393233294Sstas * 394233294Sstas * @code 395233294Sstas * len = packet.length; 396233294Sstas * net_len = htonl(len); 397233294Sstas * 398233294Sstas * if (krb5_net_write (context, &sock, &net_len, 4) != 4) 399233294Sstas * err (1, "krb5_net_write"); 400233294Sstas * if (krb5_net_write (context, &sock, packet.data, len) != len) 401233294Sstas * err (1, "krb5_net_write"); 402233294Sstas * 403233294Sstas * @endcode 404233294Sstas * 405233294Sstas * The server is using krb5_rd_safe() and 406233294Sstas * krb5_rd_priv() to verify the signature and decrypt the packet. 407233294Sstas * 408233294Sstas * @section intro_krb5_verify_user Validating a password in an application 409233294Sstas * 410233294Sstas * See the manual page for krb5_verify_user(). 411233294Sstas * 412233294Sstas * @section mit_differences API differences to MIT Kerberos 413233294Sstas * 414233294Sstas * This section is somewhat disorganised, but so far there is no overall 415233294Sstas * structure to the differences, though some of the have their root in 416233294Sstas * that Heimdal uses an ASN.1 compiler and MIT doesn't. 417233294Sstas * 418233294Sstas * @subsection mit_krb5_principal Principal and realms 419233294Sstas * 420233294Sstas * Heimdal stores the realm as a krb5_realm, that is a char *. 421233294Sstas * MIT Kerberos uses a krb5_data to store a realm. 422233294Sstas * 423233294Sstas * In Heimdal krb5_principal doesn't contain the component 424233294Sstas * name_type; it's instead stored in component 425233294Sstas * name.name_type. To get and set the nametype in Heimdal, use 426233294Sstas * krb5_principal_get_type() and 427233294Sstas * krb5_principal_set_type(). 428233294Sstas * 429233294Sstas * For more information about principal and realms, see 430233294Sstas * krb5_principal. 431233294Sstas * 432233294Sstas * @subsection mit_krb5_error_code Error messages 433233294Sstas * 434233294Sstas * To get the error string, Heimdal uses 435233294Sstas * krb5_get_error_message(). This is to return custom error messages 436233294Sstas * (like ``Can't find host/datan.example.com\@CODE.COM in 437233294Sstas * /etc/krb5.conf.'' instead of a ``Key table entry not found'' that 438233294Sstas * error_message returns. 439233294Sstas * 440233294Sstas * Heimdal uses a threadsafe(r) version of the com_err interface; the 441233294Sstas * global com_err table isn't initialised. Then 442233294Sstas * error_message returns quite a boring error string (just 443233294Sstas * the error code itself). 444233294Sstas * 445233294Sstas * 446233294Sstas */ 447233294Sstas 448233294Sstas/** 449233294Sstas * 450233294Sstas * 451233294Sstas * @page krb5_fileformats File formats 452233294Sstas * 453233294Sstas * @section fileformats File formats 454233294Sstas * 455233294Sstas * This section documents the diffrent file formats that are used in 456233294Sstas * Heimdal and other Kerberos implementations. 457233294Sstas * 458233294Sstas * @subsection file_keytab keytab 459233294Sstas * 460233294Sstas * The keytab binary format is not a standard format. The format has 461233294Sstas * evolved and may continue to. It is however understood by several 462233294Sstas * Kerberos implementations including Heimdal, MIT, Sun's Java ktab and 463233294Sstas * are created by the ktpass.exe utility from Windows. So it has 464233294Sstas * established itself as the defacto format for storing Kerberos keys. 465233294Sstas * 466233294Sstas * The following C-like structure definitions illustrate the MIT keytab 467233294Sstas * file format. All values are in network byte order. All text is ASCII. 468233294Sstas * 469233294Sstas * @code 470233294Sstas * keytab { 471233294Sstas * uint16_t file_format_version; # 0x502 472233294Sstas * keytab_entry entries[*]; 473233294Sstas * }; 474233294Sstas * 475233294Sstas * keytab_entry { 476233294Sstas * int32_t size; 477233294Sstas * uint16_t num_components; # subtract 1 if version 0x501 478233294Sstas * counted_octet_string realm; 479233294Sstas * counted_octet_string components[num_components]; 480233294Sstas * uint32_t name_type; # not present if version 0x501 481233294Sstas * uint32_t timestamp; 482233294Sstas * uint8_t vno8; 483233294Sstas * keyblock key; 484233294Sstas * uint32_t vno; #only present if >= 4 bytes left in entry 485233294Sstas * uint32_t flags; #only present if >= 4 bytes left in entry 486233294Sstas * }; 487233294Sstas * 488233294Sstas * counted_octet_string { 489233294Sstas * uint16_t length; 490233294Sstas * uint8_t data[length]; 491233294Sstas * }; 492233294Sstas * 493233294Sstas * keyblock { 494233294Sstas * uint16_t type; 495233294Sstas * counted_octet_string; 496233294Sstas * }; 497233294Sstas * @endcode 498233294Sstas * 499233294Sstas * All numbers are stored in network byteorder (big endian) format. 500233294Sstas * 501233294Sstas * The keytab file format begins with the 16 bit file_format_version which 502233294Sstas * at the time this document was authored is 0x502. The format of older 503233294Sstas * keytabs is described at the end of this document. 504233294Sstas * 505233294Sstas * The file_format_version is immediately followed by an array of 506233294Sstas * keytab_entry structures which are prefixed with a 32 bit size indicating 507233294Sstas * the number of bytes that follow in the entry. Note that the size should be 508233294Sstas * evaluated as signed. This is because a negative value indicates that the 509233294Sstas * entry is in fact empty (e.g. it has been deleted) and that the negative 510233294Sstas * value of that negative value (which is of course a positive value) is 511233294Sstas * the offset to the next keytab_entry. Based on these size values alone 512233294Sstas * the entire keytab file can be traversed. 513233294Sstas * 514233294Sstas * The size is followed by a 16 bit num_components field indicating the 515233294Sstas * number of counted_octet_string components in the components array. 516233294Sstas * 517233294Sstas * The num_components field is followed by a counted_octet_string 518233294Sstas * representing the realm of the principal. 519233294Sstas * 520233294Sstas * A counted_octet_string is simply an array of bytes prefixed with a 16 521233294Sstas * bit length. For the realm and name components, the counted_octet_string 522233294Sstas * bytes are ASCII encoded text with no zero terminator. 523233294Sstas * 524233294Sstas * Following the realm is the components array that represents the name of 525233294Sstas * the principal. The text of these components may be joined with slashs 526233294Sstas * to construct the typical SPN representation. For example, the service 527233294Sstas * principal HTTP/www.foo.net\@FOO.NET would consist of name components 528233294Sstas * "HTTP" followed by "www.foo.net". 529233294Sstas * 530233294Sstas * Following the components array is the 32 bit name_type (e.g. 1 is 531233294Sstas * KRB5_NT_PRINCIPAL, 2 is KRB5_NT_SRV_INST, 5 is KRB5_NT_UID, etc). In 532233294Sstas * practice the name_type is almost certainly 1 meaning KRB5_NT_PRINCIPAL. 533233294Sstas * 534233294Sstas * The 32 bit timestamp indicates the time the key was established for that 535233294Sstas * principal. The value represents the number of seconds since Jan 1, 1970. 536233294Sstas * 537233294Sstas * The 8 bit vno8 field is the version number of the key. This value is 538233294Sstas * overridden by the 32 bit vno field if it is present. The vno8 field is 539233294Sstas * filled with the lower 8 bits of the 32 bit protocol kvno field. 540233294Sstas * 541233294Sstas * The keyblock structure consists of a 16 bit value indicating the 542233294Sstas * encryption type and is a counted_octet_string containing the key. The 543233294Sstas * encryption type is the same as the Kerberos standard (e.g. 3 is 544233294Sstas * des-cbc-md5, 23 is arcfour-hmac-md5, etc). 545233294Sstas * 546233294Sstas * The last field of the keytab_entry structure is optional. If the size of 547233294Sstas * the keytab_entry indicates that there are at least 4 bytes remaining, 548233294Sstas * a 32 bit value representing the key version number is present. This 549233294Sstas * value supersedes the 8 bit vno8 value preceeding the keyblock. 550233294Sstas * 551233294Sstas * Older keytabs with a file_format_version of 0x501 are different in 552233294Sstas * three ways: 553233294Sstas * 554233294Sstas * - All integers are in host byte order [1]. 555233294Sstas * - The num_components field is 1 too large (i.e. after decoding, decrement by 1). 556233294Sstas * - The 32 bit name_type field is not present. 557233294Sstas * 558233294Sstas * [1] The file_format_version field should really be treated as two 559233294Sstas * separate 8 bit quantities representing the major and minor version 560233294Sstas * number respectively. 561233294Sstas * 562233294Sstas * @subsection file_hdb_dump Heimdal database dump file 563233294Sstas * 564233294Sstas * Format of the Heimdal text dump file as of Heimdal 0.6.3: 565233294Sstas * 566233294Sstas * Each line in the dump file is one entry in the database. 567233294Sstas * 568233294Sstas * Each field of a line is separated by one or more spaces, with the 569233294Sstas * exception of fields consisting of principals containing spaces, where 570233294Sstas * space can be quoted with \ and \ is quoted by \. 571233294Sstas * 572233294Sstas * Fields and their types are: 573233294Sstas * 574233294Sstas * @code 575233294Sstas * Quoted princial (quote character is \) [string] 576233294Sstas * Keys [keys] 577233294Sstas * Created by [event] 578233294Sstas * Modified by [event optional] 579233294Sstas * Valid start time [time optional] 580233294Sstas * Valid end time [time optional] 581233294Sstas * Password end valid time [time optional] 582233294Sstas * Max lifetime of ticket [time optional] 583233294Sstas * Max renew time of ticket [integer optional] 584233294Sstas * Flags [hdb flags] 585233294Sstas * Generation number [generation optional] 586233294Sstas * Extensions [extentions optional] 587233294Sstas * @endcode 588233294Sstas * 589233294Sstas * Fields following these silently are ignored. 590233294Sstas * 591233294Sstas * All optional fields will be skipped if they fail to parse (or comprise 592233294Sstas * the optional field marker of "-", w/o quotes). 593233294Sstas * 594233294Sstas * Example: 595233294Sstas * 596233294Sstas * @code 597233294Sstas * 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 - 598233294Sstas * @endcode 599233294Sstas * 600233294Sstas * Encoding of types are as follows: 601233294Sstas * 602233294Sstas * - keys 603233294Sstas * 604233294Sstas * @code 605233294Sstas * kvno:[masterkvno:keytype:keydata:salt]{zero or more separated by :} 606233294Sstas * @endcode 607233294Sstas * 608233294Sstas * kvno is the key version number. 609233294Sstas * 610233294Sstas * keydata is hex-encoded 611233294Sstas * 612233294Sstas * masterkvno is the kvno of the database master key. If this field is 613233294Sstas * empty, the kadmin load and merge operations will encrypt the key data 614233294Sstas * with the master key if there is one. Otherwise the key data will be 615233294Sstas * imported asis. 616233294Sstas * 617233294Sstas * salt is encoded as "-" (no/default salt) or 618233294Sstas * 619233294Sstas * @code 620233294Sstas * salt-type / 621233294Sstas * salt-type / "string" 622233294Sstas * salt-type / hex-encoded-data 623233294Sstas * @endcode 624233294Sstas * 625233294Sstas * keytype is the protocol enctype number; see enum ENCTYPE in 626233294Sstas * include/krb5_asn1.h for values. 627233294Sstas * 628233294Sstas * Example: 629233294Sstas * @code 630233294Sstas * 27:1:16:e8b4c8fc7e60b9e641dcf4cff3f08a701d982a2f89ba373733d26ca59ba6c789666f6b8bfcf169412bb1e5dceb9b33cda29f3412:-:1:3:4498a933881178c744f4232172dcd774c64e81fa6d05ecdf643a7e390624a0ebf3c7407a:-:1:2:b01934b13eb795d76f3a80717d469639b4da0cfb644161340ef44fdeb375e54d684dbb85:-:1:1:ea8e16d8078bf60c781da90f508d4deccba70595258b9d31888d33987cd31af0c9cced2e:- 631233294Sstas * @endcode 632233294Sstas * 633233294Sstas * 634233294Sstas * @code 635233294Sstas * kvno=27,{key: masterkvno=1,keytype=des3-cbc-sha1,keydata=..., default salt}... 636233294Sstas * @endcode 637233294Sstas * 638233294Sstas * - time 639233294Sstas * 640233294Sstas * Format of the time is: YYYYmmddHHMMSS, corresponding to strftime 641233294Sstas * format "%Y%m%d%k%M%S". 642233294Sstas * 643233294Sstas * Time is expressed in UTC. 644233294Sstas * 645233294Sstas * Time can be optional (using -), when the time 0 is used. 646233294Sstas * 647233294Sstas * Example: 648233294Sstas * 649233294Sstas * @code 650233294Sstas * 20041221112428 651233294Sstas * @endcode 652233294Sstas * 653233294Sstas * - event 654233294Sstas * 655233294Sstas * @code 656233294Sstas * time:principal 657233294Sstas * @endcode 658233294Sstas * 659233294Sstas * time is as given in format time 660233294Sstas * 661233294Sstas * principal is a string. Not quoting it may not work in earlier 662233294Sstas * versions of Heimdal. 663233294Sstas * 664233294Sstas * Example: 665233294Sstas * @code 666233294Sstas * 20041221112428:bloggs\@CODE.COM 667233294Sstas * @endcode 668233294Sstas * 669233294Sstas * - hdb flags 670233294Sstas * 671233294Sstas * Integer encoding of HDB flags, see HDBFlags in lib/hdb/hdb.asn1. Each 672233294Sstas * bit in the integer is the same as the bit in the specification. 673233294Sstas * 674233294Sstas * - generation: 675233294Sstas * 676233294Sstas * @code 677233294Sstas * time:usec:gen 678233294Sstas * @endcode 679233294Sstas * 680233294Sstas * 681233294Sstas * usec is a the microsecond, integer. 682233294Sstas * gen is generation number, integer. 683233294Sstas * 684233294Sstas * The generation can be defaulted (using '-') or the empty string 685233294Sstas * 686233294Sstas * - extensions: 687233294Sstas * 688233294Sstas * @code 689233294Sstas * first-hex-encoded-HDB-Extension[:second-...] 690233294Sstas * @endcode 691233294Sstas * 692233294Sstas * HDB-extension is encoded the DER encoded HDB-Extension from 693233294Sstas * lib/hdb/hdb.asn1. Consumers HDB extensions should be aware that 694233294Sstas * unknown entires needs to be preserved even thought the ASN.1 data 695233294Sstas * content might be unknown. There is a critical flag in the data to show 696233294Sstas * to the KDC that the entry MUST be understod if the entry is to be 697233294Sstas * used. 698233294Sstas * 699233294Sstas * 700233294Sstas */ 701