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