diff options
Diffstat (limited to 'third_party/heimdal/lib/krb5/doxygen.c')
-rw-r--r-- | third_party/heimdal/lib/krb5/doxygen.c | 700 |
1 files changed, 700 insertions, 0 deletions
diff --git a/third_party/heimdal/lib/krb5/doxygen.c b/third_party/heimdal/lib/krb5/doxygen.c new file mode 100644 index 0000000..e9266c9 --- /dev/null +++ b/third_party/heimdal/lib/krb5/doxygen.c @@ -0,0 +1,700 @@ +/* + * 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" + +/** + * + */ + +/*! @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 krb5_introduction + * - @ref krb5_principal_intro + * - @ref krb5_ccache_intro + * - @ref krb5_keytab_intro + * + * If you want to know more about the file formats that is used by + * Heimdal, please see: @ref krb5_fileformats + * + * The project web page: http://www.h5l.org/ + * + */ + +/** @defgroup krb5 Heimdal Kerberos 5 library */ +/** @defgroup krb5_address Heimdal Kerberos 5 address functions */ +/** @defgroup krb5_principal Heimdal Kerberos 5 principal functions */ +/** @defgroup krb5_ccache Heimdal Kerberos 5 credential cache functions */ +/** @defgroup krb5_crypto Heimdal Kerberos 5 cryptography 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_keytab Heimdal Kerberos 5 keytab handling functions */ +/** @defgroup krb5_ticket Heimdal Kerberos 5 ticket functions */ +/** @defgroup krb5_pac Heimdal Kerberos 5 PAC handling functions */ +/** @defgroup krb5_v4compat Heimdal Kerberos 4 compatiblity functions */ +/** @defgroup krb5_storage Heimdal Kerberos 5 storage functions */ +/** @defgroup krb5_support Heimdal Kerberos 5 support functions */ +/** @defgroup krb5_auth Heimdal Kerberos 5 authentication functions */ + + +/** + * @page krb5_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 intro_krb5_context Kerberos context + * + * A kerberos context (krb5_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. + * + * The internals of the structure should never be accessed directly, + * functions exist for extracting information. + * + * See the manual page for krb5_init_context() how to create a context + * and module @ref krb5 for more information about the functions. + * + * @subsection intro_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 intro_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 also the page @ref krb5_principal_intro for more information and also + * module @ref krb5_principal. + * + * @subsection intro_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_new_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 @ref krb5_ccache_intro and @ref krb5_ccache . + * + * @subsection intro_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 module @ref krb5_error . + * + * + * @subsection intro_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 @ref krb5_keytab_intro and @ref krb5_keytab . + * + * @subsection intro_krb5_crypto Kerberos crypto + * + * Heimdal includes a implementation of the Kerberos crypto framework, + * all crypto operations. To create a crypto context call krb5_crypto_init(). + * + * See also module @ref krb5_crypto . + * + * @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_error_message() 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_init_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 required to avoid man-in-the-middle attacks, 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 intro_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_message(). 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 krb5_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 + * uint32_t flags; #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 principal (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. + * + * + */ |