Skip to content

Commit 7199593

Browse files
committed
Move context loops to a helper function
This work simplifies the calling code and reduces duplication. Signed-off-by: Simo Sorce <simo@redhat.com> Reviewed-by: Reviewed-by: Isaac Boukris <iboukris@gmail.com> Close #94
1 parent 56c4cb5 commit 7199593

File tree

1 file changed

+72
-110
lines changed

1 file changed

+72
-110
lines changed

src/mod_auth_gssapi.c

Lines changed: 72 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
352414
static 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

546556
done:
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

760727
done:
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

Comments
 (0)