idnits 2.17.1 draft-ietf-kitten-gss-loop-01.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- ** The document is more than 15 pages and seems to lack a Table of Contents. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (November 19, 2014) is 3418 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Informational ---------------------------------------------------------------------------- No issues found here. Summary: 2 errors (**), 0 flaws (~~), 1 warning (==), 2 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group B. Kaduk 3 Internet-Draft MIT 4 Intended status: Informational November 19, 2014 5 Expires: May 23, 2015 7 Structure of the GSS Negotiation Loop 8 draft-ietf-kitten-gss-loop-01 10 Abstract 12 This document specifies the generic structure of the negotiation loop 13 to establish a GSS security context between initiator and acceptor. 14 The control flow of the loop is indicated for both parties, including 15 error conditions, and indications are given for where application- 16 specific behavior must be specified. 18 Status of This Memo 20 This Internet-Draft is submitted in full conformance with the 21 provisions of BCP 78 and BCP 79. 23 Internet-Drafts are working documents of the Internet Engineering 24 Task Force (IETF). Note that other groups may also distribute 25 working documents as Internet-Drafts. The list of current Internet- 26 Drafts is at http://datatracker.ietf.org/drafts/current/. 28 Internet-Drafts are draft documents valid for a maximum of six months 29 and may be updated, replaced, or obsoleted by other documents at any 30 time. It is inappropriate to use Internet-Drafts as reference 31 material or to cite them other than as "work in progress." 33 This Internet-Draft will expire on May 23, 2015. 35 Copyright Notice 37 Copyright (c) 2014 IETF Trust and the persons identified as the 38 document authors. All rights reserved. 40 This document is subject to BCP 78 and the IETF Trust's Legal 41 Provisions Relating to IETF Documents 42 (http://trustee.ietf.org/license-info) in effect on the date of 43 publication of this document. Please review these documents 44 carefully, as they describe your rights and restrictions with respect 45 to this document. Code Components extracted from this document must 46 include Simplified BSD License text as described in Section 4.e of 47 the Trust Legal Provisions and are provided without warranty as 48 described in the Simplified BSD License. 50 1. Introduction 52 The Generic Security Service Application Program Interface version 2 53 [RFC2743] provides a generic interface for security services, in the 54 form of an abstraction layer over the underlying security mechanisms 55 that an application may use. A GSS initiator and acceptor exchange 56 messages, called tokens, until a security context is established. 57 Such a security context allows for each party to authenticate the 58 other, the passing of confidential and/or integrity-protected 59 messages between the initiator and acceptor, the generation of 60 identical pseudo-random bit strings by both participants [RFC4401], 61 and more. 63 During context establishment, security context tokens are exchanged 64 synchronously, one at a time; the initiator sends the first context 65 token. The number of tokens which must be exchanged between 66 initiator and acceptor in order to establish the security context is 67 dependent on the underlying mechanism as well as the desired 68 properties of the security context, and is in general not known to 69 the application. Accordingly, the application's control flow must 70 include a loop within which GSS security context tokens are 71 exchanged, which terminates upon successful establishment of a 72 security context or an error condition. The GSS-API, together with 73 its security mechanisms, specifies the format and encoding of the 74 context tokens themselves, but the application protocol must specify 75 the necessary framing for the application to determine what octet 76 strings constitute GSS security context tokens and pass them into the 77 GSS-API implementation as appropriate. 79 The GSS-API C bindings [RFC2744] provide some example code for such a 80 negotiation loop, but this code does not specify the application's 81 behavior on unexpected or error conditions. As such, individual 82 application protocol specifications have had to specify the structure 83 of their GSS negotiation loops, including error handling, on a per- 84 protocol basis. [RFC4462], [RFC3645], [RFC5801], [RFC4752], 85 [RFC2203] This represents a substantial duplication of effort, and 86 the various specifications go into different levels of detail and 87 describe different possible error conditions. It is therefore 88 preferable to have the structure of the GSS negotiation loop, 89 including error conditions and token passing, described in a single 90 specification, which can then be referred to from other documents in 91 lieu of repeating the structure of the loop each time. This document 92 will perform that role. 94 The necessary requirements for correctly performing a GSS negotiation 95 loop are essentially all included in [RFC2743], but they are 96 scattered in many different places. This document brings all the 97 requirements together into one place for the convenience of 98 implementors, even though the normative requirements remain in 99 [RFC2743]. In a few places, this document notes additional behavior 100 which is useful for applications but is not mandated by [RFC2743]. 102 2. Application Protocol Requirements 104 Part of the purpose of this document is to guide the development of 105 new application protocols using the GSS-API, as well as the 106 development of new application software using such protocols. The 107 following list is features which are necessary or useful in such an 108 application protocol: 110 A way to frame and identify the initial context negotiation tokens 111 in the loop. 113 A way to frame and identify subsequent context-level tokens (e.g., 114 error tokens) after a GSS_S_COMPLETE return. 116 Failing that, a way to indicate error status from one peer to the 117 other, possibly accompanied by a descriptive string. 119 A protocol may use the negotiated GSS security context for per- 120 message operations; in such cases, the protocol will need a way to 121 frame and identify those per-message tokens and the nature of 122 their contents. For example, a protocol message may be 123 accompanied by the output of GSS_GetMIC() over that message; the 124 protocol must identify the location and size of that MIC token, 125 and indicate that it is a MIC token and what cleartext it 126 corresponds to. 128 The application (not the protocol) should provide for 129 authorization checks in the acceptor. The GSS-API authenticates 130 the initiator, but does not make any claim about whether the 131 initiator is authorized for any given operation. In particular, 132 the initiator may be from a different portion of a federated 133 identity scheme. 135 3. Loop Structure 137 The loop is begun by the appropriately named initiator, which calls 138 GSS_Init_sec_context() with an empty (zero-length) input_token and a 139 fixed set of input flags containing the desired attributes for the 140 security context. The initiator should not change any of the input 141 parameters to GSS_Init_sec_context() between calls to it during the 142 loop, with the exception of the input_token parameter, which will 143 contain a message from the acceptor after the initial call, and the 144 input_context_handle, which must be the result returned in the 145 output_context_handle of the previous call to GSS_Init_sec_context() 146 (GSS_C_NO_CONTEXT for the first call). (In the C bindings, there is 147 only a single read/modify context_handle argument, so the same 148 variable should be passed for each call in the loop.) RFC 2743 only 149 requires that the claimant_cred_handle argument remain constant over 150 all calls in the loop, but the other non-excepted arguments should 151 also remain fixed for reliable operation. 153 The following subsections will describe the various steps of the 154 loop, without special consideration to whether a call to 155 GSS_Init_sec_context() or GSS_Accept_sec_context() is the first such 156 call in the loop. 158 3.1. Anonymous Initiators 160 If the initiator is requesting anonymity by setting the anon_req_flag 161 input to GSS_Init_sec_context(), then on non-error returns from 162 GSS_Init_sec_context() (that is, when the major status is 163 GSS_S_COMPLETE or GSS_S_CONTINUE_NEEDED), the initiator must verify 164 that the output value of anon_state from GSS_Init_sec_context() is 165 true before sending the security context token to the acceptor. 166 Failing to perform this check could cause the initiator to lose 167 anonymity. 169 3.2. GSS_Init_sec_context 171 The initiator calls GSS_Init_sec_context(), using the 172 input_context_handle for the current proto-security-context and its 173 fixed set of input parameters, and the input_token received from the 174 acceptor (if not the first iteration of the loop). The presence of a 175 nonempty output_token and the value of the major status code are the 176 indicators for how to proceed: 178 If the major status code is GSS_S_COMPLETE and the output_token is 179 empty, then the context negotiation is fully complete and ready 180 for use by the initiator with no further actions. 182 If the major status code is GSS_S_COMPLETE and the output_token is 183 nonempty, then the initiator's portion of the security context 184 negotiation is complete but the acceptor's is not. The initiator 185 must send the output_token to the acceptor so that the acceptor 186 can establish its half of the security context. 188 If the major status code is GSS_S_CONTINUE_NEEDED and the 189 output_token is nonempty, the context negotiation is incomplete. 190 The initiator must send the output_token to the acceptor and await 191 another input_token from the acceptor. 193 If the major status code is GSS_S_CONTINUE_NEEDED and the 194 output_token is empty, the mechanism has produced an output which 195 is not compliant with [RFC2743]. However, there are some known 196 implementations of certain mechanisms which do produce empty 197 context negotiation tokens. For maximum interoperability, 198 applications should be prepared to accept such tokens, and should 199 transmit them to the acceptor if they are generated. 201 If the major status code is any other value, the context 202 negotiation has failed. If the output_token is nonempty, it is an 203 error token, and the initiator should send it to the acceptor. If 204 the output_token is empty, then the initiator should indicate the 205 failure to the acceptor if an appropriate application-protocol 206 channel to do so is available. 208 3.3. Sending from Initiator to Acceptor 210 The establishment of a GSS security context between initiator and 211 acceptor requires some communication channel by which to exchange the 212 context negotiation tokens. The nature of this channel is not 213 specified by the GSS specification -- it could be a dedicated TCP 214 channel, a UDP-based RPC protocol, or any other sort of channel. In 215 many cases, the channel will be multiplexed with non-GSS application 216 data; the application protocol must always provide some means by 217 which the GSS context tokens can be identified (e.g., length and 218 start location) and passed through to the mechanism accordingly. The 219 application protocol may also include a facility for indicating 220 errors from one party to the other, which can be used to convey 221 errors resulting from GSS-API calls, when appropriate (such as when 222 no error token was generated by the GSS-API implementation). Note 223 that GSS major and minor status codes are specified by language 224 bindings, not the abstract API; sending a major status code and 225 optionally the display form of the two error codes may be the best 226 that can be done in this case. 228 However, even the presence of a communication channel does not 229 necessarily indicate that it is appropriate for the initiator to 230 indicate such errors. For example, if the acceptor is a stateless or 231 near-stateless UDP server, there is probably no need for the 232 initiator to explicitly indicate its failure to the acceptor. 233 Conditions such as this can be treated in individual application 234 protocol specifications. 236 If a regular security context output_token is produced by the call to 237 GSS_Init_sec_context(), the initiator must transmit this token to the 238 acceptor over the application's communication channel. If the call 239 to GSS_Init_sec_context() returns an error token as output_token, it 240 is recommended that the intiator transmit this token to the acceptor 241 over the application's communication channel. 243 3.4. Acceptor Sanity Checking 245 The acceptor's half of the negotiation loop is triggered by the 246 receipt of a context token from the initiator. Before calling 247 GSS_Accept_sec_context(), the acceptor may find it useful to perform 248 some sanity checks on the state of the negotiation loop. 250 If the acceptor receives a context token but was not expecting such a 251 token (for example, if the acceptor's previous call to 252 GSS_Accept_sec_context() returned GSS_S_COMPLETE), this is probably 253 an error condition indicating that the initiator's state is invalid. 254 See Section 4.3 for some exceptional cases. It is likely appropriate 255 for the acceptor to report this error condition to the acceptor via 256 the application's communication channel. 258 If the acceptor is expecting a context token (e.g., if the previous 259 call to GSS_Accept_sec_context() returned GSS_S_CONTINUE_NEEDED), but 260 does not receive such a token within a reasonable amount of time 261 after transmitting the previous output_token to the initiator, the 262 acceptor should assume that the initiator's state is invalid (time 263 out) and fail the GSS negotiation. Again, it is likely appropriate 264 for the acceptor to report this error condition to the initiator via 265 the application's communication channel. 267 3.5. GSS_Accept_sec_context 269 The GSS acceptor responds to the actions of an initiator; as such, 270 there should always be a nonempty input_token to calls to 271 GSS_Accept_sec_context(). The input_context_handle parameter will 272 always be given as the output_context_handle from the previous call 273 to GSS_Accept_sec_context() in a given negotiation loop, or 274 GSS_C_NO_CONTEXT on the first call, but the acceptor_cred_handle and 275 chan_bindings arguments should remain fixed over the course of a 276 given GSS negotiation loop. [RFC2743] only requires that the 277 acceptor_cred_handle remain fixed throughout the loop, but the 278 chan_bindings argument should also remain fixed for reliable 279 operation. 281 The GSS acceptor calls GSS_Accept_sec_context(), using the 282 input_context_handle for the current proto-security-context and the 283 input_token received from the initiator. The presence of a nonempty 284 output_token and the value of the major status code are the 285 indicators for how to proceed: 287 If the major status code is GSS_S_COMPLETE and the output_token is 288 empty, then the context negotiation is fully complete and ready 289 for use by the acceptor with no further actions. 291 If the major status code is GSS_S_COMPLETE and the output_token is 292 nonempty, then the acceptor's portion of the security context 293 negotiation is complete but the initiator's is not. The acceptor 294 must send the output_token to the initiator so that the initiator 295 can establish its half of the security context. 297 If the major status code is GSS_S_CONTINUE_NEEDED and the 298 output_token is nonempty, the context negotiation is incomplete. 299 The acceptor must send the output_token to the initiator and await 300 another input_token from the initiator. 302 If the major status code is GSS_S_CONTINUE_NEEDED and the 303 output_token is empty, the mechanism has produced an output which 304 is not compliant with [RFC2743]. However, there are some known 305 implementations of certain mechanisms which do produce empty 306 context negotiation tokens. For maximum interoperability, 307 applications should be prepared to accept such tokens, and should 308 transmit them to the initiator if they are generated. 310 If the major status code is any other value, the context 311 negotiation has failed. If the output_token is nonempty, it is an 312 error token, and the acceptor should send it to the initiator. If 313 the output_token is empty, then the acceptor should indicate the 314 failure to the initiator if an appropriate application-protocol 315 channel to do so is available. 317 3.6. Sending from Acceptor to Initiator 319 The mechanism for sending the context token from acceptor to 320 initiator will depend on the nature of the communication channel 321 between the two parties. For a synchronous bidirectional channel, it 322 can be just another piece of data sent over the link, but for a 323 stateless UDP RPC acceptor, the token will probably end up being sent 324 as an RPC output parameter. Application protocol specifications will 325 need to specify the nature of this behavior. 327 If the application protocol has the initiator driving the 328 application's control flow, it is particularly helpful for the 329 acceptor to indicate a failure to the initiator, as mentioned in some 330 of the above cases conditional on "an appropriate application- 331 protocol channel to do so". 333 If a regular security context output_token is produced by the call to 334 GSS_Accept_sec_context(), the acceptor must transmit this token to 335 the initiator over the application's communication channel. If the 336 call to GSS_Accept_sec_context() returns an error token as 337 output_token, it is recommended that the acceptor transmit this token 338 to the initiator over the application's communication channel. 340 3.7. Initiator input validation 342 The initiator's half of the negotiation loop is triggered (after the 343 first call) by receipt of a context token from the acceptor. Before 344 calling GSS_Init_sec_context(), the initiator may find it useful to 345 perform some sanity checks on the state of the negotiation loop. 347 If the initiator receives a context token but was not expecting such 348 a token (for example, if the initiator's previous call to 349 GSS_Init_sec_context() returned GSS_S_COMPLETE), this is probably an 350 error condition indicating that the acceptor's state is invalid. See 351 Section 4.3 for some exceptional cases. It may be appropriate for 352 the initiator to report this error condition to the acceptor via the 353 application's communication channel. 355 If the initiator is expecting a context token (that is, the previous 356 call to GSS_Init_sec_context() returned GSS_S_CONTINUE_NEEDED), but 357 does not receive such a token within a reasonable amount of time 358 after transmitting the previous output_token to the acceptor, the 359 initiator should assume that the acceptor's state is invalid and fail 360 the GSS negotiation. Again, it may be appropriate for the initiator 361 to report this error condition to the acceptor via the application's 362 communication channel. 364 3.8. Continue the Loop 366 If the loop is in neither a success or failure condition, then the 367 loop must continue. Control flow returns to Section 3.2. 369 4. After Security Context Negotiation 371 Once a party has completed its half of the security context and 372 fulfilled its obligations to the other party, the context is 373 complete, but it is not necessarily ready and appropriate for use. 374 In particular, the security context flags may not be appropriate for 375 the given application's use. In some cases the context may be ready 376 for use before the negotiation is complete, see Section 4.2. 378 The initiator specifies as part of its fixed set of inputs to 379 GSS_Init_sec_context() values for all defined request flag booleans, 380 among them: deleg_req_flag, mutual_req_flag, replay_det_req_flag, 381 sequence_req_flag, conf_req_flag, and integ_req_flag. Upon 382 completion of the security context negotiation, the initiator must 383 verify that the values of the deleg_state, mutual_state, 384 replay_det_state, sequence_state, conf_avail, and integ_avail (and 385 any additional flags added by extensions) from the last call to 386 GSS_Init_sec_context() correspond to the requested flags. If a flag 387 was requested but is not available, and that feature is necessary for 388 the appplication protocol, the initiator must destroy the security 389 context and not use the security context for application traffic. 391 Application protocol specifications citing this document should 392 indicate which context flags are required for their application 393 protocol. 395 The acceptor receives as output the following booleans: deleg_state, 396 mutual_state, replay_det_state, sequence_state, anon_state, 397 trans_state, conf_avail, and integ_avail, and any additional flags 398 added by extensions to the GSS-API. The acceptor must verify that 399 any flags necessary for the application protocol are set. If a 400 necessary flag is not set, the acceptor must destroy the security 401 context and not use the security context for application traffic. 403 4.1. Authorization Checks 405 The acceptor receives as one of the outputs of 406 GSS_Accpet_sec_context() the name of the initiator which has 407 authenticated during the security context negotiation. Applications 408 need to implement authorization checks on this received name 409 ('client_name' in the sample code) before providing access to 410 restricted resources. In particular, security context negotiation 411 can be successful when the client is anonymous or is from a different 412 identity realm than the acceptor, depending on the details of the 413 mechanism used by the GSS-API to establish the security context. 414 Acceptor applications can check which target name was used by the 415 initiator, but the details are out of scope for this document. See 416 [RFC2743] sections 2.2.6 and 1.1.5. Additional information can be 417 available in GSS-API Naming Extensions, [RFC6680]. 419 4.2. Using Partially Complete Security Contexts 421 For mechanism/flag combinations that require multiple token 422 exchanges, the GSS-API specification [RFC2743] provides a 423 prot_ready_state output value from GSS_Init_sec_context() and 424 GSS_Accept_sec_context(), which indicates when per-message operations 425 are available. However, many mechanism implementations do not 426 provide this functionality, and the analysis of the security 427 consequences of its use is rather complicated, so it is not expected 428 to be useful in most application protocols. 430 In particular, mutual authentication (if requested) is not guaranteed 431 until GSS_S_COMPLETE is returned. That is, an attacker could cause 432 messages to be protected to the attacker instead of the actual 433 target, followed by a context establishment failure. Accordingly, 434 application protocols should not put sensitive information into 435 messages sent during security context establishment. 437 4.3. Additional Context Tokens 439 Under some conditions, a context token will be received by a party to 440 a security context negotiation after that party has completed the 441 negotiation (i.e., after GSS_Init_sec_context() or 442 GSS_Accept_sec_context() has returned GSS_S_COMPLETE). Such tokens 443 must be passed to GSS_Process_context_token() for processing. It may 444 not always be necessary for a mechanism implementation to generate an 445 error token on the intiator side, or for an initiator application to 446 transmit that token to the acceptor, but such decisions are out of 447 scope for this document. Both peers should always be prepared to 448 process such tokens, and application protocols should provide means 449 by which they can be transmitted. 451 Such tokens can be security context deletion tokens, emitted when the 452 remote party called GSS_Delete_sec_context() with a non-null 453 output_context_token parameter, or error tokens, emitted when the 454 remote party experiences an error processing the last token in a 455 security context negotiation exchange. Errors experienced when 456 processing tokens earlier in the negotiation would be transmitted as 457 normal security context tokens and processed by 458 GSS_Init_sec_context() or GSS_Accept_sec_context(), as appropriate. 459 With the GSS-API version 2, it is not recommended to use security 460 context deletion tokens, so error tokens are expected to be the most 461 common form of additional context token, for new application 462 protocols. 464 GSS_Process_context_token() may indicate an error in its major_status 465 field if an error is encountered locally during token processing, or 466 to indicate that an error was encountered on the peer and conveyed in 467 an error token. Regardless of the major_status output of 468 GSS_Process_context_token(), GSS_Inquire_context() should be used 469 after processing the extra token, to query the status of the security 470 context and whether it can supply the features necessary for the 471 application protocol. 473 At present, all tokens which should be handled by 474 GSS_Process_context_token() will lead to the security context being 475 effectively unusable. Future extensions to the GSS-API may allow for 476 applications to continue to function after a call to 477 GSS_Process_context_token(), and it is expected that the outputs of 478 GSS_Inquire_context() will indicate whether it is safe to do so. 479 However, since there are no such extensions at present (error tokens 480 and deletion tokens both result in the security context being 481 essentially unusable), there is no guidance to give to applications 482 regarding this possibility at this time. 484 Even if GSS_Process_context_token() processes an error or deletion 485 token which renders the context essentially unusable, the resources 486 associated with the context must eventually be freed with a call to 487 GSS_Delete_sec_context(), just as would be needed if 488 GSS_Init_sec_context() or GSS_Accept_sec_context() had returned an 489 error while processing an input context token and the 490 input_context_handle was not GSS_C_NO_CONTEXT. RFC 2743 has some 491 text which is slightly ambiguous in this regard, but the best 492 practice is to always call GSS_Delete_sec_context(). 494 5. Sample Code 496 This section gives sample code for the GSS negotiation loop, both for 497 a regular application and for an application where the initiator 498 wishes to remain anonymous. Since the code for the two cases is very 499 similar, the anonymous-specific additions are wrapped in a 500 conditional check; that check and the conditional code may be ignored 501 if anonymous processing is not needed. 503 Since the communication channel between the initiator and acceptor is 504 a matter for individual application protocols, it is inherently 505 unspecified at the GSS-API level, which can lead to examples that are 506 less satisfying than may be desired. For example, the sample code in 507 [RFC2744] uses an unspecified send_token_to_peer() routine. Fully 508 correct and general code to frame and transmit tokens requires a 509 substantial amount of error checking and would detract from the core 510 purpose of this document, so we only present the function signature 511 for one example of what such functions might be, and leave some 512 comments in the otherwise-empty function bodies. 514 This sample code is written in C, using the GSS-API C bindings 515 [RFC2744]. It uses the macro GSS_ERROR() to help unpack the various 516 sorts of information which can be stored in the major status field; 517 supplementary information does not necessarily indicate an error. 518 Applications written in other languages will need to exercise care 519 that checks against the major status value are written correctly. 521 This sample code should be compilable as a standalone program, linked 522 against a GSS-API library. In addition to supplying implementations 523 for the token transmission/receipt routines, in order for the program 524 to successfully run when linked against most GSS-API libraries, the 525 initiator will need to specify an explicit target name for the 526 acceptor, which must match the credentials available to the acceptor. 527 A skeleton for how this may be done is provided, using a dummy name. 529 This sample code assumes v2 of the GSS-API. Applications wishing to 530 remain compatible with v1 of the GSS-API may need to perform 531 additional checks in some locations. 533 5.1. GSS Application Sample Code 535 #include 536 #include 537 #include 538 #include 539 #include 540 #include 542 /* 543 * This helper is used only on buffers that we allocate ourselves (e.g., 544 * from receive_token()). Buffers allocated by GSS routines must use 545 * gss_release_buffer(). 546 */ 547 static void 548 release_buffer(gss_buffer_t buf) 549 { 550 free(buf->value); 551 buf->value = NULL; 552 buf->length = 0; 553 } 555 /* 556 * Helper to send a token on the specified fd. 557 * 558 * If errors are encountered, this routine must not directly cause 559 * termination of the process, because compliant GSS applications 560 * must release resources allocated by the GSS library before 561 * exiting. 562 */ 563 static int 564 send_token(int fd, gss_buffer_t token) 565 { 566 /* 567 * Supply token framing and transmission code here. 568 * 569 * It is advisable for the application protocol to specify the 570 * length of the token being transmitted, unless the underlying 571 * transit does so implicitly. 572 * 573 * In addition to checking for error returns from whichever 574 * syscall(s) are used to send data, applications should have 575 * a loop to handle EINTR returns. 576 */ 577 return 1; 578 } 580 /* 581 * Helper to receive a token on the specified fd. 582 * 583 * If errors are encountered, this routine must not directly cause 584 * termination of the process, because compliant GSS applications 585 * must release resources allocated by the GSS library before 586 * exiting. 587 */ 588 static int 589 receive_token(int fd, gss_buffer_t token) 590 { 591 /* 592 * Supply token framing and transmission code here. 593 * 594 * In addition to checking for error returns from whichever 595 * syscall(s) are used to receive data, applications should have 596 * a loop to handle EINTR returns. 597 * 598 * This routine is assumed to allocate memory for the local copy 599 * of the received token, which must be freed with release_buffer(). 600 */ 601 return 1; 602 } 604 static void 605 do_initiator(int readfd, int writefd, int anon) 606 { 607 int initiator_established = 0, ret; 608 gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; 609 OM_uint32 major, minor, req_flags, ret_flags; 610 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; 611 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; 612 gss_buffer_desc name_buf = GSS_C_EMPTY_BUFFER; 613 gss_name_t target_name = GSS_C_NO_NAME; 615 /* Applications should set target_name to a real value. */ 616 name_buf.value = "@"; 617 name_buf.length = strlen(name_buf.value); 618 major = gss_import_name(&minor, &name_buf, 619 GSS_C_NT_HOSTBASED_SERVICE, &target_name); 620 if (GSS_ERROR(major)) { 621 warnx(1, "Could not import name\n"); 622 goto cleanup; 623 } 625 /* Mutual authentication will require a token from acceptor to 626 * initiator, and thus a second call to gss_init_sec_context(). */ 627 req_flags = GSS_C_MUTUAL_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG; 628 if (anon) 629 req_flags |= GSS_C_ANON_FLAG; 631 while (!initiator_established) { 632 /* The initiator_cred_handle, mech_type, time_req, 633 * input_chan_bindings, actual_mech_type, and time_rec 634 * parameters are not needed in many cases. We pass 635 * GSS_C_NO_CREDENTIAL, GSS_C_NO_OID, 0, NULL, NULL, and NULL 636 * for them, respectively. */ 637 major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &ctx, 638 target_name, GSS_C_NO_OID, 639 req_flags, 0, NULL, &input_token, 640 NULL, &output_token, &ret_flags, 641 NULL); 642 /* This was allocated by receive_token() and is no longer 643 * needed. Free it now to avoid leaks if the loop continues. */ 644 release_buffer(&input_token); 645 if (anon) { 646 /* Initiators which wish to remain anonymous must check 647 * whether their request has been honored before sending 648 * each token. */ 649 if (!(ret_flags & GSS_C_ANON_FLAG)) { 650 warnx("Anonymous requested but not available\n"); 651 goto cleanup; 652 } 653 } 654 /* Always send a token if we are expecting another input token 655 * (GSS_S_CONTINUE_NEEDED is set) or if it is nonempty. */ 656 if ((major & GSS_S_CONTINUE_NEEDED) || 657 output_token.length > 0) { 658 ret = send_token(writefd, &output_token); 659 if (ret != 0) 660 goto cleanup; 661 } 662 /* Check for errors after sending the token so that we will send 663 * error tokens. */ 664 if (GSS_ERROR(major)) { 665 warnx("gss_init_sec_context() error major 0x%x\n", major); 666 goto cleanup; 667 } 668 /* Free the output token's storage; we don't need it anymore. 669 * gss_release_buffer() is safe to call on the output buffer 670 * from gss_int_sec_context(), even if there is no storage 671 * associated with that buffer. */ 672 (void)gss_release_buffer(&minor, &output_token); 674 if (major & GSS_S_CONTINUE_NEEDED) { 675 ret = receive_token(readfd, &input_token); 676 if (ret != 0) 677 goto cleanup; 678 } else if (major == GSS_S_COMPLETE) { 679 initiator_established = 1; 680 } else { 681 /* This situation is forbidden by RFC 2743. Bail out. */ 682 warnx("major not complete or continue but not error\n"); 683 goto cleanup; 684 } 685 } /* while(!initiator_established) */ 686 if ((ret_flags & req_flags) != req_flags) { 687 warnx("Negotiated context does not support requested flags\n"); 688 goto cleanup; 689 } 690 printf("Initiator's context negotiation successful\n"); 691 cleanup: 692 /* We are required to release storage for nonzero-length output 693 * tokens. gss_release_buffer() zeros the length, so we are 694 * will not attempt to release the same buffer twice. */ 695 if (output_token.length > 0) 696 (void)gss_release_buffer(&minor, &output_token); 697 /* Do not request a context deletion token; pass NULL. */ 698 (void)gss_delete_sec_context(&minor, &ctx, NULL); 699 (void)gss_release_name(&minor, &target_name); 700 } 702 /* 703 * Perform authorization checks on the initiator's GSS name object. 704 * 705 * Returns 0 on success (the initiator is authorized) and nonzero 706 * when the initiator is not authorized. 707 */ 708 static int 709 check_authz(gss_name_t *client_name) 710 { 711 /* 712 * Supply authorization checking code here. 713 * 714 * Options include bitwise comparison of the exported name against 715 * a local database, and introspection against name attributes. 716 */ 717 return 0; 719 } 721 static void 722 do_acceptor(int readfd, int writefd) 723 { 724 int acceptor_established = 0, ret; 725 gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; 726 OM_uint32 major, minor, ret_flags; 727 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; 728 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; 729 gss_name_t client_name; 731 major = GSS_S_CONTINUE_NEEDED; 733 while(!acceptor_established) { 734 if (major & GSS_S_CONTINUE_NEEDED) { 735 ret = receive_token(readfd, &input_token); 736 if (ret != 0) 737 goto cleanup; 738 } else if (major == GSS_S_COMPLETE) { 739 acceptor_established = 1; 740 break; 741 } else { 742 /* This situation is forbidden by RFC 2743. Bail out. */ 743 warnx("major not complete or continue but not error\n"); 744 goto cleanup; 745 } 746 /* We can use the default behavior or do not need the returned 747 * information for the parameters acceptor_cred_handle, 748 * input_chan_bindings, mech_type, time_rec, and 749 * delegated_cred_handle and pass the values 750 * GSS_C_NO_CREDENTIAL, NULL, NULL, NULL, and NULL, 751 * respectively. In some cases the src_name will not be 752 * needed, but most likely it will be needed for some 753 * authorization or logging functionality. */ 754 major = gss_accept_sec_context(&minor, &ctx, 755 GSS_C_NO_CREDENTIAL, 756 &input_token, NULL, 757 &client_name, NULL, 758 &output_token, &ret_flags, NULL, 759 NULL); 760 /* This was allocated by receive_token() and is no longer 761 * needed. Free it now to avoid leaks if the loop continues. */ 762 release_buffer(&input_token); 763 /* Always send a token if we are expecting another input token 764 * (GSS_S_CONTINUE_NEEDED is set) or if it is nonempty. */ 765 if ((major & GSS_S_CONTINUE_NEEDED) || 766 output_token.length > 0) { 767 ret = send_token(writefd, &output_token); 768 if (ret != 0) 769 goto cleanup; 770 } 771 /* Check for errors after sending the token so that we will send 772 * error tokens. */ 773 if (GSS_ERROR(major)) { 774 warnx("gss_accept_sec_context() error major 0x%x\n", major); 775 goto cleanup; 776 } 777 /* Free the output token's storage; we don't need it anymore. 778 * gss_release_buffer() is safe to call on the output buffer 779 * from gss_accept_sec_context(), even if there is no storage 780 * associated with that buffer. */ 781 (void)gss_release_buffer(&minor, &output_token); 782 } /* while(!acceptor_established) */ 783 if (!(ret_flags & GSS_C_INTEG_FLAG)) { 784 warnx("Negotiated context does not support integrity\n"); 785 goto cleanup; 786 } 787 printf("Acceptor's context negotiation successful\n"); 788 ret = check_authz(&client_name); 789 if (ret != 0) 790 printf("Client is not authorized; rejecting access\n"); 791 cleanup: 792 release_buffer(&input_token); 793 /* We are required to release storage for nonzero-length output 794 * tokens. gss_release_buffer() zeros the length, so we are 795 * will not attempt to release the same buffer twice. */ 796 if (output_token.length > 0) 797 (void)gss_release_buffer(&minor, &output_token); 798 /* Do not request a context deletion token, pass NULL. */ 799 (void)gss_delete_sec_context(&minor, &ctx, NULL); 800 (void)gss_release_name(&minor, &client_name); 801 } 803 int 804 main(void) 805 { 806 pid_t pid; 807 int fd1 = -1, fd2 = -1; 809 /* Create fds for reading/writing here. */ 810 pid = fork(); 811 if (pid == 0) 812 do_initiator(fd1, fd2, 0); 813 else if (pid > 0) 814 do_acceptor(fd2, fd1); 816 else 817 err(1, "fork() failed\n"); 818 exit(0); 819 } 821 6. Security Considerations 823 This document provides a (reasonably) concise description and example 824 for correct construction of the GSS-API security context negotiation 825 loop. Since everything relating to the construction and use of a GSS 826 security context is security-related, there are security-relevant 827 considerations throughout the document. It is useful to call out a 828 few things in this section, though. 830 The GSS-API uses a request-and-check model for features. An 831 application using the GSS-API requests that certain features 832 (confidentiality protection for messages, or anonymity), but such a 833 request does not require the GSS implementation to provide that 834 feature. The application must check the returned flags to verify 835 whether a requested feature is present; if the feature was non- 836 optional for the application, the application must generate an error. 837 Phrased differently, the GSS-API will not generate an error if it is 838 unable to satisfy the features requested by the application. 840 In many cases it is convenient for GSS acceptors to accept security 841 context using multiple acceptor names (such as by using the default 842 credential set, as happens when GSS_C_NO_CREDENTIAL is passed to 843 GSS_Accept_sec_context()). This allows acceptors to use any 844 credentials to which it has access for accepting security contexts, 845 which may not be the desired behavior for a given application. (For 846 example, sshd may only wish to accept only using GSS_C_NT_HOSTBASED 847 credentials of the form host@, and not nfs@.) 848 Acceptor applications can check which target name was used by the 849 initiator, but the details are out of scope for this document. See 850 [RFC2743] sections 2.2.6 and 1.1.5. 852 The C sample code uses the macro GSS_ERROR() to assess the return 853 value of gss_init_sec_context() and gss_accept_sec_context(). This 854 is done to indicate where checks are needed in writing code for other 855 languages and what the nature of those checks might be. The C code 856 could be made simpler by omitting that macro. Use of the GSS_ERROR() 857 macro on the results of GSS-API per-message operations has resulted 858 in security vulnerabilities in existing software! In applications 859 expecting to receive protected octet streams, this macro should not 860 be used on the result of per-message operations, as it omits checking 861 for supplementary status values such as GSS_S_DUPLICATE_TOKEN, 862 GSS_S_OLD_TOKEN, etc.. 864 7. References 866 7.1. Normative References 868 [RFC2743] Linn, J., "Generic Security Service Application Program 869 Interface Version 2, Update 1", RFC 2743, January 2000. 871 [RFC2744] Wray, J., "Generic Security Service API Version 2 : 872 C-bindings", RFC 2744, January 2000. 874 7.2. Informational References 876 [RFC4462] Hutzelman, J., Salowey, J., Galbraith, J., and V. Welch, 877 "Generic Security Service Application Program Interface 878 (GSS-API) Authentication and Key Exchange for the Secure 879 Shell (SSH) Protocol", RFC 4462, May 2006. 881 [RFC4401] Williams, N., "A Pseudo-Random Function (PRF) API 882 Extension for the Generic Security Service Application 883 Program Interface (GSS-API)", RFC 4401, February 2006. 885 [RFC3645] Kwan, S., Garg, P., Gilroy, J., Esibov, L., Westhead, J., 886 and R. Hall, "Generic Security Service Algorithm for 887 Secret Key Transaction Authentication for DNS (GSS-TSIG)", 888 RFC 3645, October 2003. 890 [RFC5801] Josefsson, S. and N. Williams, "Using Generic Security 891 Service Application Program Interface (GSS-API) Mechanisms 892 in Simple Authentication and Security Layer (SASL): The 893 GS2 Mechanism Family", RFC 5801, July 2010. 895 [RFC4752] Melnikov, A., "The Kerberos V5 ("GSSAPI") Simple 896 Authentication and Security Layer (SASL) Mechanism", RFC 897 4752, November 2006. 899 [RFC2203] Eisler, M., Chiu, A., and L. Ling, "RPCSEC_GSS Protocol 900 Specification", RFC 2203, September 1997. 902 [RFC6680] Williams, N., Johansson, L., Hartman, S., and S. 903 Josefsson, "Generic Security Service Application 904 Programming Interface (GSS-API) Naming Extensions", RFC 905 6680, August 2012. 907 Appendix A. Acknowledgements 909 Thanks to Nico Williams and Jeff Hutzleman for prompting me to write 910 this document. 912 Author's Address 914 Benjamin Kaduk 915 MIT Kerberos Consortium 917 Email: kaduk@mit.edu