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