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