idnits 2.17.1 draft-ietf-kitten-gss-loop-02.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 (December 8, 2014) is 3427 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 ---------------------------------------------------------------------------- -- Duplicate reference: RFC2743, mentioned in 'RFC2743E4151', was also mentioned in 'RFC2743'. Summary: 2 errors (**), 0 flaws (~~), 1 warning (==), 3 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 December 8, 2014 5 Expires: June 11, 2015 7 Structure of the GSS Negotiation Loop 8 draft-ietf-kitten-gss-loop-02 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 June 11, 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 o A way to frame and identify security context negotiation tokens in 111 the loop. 113 o Error tokens should generally also get special framing, as the 114 recipient may have no other way to distinguish unexpected error 115 context tokens from per-message tokens. 117 o Failing that, a way to indicate error status from one peer to the 118 other, possibly accompanied by a descriptive string. 120 o A protocol may use the negotiated GSS security context for per- 121 message operations; in such cases, the protocol will need a way to 122 frame and identify those per-message tokens and the nature of 123 their contents. For example, a protocol message may be 124 accompanied by the output of GSS_GetMIC() over that message; the 125 protocol must identify the location and size of that MIC token, 126 and indicate that it is a MIC token and what cleartext it 127 corresponds to. 129 o Applications are responsible for authorization of the 130 authenticated peer principal names which are supplied by the GSS- 131 API. Such names are mechanism-specific, and may come from a 132 different portion of a federated identity scheme. Application 133 protocols may need to supply additional information to support the 134 authorization of access to a given resource, such as the SSHv2 135 "username" parameter. 137 3. Loop Structure 139 The loop is begun by the appropriately named initiator, which calls 140 GSS_Init_sec_context() with an empty (zero-length) input_token and a 141 fixed set of input flags containing the desired attributes for the 142 security context. The initiator should not change any of the input 143 parameters to GSS_Init_sec_context() between calls to it during the 144 loop, with the exception of the input_token parameter, which will 145 contain a message from the acceptor after the initial call, and the 146 input_context_handle, which must be the result returned in the 147 output_context_handle of the previous call to GSS_Init_sec_context() 148 (GSS_C_NO_CONTEXT for the first call). (In the C bindings, there is 149 only a single read/modify context_handle argument, so the same 150 variable should be passed for each call in the loop.) RFC 2743 only 151 requires that the claimant_cred_handle argument remain constant over 152 all calls in the loop, but the other non-excepted arguments should 153 also remain fixed for reliable operation. 155 The following subsections will describe the various steps of the 156 loop, without special consideration to whether a call to 157 GSS_Init_sec_context() or GSS_Accept_sec_context() is the first such 158 call in the loop. 160 3.1. Anonymous Initiators 162 If the initiator is requesting anonymity by setting the anon_req_flag 163 input to GSS_Init_sec_context(), then on non-error returns from 164 GSS_Init_sec_context() (that is, when the major status is 165 GSS_S_COMPLETE or GSS_S_CONTINUE_NEEDED), the initiator must verify 166 that the output value of anon_state from GSS_Init_sec_context() is 167 true before sending the security context token to the acceptor. 168 Failing to perform this check could cause the initiator to lose 169 anonymity. 171 3.2. GSS_Init_sec_context 173 The initiator calls GSS_Init_sec_context(), using the 174 input_context_handle for the current proto-security-context and its 175 fixed set of input parameters, and the input_token received from the 176 acceptor (if not the first iteration of the loop). The presence of a 177 nonempty output_token and the value of the major status code are the 178 indicators for how to proceed: 180 If the major status code is GSS_S_COMPLETE and the output_token is 181 empty, then the context negotiation is fully complete and ready 182 for use by the initiator with no further actions. 184 If the major status code is GSS_S_COMPLETE and the output_token is 185 nonempty, then the initiator's portion of the security context 186 negotiation is complete but the acceptor's is not. The initiator 187 must send the output_token to the acceptor so that the acceptor 188 can establish its half of the security context. 190 If the major status code is GSS_S_CONTINUE_NEEDED and the 191 output_token is nonempty, the context negotiation is incomplete. 192 The initiator must send the output_token to the acceptor and await 193 another input_token from the acceptor. 195 If the major status code is GSS_S_CONTINUE_NEEDED and the 196 output_token is empty, the mechanism has produced an output which 197 is not compliant with [RFC2743]. However, there are some known 198 implementations of certain mechanisms which do produce empty 199 context negotiation tokens. For maximum interoperability, 200 applications should be prepared to accept such tokens, and should 201 transmit them to the acceptor if they are generated. 203 If the major status code is any other value, the context 204 negotiation has failed. If the output_token is nonempty, it is an 205 error token, and the initiator should send it to the acceptor. If 206 the output_token is empty, then the initiator should indicate the 207 failure to the acceptor if an appropriate application-protocol 208 channel to do so is available. 210 3.3. Sending from Initiator to Acceptor 212 The establishment of a GSS security context between initiator and 213 acceptor requires some communication channel by which to exchange the 214 context negotiation tokens. The nature of this channel is not 215 specified by the GSS specification -- it could be a dedicated TCP 216 channel, a UDP-based RPC protocol, or any other sort of channel. In 217 many cases, the channel will be multiplexed with non-GSS application 218 data; the application protocol must always provide some means by 219 which the GSS context tokens can be identified (e.g., length and 220 start location) and passed through to the mechanism accordingly. The 221 application protocol may also include a facility for indicating 222 errors from one party to the other, which can be used to convey 223 errors resulting from GSS-API calls, when appropriate (such as when 224 no error token was generated by the GSS-API implementation). Note 225 that GSS major and minor status codes are specified by language 226 bindings, not the abstract API; sending a major status code and 227 optionally the display form of the two error codes may be the best 228 that can be done in this case. 230 However, even the presence of a communication channel does not 231 necessarily indicate that it is appropriate for the initiator to 232 indicate such errors. For example, if the acceptor is a stateless or 233 near-stateless UDP server, there is probably no need for the 234 initiator to explicitly indicate its failure to the acceptor. 235 Conditions such as this can be treated in individual application 236 protocol specifications. 238 If a regular security context output_token is produced by the call to 239 GSS_Init_sec_context(), the initiator must transmit this token to the 240 acceptor over the application's communication channel. If the call 241 to GSS_Init_sec_context() returns an error token as output_token, it 242 is recommended that the initiator transmit this token to the acceptor 243 over the application's communication channel. 245 3.4. Acceptor Sanity Checking 247 The acceptor's half of the negotiation loop is triggered by the 248 receipt of a context token from the initiator. Before calling 249 GSS_Accept_sec_context(), the acceptor may find it useful to perform 250 some sanity checks on the state of the negotiation loop. 252 If the acceptor receives a context token but was not expecting such a 253 token (for example, if the acceptor's previous call to 254 GSS_Accept_sec_context() returned GSS_S_COMPLETE), this is probably 255 an error condition indicating that the initiator's state is invalid. 256 See Section 4.3 for some exceptional cases. It is likely appropriate 257 for the acceptor to report this error condition to the acceptor via 258 the application's communication channel. 260 If the acceptor is expecting a context token (e.g., if the previous 261 call to GSS_Accept_sec_context() returned GSS_S_CONTINUE_NEEDED), but 262 does not receive such a token within a reasonable amount of time 263 after transmitting the previous output_token to the initiator, the 264 acceptor should assume that the initiator's state is invalid (time 265 out) and fail the GSS negotiation. Again, it is likely appropriate 266 for the acceptor to report this error condition to the initiator via 267 the application's communication channel. 269 3.5. GSS_Accept_sec_context 271 The GSS acceptor responds to the actions of an initiator; as such, 272 there should always be a nonempty input_token to calls to 273 GSS_Accept_sec_context(). The input_context_handle parameter will 274 always be given as the output_context_handle from the previous call 275 to GSS_Accept_sec_context() in a given negotiation loop, or 276 GSS_C_NO_CONTEXT on the first call, but the acceptor_cred_handle and 277 chan_bindings arguments should remain fixed over the course of a 278 given GSS negotiation loop. [RFC2743] only requires that the 279 acceptor_cred_handle remain fixed throughout the loop, but the 280 chan_bindings argument should also remain fixed for reliable 281 operation. 283 The GSS acceptor calls GSS_Accept_sec_context(), using the 284 input_context_handle for the current proto-security-context and the 285 input_token received from the initiator. The presence of a nonempty 286 output_token and the value of the major status code are the 287 indicators for how to proceed: 289 If the major status code is GSS_S_COMPLETE and the output_token is 290 empty, then the context negotiation is fully complete and ready 291 for use by the acceptor with no further actions. 293 If the major status code is GSS_S_COMPLETE and the output_token is 294 nonempty, then the acceptor's portion of the security context 295 negotiation is complete but the initiator's is not. The acceptor 296 must send the output_token to the initiator so that the initiator 297 can establish its half of the security context. 299 If the major status code is GSS_S_CONTINUE_NEEDED and the 300 output_token is nonempty, the context negotiation is incomplete. 301 The acceptor must send the output_token to the initiator and await 302 another input_token from the initiator. 304 If the major status code is GSS_S_CONTINUE_NEEDED and the 305 output_token is empty, the mechanism has produced an output which 306 is not compliant with [RFC2743]. However, there are some known 307 implementations of certain mechanisms which do produce empty 308 context negotiation tokens. For maximum interoperability, 309 applications should be prepared to accept such tokens, and should 310 transmit them to the initiator if they are generated. 312 If the major status code is any other value, the context 313 negotiation has failed. If the output_token is nonempty, it is an 314 error token, and the acceptor should send it to the initiator. If 315 the output_token is empty, then the acceptor should indicate the 316 failure to the initiator if an appropriate application-protocol 317 channel to do so is available. 319 3.6. Sending from Acceptor to Initiator 321 The mechanism for sending the context token from acceptor to 322 initiator will depend on the nature of the communication channel 323 between the two parties. For a synchronous bidirectional channel, it 324 can be just another piece of data sent over the link, but for a 325 stateless UDP RPC acceptor, the token will probably end up being sent 326 as an RPC output parameter. Application protocol specifications will 327 need to specify the nature of this behavior. 329 If the application protocol has the initiator driving the 330 application's control flow, it is particularly helpful for the 331 acceptor to indicate a failure to the initiator, as mentioned in some 332 of the above cases conditional on "an appropriate application- 333 protocol channel to do so". 335 If a regular security context output_token is produced by the call to 336 GSS_Accept_sec_context(), the acceptor must transmit this token to 337 the initiator over the application's communication channel. If the 338 call to GSS_Accept_sec_context() returns an error token as 339 output_token, it is recommended that the acceptor transmit this token 340 to the initiator over the application's communication channel. 342 3.7. Initiator input validation 344 The initiator's half of the negotiation loop is triggered (after the 345 first call) by receipt of a context token from the acceptor. Before 346 calling GSS_Init_sec_context(), the initiator may find it useful to 347 perform some sanity checks on the state of the negotiation loop. 349 If the initiator receives a context token but was not expecting such 350 a token (for example, if the initiator's previous call to 351 GSS_Init_sec_context() returned GSS_S_COMPLETE), this is probably an 352 error condition indicating that the acceptor's state is invalid. See 353 Section 4.3 for some exceptional cases. It may be appropriate for 354 the initiator to report this error condition to the acceptor via the 355 application's communication channel. 357 If the initiator is expecting a context token (that is, the previous 358 call to GSS_Init_sec_context() returned GSS_S_CONTINUE_NEEDED), but 359 does not receive such a token within a reasonable amount of time 360 after transmitting the previous output_token to the acceptor, the 361 initiator should assume that the acceptor's state is invalid and fail 362 the GSS negotiation. Again, it may be appropriate for the initiator 363 to report this error condition to the acceptor via the application's 364 communication channel. 366 3.8. Continue the Loop 368 If the loop is in neither a success or failure condition, then the 369 loop must continue. Control flow returns to Section 3.2. 371 4. After Security Context Negotiation 373 Once a party has completed its half of the security context and 374 fulfilled its obligations to the other party, the context is 375 complete, but it is not necessarily ready and appropriate for use. 376 In particular, the security context flags may not be appropriate for 377 the given application's use. In some cases the context may be ready 378 for use before the negotiation is complete, see Section 4.2. 380 The initiator specifies as part of its fixed set of inputs to 381 GSS_Init_sec_context() values for all defined request flag booleans, 382 among them: deleg_req_flag, mutual_req_flag, replay_det_req_flag, 383 sequence_req_flag, conf_req_flag, and integ_req_flag. Upon 384 completion of the security context negotiation, the initiator must 385 verify that the values of the deleg_state, mutual_state, 386 replay_det_state, sequence_state, conf_avail, and integ_avail (and 387 any additional flags added by extensions) from the last call to 388 GSS_Init_sec_context() correspond to the requested flags. If a flag 389 was requested but is not available, and that feature is necessary for 390 the appplication protocol, the initiator must destroy the security 391 context and not use the security context for application traffic. 393 Application protocol specifications citing this document should 394 indicate which context flags are required for their application 395 protocol. 397 The acceptor receives as output the following booleans: deleg_state, 398 mutual_state, replay_det_state, sequence_state, anon_state, 399 trans_state, conf_avail, and integ_avail, and any additional flags 400 added by extensions to the GSS-API. The acceptor must verify that 401 any flags necessary for the application protocol are set. If a 402 necessary flag is not set, the acceptor must destroy the security 403 context and not use the security context for application traffic. 405 4.1. Authorization Checks 407 The acceptor receives as one of the outputs of 408 GSS_Accept_sec_context() the name of the initiator which has 409 authenticated during the security context negotiation. Applications 410 need to implement authorization checks on this received name 411 ('client_name' in the sample code) before providing access to 412 restricted resources. In particular, security context negotiation 413 can be successful when the client is anonymous or is from a different 414 identity realm than the acceptor, depending on the details of the 415 mechanism used by the GSS-API to establish the security context. 416 Acceptor applications can check which target name was used by the 417 initiator, but the details are out of scope for this document. See 418 [RFC2743] sections 2.2.6 and 1.1.5. Additional information can be 419 available in GSS-API Naming Extensions, [RFC6680]. 421 4.2. Using Partially Complete Security Contexts 423 For mechanism/flag combinations that require multiple token 424 exchanges, the GSS-API specification [RFC2743] provides a 425 prot_ready_state output value from GSS_Init_sec_context() and 426 GSS_Accept_sec_context(), which indicates when per-message operations 427 are available. However, many mechanism implementations do not 428 provide this functionality, and the analysis of the security 429 consequences of its use is rather complicated, so it is not expected 430 to be useful in most application protocols. 432 In particular, mutual authentication, replay protection, and other 433 services (if requested) are services which will be active when 434 GSS_S_COMPLETE is returned, but which are not necessarily active 435 before the security context is fully established. 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 initiator side, or for an initiator application to 446 transmit that token to the acceptor; such decisions are out of scope 447 for this document. Both peers should always be prepared to process 448 such tokens, and application protocols should provide means by which 449 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. [RFC2743E4151] Regardless of the major_status output 468 of 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 */ 578 return 1; 579 } 581 /* 582 * Helper to receive a token on the specified fd. 583 * 584 * If errors are encountered, this routine must not directly cause 585 * termination of the process, because compliant GSS applications 586 * must release resources allocated by the GSS library before 587 * exiting. 588 */ 589 static int 590 receive_token(int fd, gss_buffer_t token) 591 { 592 /* 593 * Supply token framing and transmission code here. 594 * 595 * In addition to checking for error returns from whichever 596 * syscall(s) are used to receive data, applications should have 597 * a loop to handle EINTR returns. 598 * 599 * This routine is assumed to allocate memory for the local copy 600 * of the received token, which must be freed with release_buffer(). 601 */ 602 return 1; 603 } 605 static void 606 do_initiator(int readfd, int writefd, int anon) 607 { 608 int initiator_established = 0, ret; 609 gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; 610 OM_uint32 major, minor, req_flags, ret_flags; 611 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; 612 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; 613 gss_buffer_desc name_buf = GSS_C_EMPTY_BUFFER; 614 gss_name_t target_name = GSS_C_NO_NAME; 616 /* Applications should set target_name to a real value. */ 617 name_buf.value = "@"; 618 name_buf.length = strlen(name_buf.value); 619 major = gss_import_name(&minor, &name_buf, 620 GSS_C_NT_HOSTBASED_SERVICE, &target_name); 621 if (GSS_ERROR(major)) { 622 warnx(1, "Could not import name\n"); 623 goto cleanup; 624 } 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); 673 if (major & GSS_S_CONTINUE_NEEDED) { 674 ret = receive_token(readfd, &input_token); 675 if (ret != 0) 676 goto cleanup; 677 } else if (major == GSS_S_COMPLETE) { 678 initiator_established = 1; 679 } else { 680 /* This situation is forbidden by RFC 2743. Bail out. */ 681 warnx("major not complete or continue but not error\n"); 682 goto cleanup; 683 } 684 } /* while (!initiator_established) */ 685 if ((ret_flags & req_flags) != req_flags) { 686 warnx("Negotiated context does not support requested flags\n"); 687 goto cleanup; 688 } 689 printf("Initiator's context negotiation successful\n"); 690 cleanup: 691 /* We are required to release storage for nonzero-length output 692 * tokens. gss_release_buffer() zeros the length, so we are 693 * will not attempt to release the same buffer twice. */ 694 if (output_token.length > 0) 695 (void)gss_release_buffer(&minor, &output_token); 696 /* Do not request a context deletion token; pass NULL. */ 697 (void)gss_delete_sec_context(&minor, &ctx, NULL); 698 (void)gss_release_name(&minor, &target_name); 699 } 701 /* 702 * Perform authorization checks on the initiator's GSS name object. 703 * 704 * Returns 0 on success (the initiator is authorized) and nonzero 705 * when the initiator is not authorized. 706 */ 707 static int 708 check_authz(gss_name_t client_name) 709 { 710 /* 711 * Supply authorization checking code here. 712 * 713 * Options include bitwise comparison of the exported name against 714 * a local database, and introspection against name attributes. 715 */ 716 return 0; 717 } 719 static void 720 do_acceptor(int readfd, int writefd) 721 { 722 int acceptor_established = 0, ret; 723 gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; 724 OM_uint32 major, minor, ret_flags; 725 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; 726 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; 727 gss_name_t client_name; 729 major = GSS_S_CONTINUE_NEEDED; 731 while (!acceptor_established) { 732 if (major & GSS_S_CONTINUE_NEEDED) { 733 ret = receive_token(readfd, &input_token); 734 if (ret != 0) 735 goto cleanup; 736 } else if (major == GSS_S_COMPLETE) { 737 acceptor_established = 1; 738 break; 739 } else { 740 /* This situation is forbidden by RFC 2743. Bail out. */ 741 warnx("major not complete or continue but not error\n"); 742 goto cleanup; 743 } 744 /* We can use the default behavior or do not need the returned 745 * information for the parameters acceptor_cred_handle, 746 * input_chan_bindings, mech_type, time_rec, and 747 * delegated_cred_handle and pass the values 748 * GSS_C_NO_CREDENTIAL, NULL, NULL, NULL, and NULL, 749 * respectively. In some cases the src_name will not be 750 * needed, but most likely it will be needed for some 751 * authorization or logging functionality. */ 752 major = gss_accept_sec_context(&minor, &ctx, 753 GSS_C_NO_CREDENTIAL, 754 &input_token, NULL, 755 &client_name, NULL, 756 &output_token, &ret_flags, NULL, 757 NULL); 758 /* This was allocated by receive_token() and is no longer 759 * needed. Free it now to avoid leaks if the loop continues. */ 760 release_buffer(&input_token); 761 /* Always send a token if we are expecting another input token 762 * (GSS_S_CONTINUE_NEEDED is set) or if it is nonempty. */ 763 if ((major & GSS_S_CONTINUE_NEEDED) || 764 output_token.length > 0) { 765 ret = send_token(writefd, &output_token); 766 if (ret != 0) 767 goto cleanup; 768 } 769 /* Check for errors after sending the token so that we will send 770 * error tokens. */ 771 if (GSS_ERROR(major)) { 772 warnx("gss_accept_sec_context() error major 0x%x\n", major); 773 goto cleanup; 774 } 775 /* Free the output token's storage; we don't need it anymore. 776 * gss_release_buffer() is safe to call on the output buffer 777 * from gss_accept_sec_context(), even if there is no storage 778 * associated with that buffer. */ 779 (void)gss_release_buffer(&minor, &output_token); 780 } /* while (!acceptor_established) */ 781 if (!(ret_flags & GSS_C_INTEG_FLAG)) { 782 warnx("Negotiated context does not support integrity\n"); 783 goto cleanup; 784 } 785 printf("Acceptor's context negotiation successful\n"); 786 ret = check_authz(client_name); 787 if (ret != 0) 788 printf("Client is not authorized; rejecting access\n"); 789 cleanup: 790 release_buffer(&input_token); 791 /* We are required to release storage for nonzero-length output 792 * tokens. gss_release_buffer() zeros the length, so we are 793 * will not attempt to release the same buffer twice. */ 794 if (output_token.length > 0) 795 (void)gss_release_buffer(&minor, &output_token); 796 /* Do not request a context deletion token, pass NULL. */ 797 (void)gss_delete_sec_context(&minor, &ctx, NULL); 798 (void)gss_release_name(&minor, &client_name); 799 } 801 int 802 main(void) 803 { 804 pid_t pid; 805 int fd1 = -1, fd2 = -1; 807 /* Create fds for reading/writing here. */ 808 pid = fork(); 809 if (pid == 0) 810 do_initiator(fd1, fd2, 0); 811 else if (pid > 0) 812 do_acceptor(fd2, fd1); 813 else 814 err(1, "fork() failed\n"); 815 exit(0); 816 } 817 6. Security Considerations 819 This document provides a (reasonably) concise description and example 820 for correct construction of the GSS-API security context negotiation 821 loop. Since everything relating to the construction and use of a GSS 822 security context is security-related, there are security-relevant 823 considerations throughout the document. It is useful to call out a 824 few things in this section, though. 826 The GSS-API uses a request-and-check model for features. An 827 application using the GSS-API requests certain features 828 (confidentiality protection for messages, or anonymity), but such a 829 request does not require the GSS implementation to provide that 830 feature. The application must check the returned flags to verify 831 whether a requested feature is present; if the feature was non- 832 optional for the application, the application must generate an error. 833 Phrased differently, the GSS-API will not generate an error if it is 834 unable to satisfy the features requested by the application. 836 In many cases it is convenient for GSS acceptors to accept security 837 contexts using multiple acceptor names (such as by using the default 838 credential set, as happens when GSS_C_NO_CREDENTIAL is passed to 839 GSS_Accept_sec_context()). This allows acceptors to use any 840 credentials to which it has access for accepting security contexts, 841 which may not be the desired behavior for a given application. (For 842 example, sshd may only wish to accept only using GSS_C_NT_HOSTBASED 843 credentials of the form host@, and not nfs@.) 844 Acceptor applications can check which target name was used by the 845 initiator, but the details are out of scope for this document. See 846 [RFC2743] sections 2.2.6 and 1.1.5. 848 The C sample code uses the macro GSS_ERROR() to assess the return 849 value of gss_init_sec_context() and gss_accept_sec_context(). This 850 is done to indicate where checks are needed in writing code for other 851 languages and what the nature of those checks might be. The C code 852 could be made simpler by omitting that macro. In applications 853 expecting to receive protected octet streams, this macro should not 854 be used on the result of per-message operations, as it omits checking 855 for supplementary status values such as GSS_S_DUPLICATE_TOKEN, 856 GSS_S_OLD_TOKEN, etc.. Use of the GSS_ERROR() macro on the results 857 of GSS-API per-message operations has resulted in security 858 vulnerabilities in existing software! 860 The security considerations from RFCs 2743 and 2744 remain applicable 861 to consumers of this document. 863 7. References 865 7.1. Normative References 867 [RFC2743] Linn, J., "Generic Security Service Application Program 868 Interface Version 2, Update 1", RFC 2743, January 2000. 870 [RFC2744] Wray, J., "Generic Security Service API Version 2 : 871 C-bindings", RFC 2744, January 2000. 873 7.2. Informational References 875 [RFC4462] Hutzelman, J., Salowey, J., Galbraith, J., and V. Welch, 876 "Generic Security Service Application Program Interface 877 (GSS-API) Authentication and Key Exchange for the Secure 878 Shell (SSH) Protocol", RFC 4462, May 2006. 880 [RFC4401] Williams, N., "A Pseudo-Random Function (PRF) API 881 Extension for the Generic Security Service Application 882 Program Interface (GSS-API)", RFC 4401, February 2006. 884 [RFC3645] Kwan, S., Garg, P., Gilroy, J., Esibov, L., Westhead, J., 885 and R. Hall, "Generic Security Service Algorithm for 886 Secret Key Transaction Authentication for DNS (GSS-TSIG)", 887 RFC 3645, October 2003. 889 [RFC5801] Josefsson, S. and N. Williams, "Using Generic Security 890 Service Application Program Interface (GSS-API) Mechanisms 891 in Simple Authentication and Security Layer (SASL): The 892 GS2 Mechanism Family", RFC 5801, July 2010. 894 [RFC4752] Melnikov, A., "The Kerberos V5 ("GSSAPI") Simple 895 Authentication and Security Layer (SASL) Mechanism", RFC 896 4752, November 2006. 898 [RFC2203] Eisler, M., Chiu, A., and L. Ling, "RPCSEC_GSS Protocol 899 Specification", RFC 2203, September 1997. 901 [RFC6680] Williams, N., Johansson, L., Hartman, S., and S. 902 Josefsson, "Generic Security Service Application 903 Programming Interface (GSS-API) Naming Extensions", RFC 904 6680, August 2012. 906 [RFC2743E4151] 907 Williams, N., "RFC 2743 Errata 4151", November 2014. 909 Appendix A. Acknowledgements 911 Thanks to Nico Williams and Jeff Hutzleman for prompting me to write 912 this document. 914 Author's Address 916 Benjamin Kaduk 917 MIT Kerberos Consortium 919 Email: kaduk@mit.edu