Release 0.8.1
[heimdal.git] / doc / programming.texi
blob8d2570df28370db02063fcaf2e094b7765362fe5
1 @c $Id$
3 @node Programming with Kerberos, Migration, Windows 2000 compatability, Top
4 @chapter Programming with Kerberos
6 First you need to know how the Kerberos model works, go read the
7 introduction text (@pxref{What is Kerberos?}).
9 @menu
10 * Kerberos 5 API Overview::     
11 * Walkthrough of a sample Kerberos 5 client::  
12 * Validating a password in a server application::  
13 * API differences to MIT Kerberos::  
14 * File formats::
15 @end menu
17 @node Kerberos 5 API Overview, Walkthrough of a sample Kerberos 5 client, Programming with Kerberos, Programming with Kerberos
18 @section Kerberos 5 API Overview
20 All functions are documented in manual pages.  This section tries to
21 give an overview of the major components used in Kerberos library, and
22 point to where to look for a specific function.
24 @subsection Kerberos context
26 A kerberos context (@code{krb5_context}) holds all per thread state. All global variables that
27 are context specific are stored in this structure, including default
28 encryption types, credential cache (for example, a ticket file), and default realms.
30 See the manual pages for @manpage{krb5_context,3} and
31 @manpage{krb5_init_context,3}.
33 @subsection Kerberos authentication context
35 Kerberos authentication context (@code{krb5_auth_context}) holds all
36 context related to an authenticated connection, in a similar way to the
37 kerberos context that holds the context for the thread or process.
39 The @code{krb5_auth_context} is used by various functions that are
40 directly related to authentication between the server/client. Example of
41 data that this structure contains are various flags, addresses of client
42 and server, port numbers, keyblocks (and subkeys), sequence numbers,
43 replay cache, and checksum types.
45 See the manual page for @manpage{krb5_auth_context,3}.
47 @subsection Kerberos principal
49 The Kerberos principal is the structure that identifies a user or
50 service in Kerberos. The structure that holds the principal is the
51 @code{krb5_principal}. There are function to extract the realm and
52 elements of the principal, but most applications have no reason to
53 inspect the content of the structure.
55 The are several ways to create a principal (with different degree of
56 portability), and one way to free it.
58 See manual page for @manpage{krb5_principal,3} for more information
59 about the functions.
61 @subsection Credential cache
63 A credential cache holds the tickets for a user. A given user can have
64 several credential caches, one for each realm where the user have the
65 initial tickets (the first krbtgt).
67 The credential cache data can be stored internally in different way, each of them for
68 different proposes.  File credential (FILE) caches and processes based
69 (KCM) caches are for permanent storage. While memory caches (MEMORY)
70 are local caches to the local process.
72 Caches are opened with @manpage{krb5_cc_resolve,3} or created with
73 @manpage{krb5_cc_gen_unique,3}.
75 If the cache needs to be opened again (using
76 @manpage{krb5_cc_resolve,3}) @manpage{krb5_cc_close,3} will close the
77 handle, but not the remove the cache. @manpage{krb5_cc_destroy,3} will
78 zero out the cache, remove the cache so it can no longer be
79 referenced.
81 See also manual page for @manpage{krb5_ccache,3}
83 @subsection Kerberos errors
85 Kerberos errors are based on the com_err library.  All error codes are
86 32-bit signed numbers, the first 24 bits define what subsystem the
87 error originates from, and last 8 bits are 255 error codes within the
88 library.  Each error code have fixed string associated with it.  For
89 example, the error-code -1765328383 have the symbolic name
90 KRB5KDC_ERR_NAME_EXP, and associated error string ``Client's entry in
91 database has expired''.
93 This is a great improvement compared to just getting one of the unix
94 error-codes back.  However, Heimdal have an extention to pass back
95 customised errors messages.  Instead of getting ``Key table entry not
96 found'', the user might back ``failed to find
97 host/host.example.com@@EXAMLE.COM(kvno 3) in keytab /etc/krb5.keytab
98 (des-cbc-crc)''.  This improves the chance that the user find the
99 cause of the error so you should use the customised error message
100 whenever its available.
102 See also manual page for @manpage{krb5_get_error_string,3} and
103 @manpage{krb5_get_err_text,3}.
105 @subsection Keytab management
107 A keytab is a storage for locally stored keys. Heimdal includes keytab
108 support for Kerberos 5 keytabs, Kerberos 4 srvtab, AFS-KeyFile's,
109 and for storing keys in memory.
111 Keytabs are used for servers and long-running services.
113 See also manual page for @manpage{krb5_keytab,3}
115 @subsection Kerberos crypto
117 Heimdal includes a implementation of the Kerberos crypto framework,
118 all crypto operations.
120 See also manual page for @manpage{krb5_crypto_init,3},
121 @manpage{krb5_keyblock,3}, @manpage{krb5_create_checksum,3}, 
122 and @manpage{krb5_encrypt,3}.
124 @node Walkthrough of a sample Kerberos 5 client, Validating a password in a server application, Kerberos 5 API Overview, Programming with Kerberos
125 @section Walkthrough of a sample Kerberos 5 client
127 This example contains parts of a sample TCP Kerberos 5 clients, if you
128 want a real working client, please look in @file{appl/test} directory in
129 the Heimdal distribution.
131 All Kerberos error-codes that are returned from kerberos functions in
132 this program are passed to @code{krb5_err}, that will print a
133 descriptive text of the error code and exit. Graphical programs can
134 convert error-code to a human readable error-string with the
135 @manpage{krb5_get_err_text,3} function.
137 Note that you should not use any Kerberos function before
138 @code{krb5_init_context()} have completed successfully. That is the
139 reason @code{err()} is used when @code{krb5_init_context()} fails.
141 First the client needs to call @code{krb5_init_context} to initialise
142 the Kerberos 5 library. This is only needed once per thread
143 in the program. If the function returns a non-zero value it indicates
144 that either the Kerberos implementation is failing or its disabled on
145 this host.
147 @example
148 #include <krb5.h>
151 main(int argc, char **argv)
153         krb5_context context;
155         if (krb5_context(&context))
156                 errx (1, "krb5_context");
157 @end example
159 Now the client wants to connect to the host at the other end. The
160 preferred way of doing this is using @manpage{getaddrinfo,3} (for
161 operating system that have this function implemented), since getaddrinfo
162 is neutral to the address type and can use any protocol that is available.
164 @example
165         struct addrinfo *ai, *a;
166         struct addrinfo hints;
167         int error;
169         memset (&hints, 0, sizeof(hints));
170         hints.ai_socktype = SOCK_STREAM;
171         hints.ai_protocol = IPPROTO_TCP;
173         error = getaddrinfo (hostname, "pop3", &hints, &ai);
174         if (error)
175                 errx (1, "%s: %s", hostname, gai_strerror(error));
177         for (a = ai; a != NULL; a = a->ai_next) @{
178                 int s;
180                 s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
181                 if (s < 0)
182                         continue;
183                 if (connect (s, a->ai_addr, a->ai_addrlen) < 0) @{
184                         warn ("connect(%s)", hostname);
185                             close (s);
186                             continue;
187                 @}
188                 freeaddrinfo (ai);
189                 ai = NULL;
190         @}
191         if (ai) @{
192                     freeaddrinfo (ai);
193                     errx ("failed to contact %s", hostname);
194         @}
195 @end example
197 Before authenticating, an authentication context needs to be
198 created. This context keeps all information for one (to be) authenticated
199 connection (see @manpage{krb5_auth_context,3}).
201 @example
202         status = krb5_auth_con_init (context, &auth_context);
203         if (status)
204                 krb5_err (context, 1, status, "krb5_auth_con_init");
205 @end example
207 For setting the address in the authentication there is a help function
208 @code{krb5_auth_con_setaddrs_from_fd} that does everything that is needed
209 when given a connected file descriptor to the socket.
211 @example
212         status = krb5_auth_con_setaddrs_from_fd (context,
213                                                  auth_context,
214                                                  &sock);
215         if (status)
216                 krb5_err (context, 1, status, 
217                           "krb5_auth_con_setaddrs_from_fd");
218 @end example
220 The next step is to build a server principal for the service we want
221 to connect to. (See also @manpage{krb5_sname_to_principal,3}.)
223 @example
224         status = krb5_sname_to_principal (context,
225                                           hostname,
226                                           service,
227                                           KRB5_NT_SRV_HST,
228                                           &server);
229         if (status)
230                 krb5_err (context, 1, status, "krb5_sname_to_principal");
231 @end example
233 The client principal is not passed to @manpage{krb5_sendauth,3}
234 function, this causes the @code{krb5_sendauth} function to try to figure it
235 out itself.
237 The server program is using the function @manpage{krb5_recvauth,3} to
238 receive the Kerberos 5 authenticator.
240 In this case, mutual authentication will be tried. That means that the server
241 will authenticate to the client. Using mutual authentication
242 is good since it enables the user to verify that they are talking to the
243 right server (a server that knows the key).
245 If you are using a non-blocking socket you will need to do all work of
246 @code{krb5_sendauth} yourself. Basically you need to send over the
247 authenticator from @manpage{krb5_mk_req,3} and, in case of mutual
248 authentication, verifying the result from the server with
249 @manpage{krb5_rd_rep,3}.
251 @example
252         status = krb5_sendauth (context,
253                                 &auth_context,
254                                 &sock,
255                                 VERSION,
256                                 NULL,
257                                 server,
258                                 AP_OPTS_MUTUAL_REQUIRED,
259                                 NULL,
260                                 NULL,
261                                 NULL,
262                                 NULL,
263                                 NULL,
264                                 NULL);
265         if (status)
266                 krb5_err (context, 1, status, "krb5_sendauth");
267 @end example
269 Once authentication has been performed, it is time to send some
270 data. First we create a krb5_data structure, then we sign it with
271 @manpage{krb5_mk_safe,3} using the @code{auth_context} that contains the
272 session-key that was exchanged in the
273 @manpage{krb5_sendauth,3}/@manpage{krb5_recvauth,3} authentication
274 sequence.
276 @example
277         data.data   = "hej";
278         data.length = 3;
280         krb5_data_zero (&packet);
282         status = krb5_mk_safe (context,
283                                auth_context,
284                                &data,
285                                &packet,
286                                NULL);
287         if (status)
288                 krb5_err (context, 1, status, "krb5_mk_safe");
289 @end example
291 And send it over the network.
293 @example
294         len = packet.length;
295         net_len = htonl(len);
297         if (krb5_net_write (context, &sock, &net_len, 4) != 4)
298                 err (1, "krb5_net_write");
299         if (krb5_net_write (context, &sock, packet.data, len) != len)
300                 err (1, "krb5_net_write");
301 @end example
303 To send encrypted (and signed) data @manpage{krb5_mk_priv,3} should be
304 used instead. @manpage{krb5_mk_priv,3} works the same way as
305 @manpage{krb5_mk_safe,3}, with the exception that it encrypts the data
306 in addition to signing it.
308 @example
309         data.data   = "hemligt";
310         data.length = 7;
312         krb5_data_free (&packet);
314         status = krb5_mk_priv (context,
315                                auth_context,
316                                &data,
317                                &packet,
318                                NULL);
319         if (status)
320                 krb5_err (context, 1, status, "krb5_mk_priv");
321 @end example
323 And send it over the network.
325 @example
326         len = packet.length;
327         net_len = htonl(len);
329         if (krb5_net_write (context, &sock, &net_len, 4) != 4)
330                 err (1, "krb5_net_write");
331         if (krb5_net_write (context, &sock, packet.data, len) != len)
332                 err (1, "krb5_net_write");
334 @end example
336 The server is using @manpage{krb5_rd_safe,3} and
337 @manpage{krb5_rd_priv,3} to verify the signature and decrypt the packet.
339 @node Validating a password in a server application, API differences to MIT Kerberos, Walkthrough of a sample Kerberos 5 client, Programming with Kerberos
340 @section Validating a password in an application
342 See the manual page for @manpage{krb5_verify_user,3}.
344 @node API differences to MIT Kerberos, File formats, Validating a password in a server application, Programming with Kerberos
345 @section API differences to MIT Kerberos
347 This section is somewhat disorganised, but so far there is no overall
348 structure to the differences, though some of the have their root in
349 that Heimdal uses an ASN.1 compiler and MIT doesn't.
351 @subsection Principal and realms
353 Heimdal stores the realm as a @code{krb5_realm}, that is a @code{char *}.
354 MIT Kerberos uses a @code{krb5_data} to store a realm.
356 In Heimdal @code{krb5_principal} doesn't contain the component
357 @code{name_type}; it's instead stored in component
358 @code{name.name_type}. To get and set the nametype in Heimdal, use
359 @manpage{krb5_principal_get_type,3} and
360 @manpage{krb5_principal_set_type,3}.
362 For more information about principal and realms, see
363 @manpage{krb5_principal,3}.
365 @subsection Error messages
367 To get the error string, Heimdal uses
368 @manpage{krb5_get_error_string,3} or, if @code{NULL} is returned,
369 @manpage{krb5_get_err_text,3}. This is to return custom error messages
370 (like ``Can't find host/datan.example.com@@EXAMPLE.COM in
371 /etc/krb5.conf.'' instead of a ``Key table entry not found'' that
372 @manpage{error_message,3} returns.
374 Heimdal uses a threadsafe(r) version of the com_err interface; the
375 global @code{com_err} table isn't initialised.  Then
376 @manpage{error_message,3} returns quite a boring error string (just
377 the error code itself).
380 @c @node Why you should use GSS-API for new applications, Walkthrough of a sample GSS-API client, Validating a password in a server application, Programming with Kerberos
381 @c @section Why you should use GSS-API for new applications
382 @c 
383 @c SSPI, bah, bah, microsoft, bah, bah, almost GSS-API.
384 @c 
385 @c It would also be possible for other mechanisms then Kerberos, but that
386 @c doesn't exist any other GSS-API implementations today.
387 @c 
388 @c @node Walkthrough of a sample GSS-API client, , Why you should use GSS-API for new applications, Programming with Kerberos
389 @c @section Walkthrough of a sample GSS-API client
390 @c 
391 @c Write about how gssapi_clent.c works.
393 @node File formats,  , API differences to MIT Kerberos, Programming with Kerberos
394 @section File formats
396 This section documents the diffrent file formats that are used in
397 Heimdal and other Kerberos implementations.
399 @subsection keytab
401 The keytab binary format is not a standard format. The format has
402 evolved and may continue to. It is however understood by several
403 Kerberos implementations including Heimdal, MIT, Sun's Java ktab and
404 are created by the ktpass.exe utility from Windows. So it has
405 established itself as the defacto format for storing Kerberos keys.
407 The following C-like structure definitions illustrate the MIT keytab
408 file format. All values are in network byte order. All text is ASCII.
410 @example
411   keytab @{
412       uint16_t file_format_version;                    /* 0x502 */
413       keytab_entry entries[*];
414   @};
416   keytab_entry @{
417       int32_t size;
418       uint16_t num_components;   /* subtract 1 if version 0x501 */
419       counted_octet_string realm;
420       counted_octet_string components[num_components];
421       uint32_t name_type;       /* not present if version 0x501 */
422       uint32_t timestamp;
423       uint8_t vno8;
424       keyblock key;
425       uint32_t vno; /* only present if >= 4 bytes left in entry */
426   @};
428   counted_octet_string @{
429       uint16_t length;
430       uint8_t data[length];
431   @};
433   keyblock @{
434       uint16_t type;
435       counted_octet_string;
436   @};
437 @end example
439 All numbers are stored in network byteorder (big endian) format.
441 The keytab file format begins with the 16 bit file_format_version which
442 at the time this document was authored is 0x502. The format of older
443 keytabs is described at the end of this document.
445 The file_format_version is immediately followed by an array of
446 keytab_entry structures which are prefixed with a 32 bit size indicating
447 the number of bytes that follow in the entry. Note that the size should be
448 evaluated as signed. This is because a negative value indicates that the
449 entry is in fact empty (e.g. it has been deleted) and that the negative
450 value of that negative value (which is of course a positive value) is
451 the offset to the next keytab_entry. Based on these size values alone
452 the entire keytab file can be traversed.
454 The size is followed by a 16 bit num_components field indicating the
455 number of counted_octet_string components in the components array.
457 The num_components field is followed by a counted_octet_string
458 representing the realm of the principal.
460 A counted_octet_string is simply an array of bytes prefixed with a 16
461 bit length. For the realm and name components, the counted_octet_string
462 bytes are ASCII encoded text with no zero terminator.
464 Following the realm is the components array that represents the name of
465 the principal. The text of these components may be joined with slashs
466 to construct the typical SPN representation. For example, the service
467 principal HTTP/www.foo.net@@FOO.NET would consist of name components
468 "HTTP" followed by "www.foo.net".
470 Following the components array is the 32 bit name_type (e.g. 1 is
471 KRB5_NT_PRINCIPAL, 2 is KRB5_NT_SRV_INST, 5 is KRB5_NT_UID, etc). In
472 practice the name_type is almost certainly 1 meaning KRB5_NT_PRINCIPAL.
474 The 32 bit timestamp indicates the time the key was established for that
475 principal. The value represents the number of seconds since Jan 1, 1970.
477 The 8 bit vno8 field is the version number of the key. This value is
478 overridden by the 32 bit vno field if it is present. The vno8 field is
479 filled with the lower 8 bits of the 32 bit protocol kvno field.
481 The keyblock structure consists of a 16 bit value indicating the
482 encryption type and is a counted_octet_string containing the key.  The
483 encryption type is the same as the Kerberos standard (e.g. 3 is
484 des-cbc-md5, 23 is arcfour-hmac-md5, etc).
486 The last field of the keytab_entry structure is optional. If the size of
487 the keytab_entry indicates that there are at least 4 bytes remaining,
488 a 32 bit value representing the key version number is present. This
489 value supersedes the 8 bit vno8 value preceeding the keyblock.
491 Older keytabs with a file_format_version of 0x501 are different in
492 three ways:
494 @table @asis
495 @item All integers are in host byte order [1].
496 @item The num_components field is 1 too large (i.e. after decoding, decrement by 1).
497 @item The 32 bit name_type field is not present.
498 @end table
500 [1] The file_format_version field should really be treated as two
501 separate 8 bit quantities representing the major and minor version
502 number respectively.
504 @subsection Heimdal database dump file
506 Format of the Heimdal text dump file as of Heimdal 0.6.3:
508 Each line in the dump file is one entry in the database.
510 Each field of a line is separated by one or more spaces, with the
511 exception of fields consisting of principals containing spaces, where
512 space can be quoted with \ and \ is quoted by \.
514 Fields and their types are:
516 @example
517         Quoted princial (quote character is \) [string]
518         Keys [keys]
519         Created by [event]
520         Modified by [event optional]
521         Valid start time [time optional]
522         Valid end time [time optional]
523         Password end valid time [time optional]
524         Max lifetime of ticket [time optional]
525         Max renew time of ticket [integer optional]
526         Flags [hdb flags]
527         Generation number [generation optional]
528         Extensions [extentions optional]
529 @end example
531 Fields following these silently are ignored.
533 All optional fields will be skipped if they fail to parse (or comprise
534 the optional field marker of "-", w/o quotes).
536 Example:
538 @example
539 fred@@EXAMPLE.COM 27:1:16:e8b4c8fc7e60b9e641dcf4cff3f08a701d982a2f89ba373733d26ca59ba6c789666f6b8bfcf169412bb1e5dceb9b33cda29f3412:-:1:3:4498a933881178c744f4232172dcd774c64e81fa6d05ecdf643a7e390624a0ebf3c7407a:-:1:2:b01934b13eb795d76f3a80717d469639b4da0cfb644161340ef44fdeb375e54d684dbb85:-:1:1:ea8e16d8078bf60c781da90f508d4deccba70595258b9d31888d33987cd31af0c9cced2e:- 20020415130120:admin@@EXAMPLE.COM 20041221112428:fred@@EXAMPLE.COM - - - 86400 604800 126 20020415130120:793707:28 -
540 @end example
542 Encoding of types are as follows:
544 @table @asis
545 @item keys
547 @example
548 kvno:[masterkvno:keytype:keydata:salt]@{zero or more separated by :@}
549 @end example
551 kvno is the key version number.
553 keydata is hex-encoded
555 masterkvno is the kvno of the database master key.  If this field is
556 empty, the kadmin load and merge operations will encrypt the key data
557 with the master key if there is one.  Otherwise the key data will be
558 imported asis.
560 salt is encoded as "-" (no/default salt) or
562 @example
563 salt-type /
564 salt-type / "string"
565 salt-type / hex-encoded-data
566 @end example
568 keytype is the protocol enctype number; see enum ENCTYPE in
569 include/krb5_asn1.h for values.
571 Example:
572 @example
573 27:1:16:e8b4c8fc7e60b9e641dcf4cff3f08a701d982a2f89ba373733d26ca59ba6c789666f6b8bfcf169412bb1e5dceb9b33cda29f3412:-:1:3:4498a933881178c744f4232172dcd774c64e81fa6d05ecdf643a7e390624a0ebf3c7407a:-:1:2:b01934b13eb795d76f3a80717d469639b4da0cfb644161340ef44fdeb375e54d684dbb85:-:1:1:ea8e16d8078bf60c781da90f508d4deccba70595258b9d31888d33987cd31af0c9cced2e:-
574 @end example
577 @example
578 kvno=27,@{key: masterkvno=1,keytype=des3-cbc-sha1,keydata=..., default salt@}...
579 @end example
581 @item time
582         
583 Format of the time is: YYYYmmddHHMMSS, corresponding to strftime
584 format "%Y%m%d%k%M%S".
586 Time is expressed in UTC.
588 Time can be optional (using -), when the time 0 is used.
590 Example:
592 @example
593 20041221112428
594 @end example
596 @item event
598 @example
599         time:principal
600 @end example
602 time is as given in format time
604 principal is a string.  Not quoting it may not work in earlier
605 versions of Heimdal.
607 Example:
608 @example
609 20041221112428:bloggs@@EXAMPLE.COM
610 @end example
612 @item hdb flags
614 Integer encoding of HDB flags, see HDBFlags in lib/hdb/hdb.asn1. Each
615 bit in the integer is the same as the bit in the specification.
617 @item generation:
619 @example
620 time:usec:gen
621 @end example
624 usec is a the microsecond, integer.
625 gen is generation number, integer.
627 The generation can be defaulted (using '-') or the empty string
629 @item extensions:
631 @example
632 first-hex-encoded-HDB-Extension[:second-...]
633 @end example
635 HDB-extension is encoded the DER encoded HDB-Extension from
636 lib/hdb/hdb.asn1. Consumers HDB extensions should be aware that
637 unknown entires needs to be preserved even thought the ASN.1 data
638 content might be unknown. There is a critical flag in the data to show
639 to the KDC that the entry MUST be understod if the entry is to be
640 used.
642 @end table