@@ -349,6 +349,68 @@ gss_OID_set mag_filter_unwanted_mechs(gss_OID_set src)
349349 return src ;
350350}
351351
352+ static uint32_t mag_context_loop (uint32_t * min ,
353+ request_rec * req ,
354+ gss_cred_id_t init_cred ,
355+ gss_cred_id_t accept_cred ,
356+ gss_OID mech_type ,
357+ uint32_t req_lifetime ,
358+ gss_name_t * client ,
359+ uint32_t * lifetime ,
360+ gss_cred_id_t * delegated_cred )
361+ {
362+ gss_ctx_id_t init_ctx = GSS_C_NO_CONTEXT ;
363+ gss_ctx_id_t accept_ctx = GSS_C_NO_CONTEXT ;
364+ gss_buffer_desc init_token = GSS_C_EMPTY_BUFFER ;
365+ gss_buffer_desc accept_token = GSS_C_EMPTY_BUFFER ;
366+ gss_name_t accept_name = GSS_C_NO_NAME ;
367+ uint32_t maj , tmin ;
368+
369+ maj = gss_inquire_cred_by_mech (min , accept_cred , mech_type , & accept_name ,
370+ NULL , NULL , NULL );
371+ if (GSS_ERROR (maj )) {
372+ ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , req ,
373+ "%s" , mag_error (req , "gss_inquired_cred_by_mech() "
374+ "failed" , maj , * min ));
375+ return maj ;
376+ }
377+
378+ do {
379+ /* output and input are inverted here, this is intentional */
380+ maj = gss_init_sec_context (min , init_cred , & init_ctx ,
381+ accept_name , mech_type , GSS_C_DELEG_FLAG ,
382+ req_lifetime , GSS_C_NO_CHANNEL_BINDINGS ,
383+ & accept_token , NULL , & init_token , NULL ,
384+ NULL );
385+ if (GSS_ERROR (maj )) {
386+ ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , req , "%s" ,
387+ mag_error (req , "gss_init_sec_context()" , maj , * min ));
388+ goto done ;
389+ }
390+ gss_release_buffer (& tmin , & accept_token );
391+
392+ maj = gss_accept_sec_context (min , & accept_ctx , accept_cred ,
393+ & init_token , GSS_C_NO_CHANNEL_BINDINGS ,
394+ client , NULL , & accept_token , NULL ,
395+ lifetime , delegated_cred );
396+ if (GSS_ERROR (maj )) {
397+ ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , req , "%s" ,
398+ mag_error (req , "gss_accept_sec_context()" ,
399+ maj , * min ));
400+ goto done ;
401+ }
402+ gss_release_buffer (& tmin , & init_token );
403+ } while (maj == GSS_S_CONTINUE_NEEDED );
404+
405+ done :
406+ gss_release_name (& tmin , & accept_name );
407+ gss_release_buffer (& tmin , & init_token );
408+ gss_release_buffer (& tmin , & accept_token );
409+ gss_delete_sec_context (& tmin , & init_ctx , GSS_C_NO_BUFFER );
410+ gss_delete_sec_context (& tmin , & accept_ctx , GSS_C_NO_BUFFER );
411+ return maj ;
412+ }
413+
352414static bool mag_auth_basic (request_rec * req ,
353415 struct mag_config * cfg ,
354416 gss_buffer_desc ba_user ,
@@ -366,16 +428,10 @@ static bool mag_auth_basic(request_rec *req,
366428#endif
367429 gss_name_t user = GSS_C_NO_NAME ;
368430 gss_cred_id_t user_cred = GSS_C_NO_CREDENTIAL ;
369- gss_ctx_id_t user_ctx = GSS_C_NO_CONTEXT ;
370- gss_name_t server = GSS_C_NO_NAME ;
371431 gss_cred_id_t server_cred = GSS_C_NO_CREDENTIAL ;
372- gss_ctx_id_t server_ctx = GSS_C_NO_CONTEXT ;
373- gss_buffer_desc input = GSS_C_EMPTY_BUFFER ;
374- gss_buffer_desc output = GSS_C_EMPTY_BUFFER ;
375432 gss_OID_set allowed_mechs ;
376433 gss_OID_set filtered_mechs ;
377434 gss_OID_set actual_mechs = GSS_C_NO_OID_SET ;
378- uint32_t init_flags = 0 ;
379435 uint32_t maj , min ;
380436 int present = 0 ;
381437 bool ret = false;
@@ -487,71 +543,20 @@ static bool mag_auth_basic(request_rec *req,
487543 goto done ;
488544 }
489545
490- #ifdef HAVE_CRED_STORE
491- if (cfg -> deleg_ccache_dir ) {
492- /* delegate ourselves credentials so we store them as requested */
493- init_flags |= GSS_C_DELEG_FLAG ;
494- }
495- #endif
496-
497546 for (int i = 0 ; i < actual_mechs -> count ; i ++ ) {
498-
499- /* free these if looping */
500- gss_release_buffer (& min , & output );
501- gss_release_buffer (& min , & input );
502- gss_release_name (& min , & server );
503-
504- maj = gss_inquire_cred_by_mech (& min , server_cred ,
505- & actual_mechs -> elements [i ],
506- & server , NULL , NULL , NULL );
507- if (GSS_ERROR (maj )) {
508- ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , req ,
509- "%s" , mag_error (req , "gss_inquired_cred_by_mech() "
510- "failed" , maj , min ));
511- continue ;
512- }
513-
514- do {
515- /* output and input are inverted here, this is intentional */
516- maj = gss_init_sec_context (& min , user_cred , & user_ctx , server ,
517- & actual_mechs -> elements [i ], init_flags ,
518- 300 , GSS_C_NO_CHANNEL_BINDINGS , & output ,
519- NULL , & input , NULL , NULL );
520- if (GSS_ERROR (maj )) {
521- ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , req ,
522- "%s" , mag_error (req , "gss_init_sec_context() "
523- "failed" , maj , min ));
524- break ;
525- }
526- gss_release_buffer (& min , & output );
527- maj = gss_accept_sec_context (& min , & server_ctx , server_cred ,
528- & input , GSS_C_NO_CHANNEL_BINDINGS ,
529- client , mech_type , & output , NULL ,
530- vtime , delegated_cred );
531- if (GSS_ERROR (maj )) {
532- ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , req ,
533- "%s" , mag_error (req , "gss_accept_sec_context()"
534- " failed" , maj , min ));
535- break ;
536- }
537- gss_release_buffer (& min , & input );
538- } while (maj == GSS_S_CONTINUE_NEEDED );
539-
547+ maj = mag_context_loop (& min , req , user_cred , server_cred ,
548+ & actual_mechs -> elements [i ], 300 , client , vtime ,
549+ delegated_cred );
540550 if (maj == GSS_S_COMPLETE ) {
541551 ret = true;
542552 break ;
543553 }
544554 }
545555
546556done :
547- gss_release_buffer (& min , & output );
548- gss_release_buffer (& min , & input );
549- gss_release_name (& min , & server );
550- gss_delete_sec_context (& min , & server_ctx , GSS_C_NO_BUFFER );
551557 gss_release_cred (& min , & server_cred );
552558 gss_release_name (& min , & user );
553559 gss_release_cred (& min , & user_cred );
554- gss_delete_sec_context (& min , & user_ctx , GSS_C_NO_BUFFER );
555560 gss_release_oid_set (& min , & actual_mechs );
556561 gss_release_oid_set (& min , & filtered_mechs );
557562#ifdef HAVE_GSS_KRB5_CCACHE_NAME
@@ -638,13 +643,9 @@ static apr_status_t mag_s4u2self(request_rec *req)
638643 gss_name_t user = GSS_C_NO_NAME ;
639644 gss_name_t client = GSS_C_NO_NAME ;
640645 gss_cred_id_t server_cred = GSS_C_NO_CREDENTIAL ;
641- gss_name_t server_name = GSS_C_NO_NAME ;
642646 gss_cred_id_t delegated_cred = GSS_C_NO_CREDENTIAL ;
643- gss_ctx_id_t initiator_context = GSS_C_NO_CONTEXT ;
644- gss_buffer_desc init_token = GSS_C_EMPTY_BUFFER ;
645- gss_ctx_id_t acceptor_context = GSS_C_NO_CONTEXT ;
646- gss_buffer_desc accept_token = GSS_C_EMPTY_BUFFER ;
647647 struct mag_conn * mc = NULL ;
648+ uint32_t vtime ;
648649 uint32_t maj , min ;
649650
650651 req_cfg = mag_init_cfg (req );
@@ -677,15 +678,6 @@ static apr_status_t mag_s4u2self(request_rec *req)
677678 goto done ;
678679 }
679680
680- maj = gss_inquire_cred (& min , server_cred , & server_name , NULL , NULL , NULL );
681- if (GSS_ERROR (maj )) {
682- ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , req ,
683- "Failed to inquire server's creds: %s" ,
684- mag_error (req , "gss_inquired_cred()" ,
685- maj , min ));
686- goto done ;
687- }
688-
689681 user_name .value = req -> user ;
690682 user_name .length = strlen (user_name .value );
691683 maj = gss_import_name (& min , & user_name , GSS_C_NT_USER_NAME , & user );
@@ -713,36 +705,11 @@ static apr_status_t mag_s4u2self(request_rec *req)
713705 /* the following exchange is needed to decrypt the ticket and get named
714706 * attributes as well as check if the ticket is forwardable when
715707 * delegated credentials are requested */
716- do {
717- /* output and input are inverted here, this is intentional */
718-
719- /* now acquire credentials for impersonated user to self */
720- maj = gss_init_sec_context (& min , user_cred , & initiator_context ,
721- server_name , discard_const (gss_mech_krb5 ),
722- GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG ,
723- GSS_C_INDEFINITE ,
724- GSS_C_NO_CHANNEL_BINDINGS , & accept_token ,
725- NULL , & init_token , NULL , NULL );
726- if (GSS_ERROR (maj )) {
727- ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , req , "%s" ,
728- mag_error (req , "gss_init_sec_context()" , maj , min ));
729- goto done ;
730- }
731- gss_release_buffer (& min , & accept_token );
732-
733- /* accept context to be able to store delegated credentials */
734- maj = gss_accept_sec_context (& min , & acceptor_context , server_cred ,
735- & init_token , GSS_C_NO_CHANNEL_BINDINGS ,
736- & client , NULL , & accept_token ,
737- NULL , NULL , & delegated_cred );
738- if (GSS_ERROR (maj )) {
739- ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , req , "%s" ,
740- mag_error (req , "gss_accept_sec_context()" ,
741- maj , min ));
742- goto done ;
743- }
744- gss_release_buffer (& min , & init_token );
745- } while (maj == GSS_S_CONTINUE_NEEDED );
708+ maj = mag_context_loop (& min , req , user_cred , server_cred ,
709+ discard_const (gss_mech_krb5 ), GSS_C_INDEFINITE ,
710+ & client , & vtime , & delegated_cred );
711+ if (GSS_ERROR (maj ))
712+ goto done ;
746713
747714 if (cfg -> deleg_ccache_dir && delegated_cred == GSS_C_NO_CREDENTIAL ) {
748715 ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , req ,
@@ -754,20 +721,15 @@ static apr_status_t mag_s4u2self(request_rec *req)
754721 mc = mag_new_conn_ctx (req -> pool );
755722 mc -> auth_type = AUTH_TYPE_IMPERSONATE ;
756723
757- ret = mag_complete (req_cfg , mc , client , mech_type , GSS_C_INDEFINITE , delegated_cred );
724+ ret = mag_complete (req_cfg , mc , client , mech_type , vtime , delegated_cred );
758725 if (ret != OK ) ret = DECLINED ;
759726
760727done :
761728 gss_release_cred (& min , & user_cred );
762729 gss_release_name (& min , & user );
763730 gss_release_name (& min , & client );
764731 gss_release_cred (& min , & server_cred );
765- gss_release_name (& min , & server_name );
766732 gss_release_cred (& min , & delegated_cred );
767- gss_delete_sec_context (& min , & initiator_context , GSS_C_NO_BUFFER );
768- gss_release_buffer (& min , & init_token );
769- gss_delete_sec_context (& min , & acceptor_context , GSS_C_NO_BUFFER );
770- gss_release_buffer (& min , & accept_token );
771733 return ret ;
772734}
773735#endif
0 commit comments