/*1* Copyright (c) 2007-2008 Kungliga Tekniska Högskolan2* (Royal Institute of Technology, Stockholm, Sweden).3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11*12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* 3. Neither the name of the Institute nor the names of its contributors17* may be used to endorse or promote products derived from this software18* without specific prior written permission.19*20* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND21* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE23* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE24* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL25* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS26* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)27* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT28* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY29* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF30* SUCH DAMAGE.31*/3233#include "krb5_locl.h"3435/**36*37*/3839/*! @mainpage Heimdal Kerberos 5 library40*41* @section intro Introduction42*43* Heimdal libkrb5 library is a implementation of the Kerberos44* protocol.45*46* Kerberos is a system for authenticating users and services on a47* network. It is built upon the assumption that the network is48* ``unsafe''. For example, data sent over the network can be49* eavesdropped and altered, and addresses can also be faked.50* Therefore they cannot be used for authentication purposes.51*52*53* - @ref krb5_introduction54* - @ref krb5_principal_intro55* - @ref krb5_ccache_intro56* - @ref krb5_keytab_intro57*58* If you want to know more about the file formats that is used by59* Heimdal, please see: @ref krb5_fileformats60*61* The project web page: http://www.h5l.org/62*63*/6465/** @defgroup krb5 Heimdal Kerberos 5 library */66/** @defgroup krb5_address Heimdal Kerberos 5 address functions */67/** @defgroup krb5_principal Heimdal Kerberos 5 principal functions */68/** @defgroup krb5_ccache Heimdal Kerberos 5 credential cache functions */69/** @defgroup krb5_crypto Heimdal Kerberos 5 cryptography functions */70/** @defgroup krb5_credential Heimdal Kerberos 5 credential handing functions */71/** @defgroup krb5_deprecated Heimdal Kerberos 5 deprecated functions */72/** @defgroup krb5_digest Heimdal Kerberos 5 digest service */73/** @defgroup krb5_error Heimdal Kerberos 5 error reporting functions */74/** @defgroup krb5_keytab Heimdal Kerberos 5 keytab handling functions */75/** @defgroup krb5_ticket Heimdal Kerberos 5 ticket functions */76/** @defgroup krb5_pac Heimdal Kerberos 5 PAC handling functions */77/** @defgroup krb5_v4compat Heimdal Kerberos 4 compatiblity functions */78/** @defgroup krb5_storage Heimdal Kerberos 5 storage functions */79/** @defgroup krb5_support Heimdal Kerberos 5 support functions */80/** @defgroup krb5_auth Heimdal Kerberos 5 authentication functions */818283/**84* @page krb5_introduction Introduction to the Kerberos 5 API85* @section api_overview Kerberos 5 API Overview86*87* All functions are documented in manual pages. This section tries88* to give an overview of the major components used in Kerberos89* library, and point to where to look for a specific function.90*91* @subsection intro_krb5_context Kerberos context92*93* A kerberos context (krb5_context) holds all per thread state. All94* global variables that are context specific are stored in this95* structure, including default encryption types, credential cache96* (for example, a ticket file), and default realms.97*98* The internals of the structure should never be accessed directly,99* functions exist for extracting information.100*101* See the manual page for krb5_init_context() how to create a context102* and module @ref krb5 for more information about the functions.103*104* @subsection intro_krb5_auth_context Kerberos authentication context105*106* Kerberos authentication context (krb5_auth_context) holds all107* context related to an authenticated connection, in a similar way to108* the kerberos context that holds the context for the thread or109* process.110*111* The krb5_auth_context is used by various functions that are112* directly related to authentication between the113* server/client. Example of data that this structure contains are114* various flags, addresses of client and server, port numbers,115* keyblocks (and subkeys), sequence numbers, replay cache, and116* checksum types.117*118* @subsection intro_krb5_principal Kerberos principal119*120* The Kerberos principal is the structure that identifies a user or121* service in Kerberos. The structure that holds the principal is the122* krb5_principal. There are function to extract the realm and123* elements of the principal, but most applications have no reason to124* inspect the content of the structure.125*126* The are several ways to create a principal (with different degree of127* portability), and one way to free it.128*129* See also the page @ref krb5_principal_intro for more information and also130* module @ref krb5_principal.131*132* @subsection intro_krb5_ccache Credential cache133*134* A credential cache holds the tickets for a user. A given user can135* have several credential caches, one for each realm where the user136* have the initial tickets (the first krbtgt).137*138* The credential cache data can be stored internally in different139* way, each of them for different proposes. File credential (FILE)140* caches and processes based (KCM) caches are for permanent141* storage. While memory caches (MEMORY) are local caches to the local142* process.143*144* Caches are opened with krb5_cc_resolve() or created with145* krb5_cc_new_unique().146*147* If the cache needs to be opened again (using krb5_cc_resolve())148* krb5_cc_close() will close the handle, but not the remove the149* cache. krb5_cc_destroy() will zero out the cache, remove the cache150* so it can no longer be referenced.151*152* See also @ref krb5_ccache_intro and @ref krb5_ccache .153*154* @subsection intro_krb5_error_code Kerberos errors155*156* Kerberos errors are based on the com_err library. All error codes are157* 32-bit signed numbers, the first 24 bits define what subsystem the158* error originates from, and last 8 bits are 255 error codes within the159* library. Each error code have fixed string associated with it. For160* example, the error-code -1765328383 have the symbolic name161* KRB5KDC_ERR_NAME_EXP, and associated error string ``Client's entry in162* database has expired''.163*164* This is a great improvement compared to just getting one of the unix165* error-codes back. However, Heimdal have an extention to pass back166* customised errors messages. Instead of getting ``Key table entry not167* found'', the user might back ``failed to find168* host/host.example.com\@EXAMLE.COM(kvno 3) in keytab /etc/krb5.keytab169* (des-cbc-crc)''. This improves the chance that the user find the170* cause of the error so you should use the customised error message171* whenever it's available.172*173* See also module @ref krb5_error .174*175*176* @subsection intro_krb5_keytab Keytab management177*178* A keytab is a storage for locally stored keys. Heimdal includes keytab179* support for Kerberos 5 keytabs, Kerberos 4 srvtab, AFS-KeyFile's,180* and for storing keys in memory.181*182* Keytabs are used for servers and long-running services.183*184* See also @ref krb5_keytab_intro and @ref krb5_keytab .185*186* @subsection intro_krb5_crypto Kerberos crypto187*188* Heimdal includes a implementation of the Kerberos crypto framework,189* all crypto operations. To create a crypto context call krb5_crypto_init().190*191* See also module @ref krb5_crypto .192*193* @section kerberos5_client Walkthrough of a sample Kerberos 5 client194*195* This example contains parts of a sample TCP Kerberos 5 clients, if you196* want a real working client, please look in appl/test directory in197* the Heimdal distribution.198*199* All Kerberos error-codes that are returned from kerberos functions in200* this program are passed to krb5_err, that will print a201* descriptive text of the error code and exit. Graphical programs can202* convert error-code to a human readable error-string with the203* krb5_get_error_message() function.204*205* Note that you should not use any Kerberos function before206* krb5_init_context() have completed successfully. That is the207* reason err() is used when krb5_init_context() fails.208*209* First the client needs to call krb5_init_context to initialise210* the Kerberos 5 library. This is only needed once per thread211* in the program. If the function returns a non-zero value it indicates212* that either the Kerberos implementation is failing or it's disabled on213* this host.214*215* @code216* #include <krb5.h>217*218* int219* main(int argc, char **argv)220* {221* krb5_context context;222*223* if (krb5_init_context(&context))224* errx (1, "krb5_context");225* @endcode226*227* Now the client wants to connect to the host at the other end. The228* preferred way of doing this is using getaddrinfo (for229* operating system that have this function implemented), since getaddrinfo230* is neutral to the address type and can use any protocol that is available.231*232* @code233* struct addrinfo *ai, *a;234* struct addrinfo hints;235* int error;236*237* memset (&hints, 0, sizeof(hints));238* hints.ai_socktype = SOCK_STREAM;239* hints.ai_protocol = IPPROTO_TCP;240*241* error = getaddrinfo (hostname, "pop3", &hints, &ai);242* if (error)243* errx (1, "%s: %s", hostname, gai_strerror(error));244*245* for (a = ai; a != NULL; a = a->ai_next) {246* int s;247*248* s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);249* if (s < 0)250* continue;251* if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {252* warn ("connect(%s)", hostname);253* close (s);254* continue;255* }256* freeaddrinfo (ai);257* ai = NULL;258* }259* if (ai) {260* freeaddrinfo (ai);261* errx ("failed to contact %s", hostname);262* }263* @endcode264*265* Before authenticating, an authentication context needs to be266* created. This context keeps all information for one (to be) authenticated267* connection (see krb5_auth_context).268*269* @code270* status = krb5_auth_con_init (context, &auth_context);271* if (status)272* krb5_err (context, 1, status, "krb5_auth_con_init");273* @endcode274*275* For setting the address in the authentication there is a help function276* krb5_auth_con_setaddrs_from_fd() that does everything that is needed277* when given a connected file descriptor to the socket.278*279* @code280* status = krb5_auth_con_setaddrs_from_fd (context,281* auth_context,282* &sock);283* if (status)284* krb5_err (context, 1, status,285* "krb5_auth_con_setaddrs_from_fd");286* @endcode287*288* The next step is to build a server principal for the service we want289* to connect to. (See also krb5_sname_to_principal().)290*291* @code292* status = krb5_sname_to_principal (context,293* hostname,294* service,295* KRB5_NT_SRV_HST,296* &server);297* if (status)298* krb5_err (context, 1, status, "krb5_sname_to_principal");299* @endcode300*301* The client principal is not passed to krb5_sendauth()302* function, this causes the krb5_sendauth() function to try to figure it303* out itself.304*305* The server program is using the function krb5_recvauth() to306* receive the Kerberos 5 authenticator.307*308* In this case, mutual authentication will be tried. That means that the server309* will authenticate to the client. Using mutual authentication310* is good since it enables the user to verify that they are talking to the311* right server (a server that knows the key).312*313* If you are using a non-blocking socket you will need to do all work of314* krb5_sendauth() yourself. Basically you need to send over the315* authenticator from krb5_mk_req() and, in case of mutual316* authentication, verifying the result from the server with317* krb5_rd_rep().318*319* @code320* status = krb5_sendauth (context,321* &auth_context,322* &sock,323* VERSION,324* NULL,325* server,326* AP_OPTS_MUTUAL_REQUIRED,327* NULL,328* NULL,329* NULL,330* NULL,331* NULL,332* NULL);333* if (status)334* krb5_err (context, 1, status, "krb5_sendauth");335* @endcode336*337* Once authentication has been performed, it is time to send some338* data. First we create a krb5_data structure, then we sign it with339* krb5_mk_safe() using the auth_context that contains the340* session-key that was exchanged in the341* krb5_sendauth()/krb5_recvauth() authentication342* sequence.343*344* @code345* data.data = "hej";346* data.length = 3;347*348* krb5_data_zero (&packet);349*350* status = krb5_mk_safe (context,351* auth_context,352* &data,353* &packet,354* NULL);355* if (status)356* krb5_err (context, 1, status, "krb5_mk_safe");357* @endcode358*359* And send it over the network.360*361* @code362* len = packet.length;363* net_len = htonl(len);364*365* if (krb5_net_write (context, &sock, &net_len, 4) != 4)366* err (1, "krb5_net_write");367* if (krb5_net_write (context, &sock, packet.data, len) != len)368* err (1, "krb5_net_write");369* @endcode370*371* To send encrypted (and signed) data krb5_mk_priv() should be372* used instead. krb5_mk_priv() works the same way as373* krb5_mk_safe(), with the exception that it encrypts the data374* in addition to signing it.375*376* @code377* data.data = "hemligt";378* data.length = 7;379*380* krb5_data_free (&packet);381*382* status = krb5_mk_priv (context,383* auth_context,384* &data,385* &packet,386* NULL);387* if (status)388* krb5_err (context, 1, status, "krb5_mk_priv");389* @endcode390*391* And send it over the network.392*393* @code394* len = packet.length;395* net_len = htonl(len);396*397* if (krb5_net_write (context, &sock, &net_len, 4) != 4)398* err (1, "krb5_net_write");399* if (krb5_net_write (context, &sock, packet.data, len) != len)400* err (1, "krb5_net_write");401*402* @endcode403*404* The server is using krb5_rd_safe() and405* krb5_rd_priv() to verify the signature and decrypt the packet.406*407* @section intro_krb5_verify_user Validating a password in an application408*409* See the manual page for krb5_verify_user().410*411* @section mit_differences API differences to MIT Kerberos412*413* This section is somewhat disorganised, but so far there is no overall414* structure to the differences, though some of the have their root in415* that Heimdal uses an ASN.1 compiler and MIT doesn't.416*417* @subsection mit_krb5_principal Principal and realms418*419* Heimdal stores the realm as a krb5_realm, that is a char *.420* MIT Kerberos uses a krb5_data to store a realm.421*422* In Heimdal krb5_principal doesn't contain the component423* name_type; it's instead stored in component424* name.name_type. To get and set the nametype in Heimdal, use425* krb5_principal_get_type() and426* krb5_principal_set_type().427*428* For more information about principal and realms, see429* krb5_principal.430*431* @subsection mit_krb5_error_code Error messages432*433* To get the error string, Heimdal uses434* krb5_get_error_message(). This is to return custom error messages435* (like ``Can't find host/datan.example.com\@CODE.COM in436* /etc/krb5.conf.'' instead of a ``Key table entry not found'' that437* error_message returns.438*439* Heimdal uses a threadsafe(r) version of the com_err interface; the440* global com_err table isn't initialised. Then441* error_message returns quite a boring error string (just442* the error code itself).443*444*445*/446447/**448*449*450* @page krb5_fileformats File formats451*452* @section fileformats File formats453*454* This section documents the diffrent file formats that are used in455* Heimdal and other Kerberos implementations.456*457* @subsection file_keytab keytab458*459* The keytab binary format is not a standard format. The format has460* evolved and may continue to. It is however understood by several461* Kerberos implementations including Heimdal, MIT, Sun's Java ktab and462* are created by the ktpass.exe utility from Windows. So it has463* established itself as the defacto format for storing Kerberos keys.464*465* The following C-like structure definitions illustrate the MIT keytab466* file format. All values are in network byte order. All text is ASCII.467*468* @code469* keytab {470* uint16_t file_format_version; # 0x502471* keytab_entry entries[*];472* };473*474* keytab_entry {475* int32_t size;476* uint16_t num_components; # subtract 1 if version 0x501477* counted_octet_string realm;478* counted_octet_string components[num_components];479* uint32_t name_type; # not present if version 0x501480* uint32_t timestamp;481* uint8_t vno8;482* keyblock key;483* uint32_t vno; #only present if >= 4 bytes left in entry484* uint32_t flags; #only present if >= 4 bytes left in entry485* };486*487* counted_octet_string {488* uint16_t length;489* uint8_t data[length];490* };491*492* keyblock {493* uint16_t type;494* counted_octet_string;495* };496* @endcode497*498* All numbers are stored in network byteorder (big endian) format.499*500* The keytab file format begins with the 16 bit file_format_version which501* at the time this document was authored is 0x502. The format of older502* keytabs is described at the end of this document.503*504* The file_format_version is immediately followed by an array of505* keytab_entry structures which are prefixed with a 32 bit size indicating506* the number of bytes that follow in the entry. Note that the size should be507* evaluated as signed. This is because a negative value indicates that the508* entry is in fact empty (e.g. it has been deleted) and that the negative509* value of that negative value (which is of course a positive value) is510* the offset to the next keytab_entry. Based on these size values alone511* the entire keytab file can be traversed.512*513* The size is followed by a 16 bit num_components field indicating the514* number of counted_octet_string components in the components array.515*516* The num_components field is followed by a counted_octet_string517* representing the realm of the principal.518*519* A counted_octet_string is simply an array of bytes prefixed with a 16520* bit length. For the realm and name components, the counted_octet_string521* bytes are ASCII encoded text with no zero terminator.522*523* Following the realm is the components array that represents the name of524* the principal. The text of these components may be joined with slashs525* to construct the typical SPN representation. For example, the service526* principal HTTP/www.foo.net\@FOO.NET would consist of name components527* "HTTP" followed by "www.foo.net".528*529* Following the components array is the 32 bit name_type (e.g. 1 is530* KRB5_NT_PRINCIPAL, 2 is KRB5_NT_SRV_INST, 5 is KRB5_NT_UID, etc). In531* practice the name_type is almost certainly 1 meaning KRB5_NT_PRINCIPAL.532*533* The 32 bit timestamp indicates the time the key was established for that534* principal. The value represents the number of seconds since Jan 1, 1970.535*536* The 8 bit vno8 field is the version number of the key. This value is537* overridden by the 32 bit vno field if it is present. The vno8 field is538* filled with the lower 8 bits of the 32 bit protocol kvno field.539*540* The keyblock structure consists of a 16 bit value indicating the541* encryption type and is a counted_octet_string containing the key. The542* encryption type is the same as the Kerberos standard (e.g. 3 is543* des-cbc-md5, 23 is arcfour-hmac-md5, etc).544*545* The last field of the keytab_entry structure is optional. If the size of546* the keytab_entry indicates that there are at least 4 bytes remaining,547* a 32 bit value representing the key version number is present. This548* value supersedes the 8 bit vno8 value preceeding the keyblock.549*550* Older keytabs with a file_format_version of 0x501 are different in551* three ways:552*553* - All integers are in host byte order [1].554* - The num_components field is 1 too large (i.e. after decoding, decrement by 1).555* - The 32 bit name_type field is not present.556*557* [1] The file_format_version field should really be treated as two558* separate 8 bit quantities representing the major and minor version559* number respectively.560*561* @subsection file_hdb_dump Heimdal database dump file562*563* Format of the Heimdal text dump file as of Heimdal 0.6.3:564*565* Each line in the dump file is one entry in the database.566*567* Each field of a line is separated by one or more spaces, with the568* exception of fields consisting of principals containing spaces, where569* space can be quoted with \ and \ is quoted by \.570*571* Fields and their types are:572*573* @code574* Quoted princial (quote character is \) [string]575* Keys [keys]576* Created by [event]577* Modified by [event optional]578* Valid start time [time optional]579* Valid end time [time optional]580* Password end valid time [time optional]581* Max lifetime of ticket [time optional]582* Max renew time of ticket [integer optional]583* Flags [hdb flags]584* Generation number [generation optional]585* Extensions [extentions optional]586* @endcode587*588* Fields following these silently are ignored.589*590* All optional fields will be skipped if they fail to parse (or comprise591* the optional field marker of "-", w/o quotes).592*593* Example:594*595* @code596* 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 -597* @endcode598*599* Encoding of types are as follows:600*601* - keys602*603* @code604* kvno:[masterkvno:keytype:keydata:salt]{zero or more separated by :}605* @endcode606*607* kvno is the key version number.608*609* keydata is hex-encoded610*611* masterkvno is the kvno of the database master key. If this field is612* empty, the kadmin load and merge operations will encrypt the key data613* with the master key if there is one. Otherwise the key data will be614* imported asis.615*616* salt is encoded as "-" (no/default salt) or617*618* @code619* salt-type /620* salt-type / "string"621* salt-type / hex-encoded-data622* @endcode623*624* keytype is the protocol enctype number; see enum ENCTYPE in625* include/krb5_asn1.h for values.626*627* Example:628* @code629* 27:1:16:e8b4c8fc7e60b9e641dcf4cff3f08a701d982a2f89ba373733d26ca59ba6c789666f6b8bfcf169412bb1e5dceb9b33cda29f3412:-:1:3:4498a933881178c744f4232172dcd774c64e81fa6d05ecdf643a7e390624a0ebf3c7407a:-:1:2:b01934b13eb795d76f3a80717d469639b4da0cfb644161340ef44fdeb375e54d684dbb85:-:1:1:ea8e16d8078bf60c781da90f508d4deccba70595258b9d31888d33987cd31af0c9cced2e:-630* @endcode631*632*633* @code634* kvno=27,{key: masterkvno=1,keytype=des3-cbc-sha1,keydata=..., default salt}...635* @endcode636*637* - time638*639* Format of the time is: YYYYmmddHHMMSS, corresponding to strftime640* format "%Y%m%d%k%M%S".641*642* Time is expressed in UTC.643*644* Time can be optional (using -), when the time 0 is used.645*646* Example:647*648* @code649* 20041221112428650* @endcode651*652* - event653*654* @code655* time:principal656* @endcode657*658* time is as given in format time659*660* principal is a string. Not quoting it may not work in earlier661* versions of Heimdal.662*663* Example:664* @code665* 20041221112428:bloggs\@CODE.COM666* @endcode667*668* - hdb flags669*670* Integer encoding of HDB flags, see HDBFlags in lib/hdb/hdb.asn1. Each671* bit in the integer is the same as the bit in the specification.672*673* - generation:674*675* @code676* time:usec:gen677* @endcode678*679*680* usec is a the microsecond, integer.681* gen is generation number, integer.682*683* The generation can be defaulted (using '-') or the empty string684*685* - extensions:686*687* @code688* first-hex-encoded-HDB-Extension[:second-...]689* @endcode690*691* HDB-extension is encoded the DER encoded HDB-Extension from692* lib/hdb/hdb.asn1. Consumers HDB extensions should be aware that693* unknown entires needs to be preserved even thought the ASN.1 data694* content might be unknown. There is a critical flag in the data to show695* to the KDC that the entry MUST be understod if the entry is to be696* used.697*698*699*/700701702