Skip to content

Commit 56c4cb5

Browse files
committed
Postpone adding spnego mech to mech list
Add the SPNEGO mech oid only if we are performing negotiate auth. This cacthes earlier, with a hard failure, the case where a mechanism defined on the command line is not available, by checking if there are any desired mechs. Signed-off-by: Simo Sorce <[email protected]> Reviewed-by: Isaac Boukris <[email protected]> Close #93
1 parent d1710af commit 56c4cb5

File tree

1 file changed

+65
-23
lines changed

1 file changed

+65
-23
lines changed

src/mod_auth_gssapi.c

Lines changed: 65 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,49 @@ static apr_status_t mag_s4u2self(request_rec *req)
772772
}
773773
#endif
774774

775+
static apr_status_t mag_oid_set_destroy(void *ptr)
776+
{
777+
uint32_t min;
778+
gss_OID_set set = (gss_OID_set)ptr;
779+
(void)gss_release_oid_set(&min, &set);
780+
return APR_SUCCESS;
781+
}
782+
783+
static gss_OID_set mag_get_negotiate_mechs(apr_pool_t *p, gss_OID_set desired)
784+
{
785+
gss_OID spnego_oid = discard_const(&gss_mech_spnego);
786+
uint32_t maj, min;
787+
int present = 0;
788+
789+
maj = gss_test_oid_set_member(&min, spnego_oid, desired, &present);
790+
if (maj != GSS_S_COMPLETE) {
791+
return GSS_C_NO_OID_SET;
792+
}
793+
if (present) {
794+
return desired;
795+
} else {
796+
gss_OID_set set;
797+
maj = gss_create_empty_oid_set(&min, &set);
798+
if (maj != GSS_S_COMPLETE) {
799+
return GSS_C_NO_OID_SET;
800+
}
801+
apr_pool_cleanup_register(p, (void *)set,
802+
mag_oid_set_destroy,
803+
apr_pool_cleanup_null);
804+
maj = gss_add_oid_set_member(&min, spnego_oid, &set);
805+
if (maj != GSS_S_COMPLETE) {
806+
return GSS_C_NO_OID_SET;
807+
}
808+
for (int i = 0; i < desired->count; i++) {
809+
maj = gss_add_oid_set_member(&min, &desired->elements[i], &set);
810+
if (maj != GSS_S_COMPLETE) {
811+
return GSS_C_NO_OID_SET;
812+
}
813+
}
814+
return set;
815+
}
816+
}
817+
775818
static int mag_auth(request_rec *req)
776819
{
777820
const char *type;
@@ -810,7 +853,13 @@ static int mag_auth(request_rec *req)
810853

811854
cfg = req_cfg->cfg;
812855

813-
desired_mechs = req_cfg->desired_mechs;
856+
if ((req_cfg->desired_mechs == GSS_C_NO_OID_SET) ||
857+
(req_cfg->desired_mechs->count == 0)) {
858+
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req,
859+
"List of desired mechs is missing or empty, "
860+
"can't proceed!");
861+
return HTTP_UNAUTHORIZED;
862+
}
814863

815864
/* implicit auth for subrequests if main auth already happened */
816865
if (!ap_is_initial_req(req) && req->main != NULL) {
@@ -906,6 +955,13 @@ static int mag_auth(request_rec *req)
906955
if (!parse_auth_header(req->pool, &auth_header, &input)) {
907956
goto done;
908957
}
958+
desired_mechs = mag_get_negotiate_mechs(req->pool,
959+
req_cfg->desired_mechs);
960+
if (desired_mechs == GSS_C_NO_OID_SET) {
961+
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req,
962+
"Failed to get negotiate_mechs");
963+
goto done;
964+
}
909965
break;
910966
case AUTH_TYPE_BASIC:
911967
if (!cfg->use_basic_auth) {
@@ -951,6 +1007,11 @@ static int mag_auth(request_rec *req)
9511007
}
9521008

9531009
desired_mechs = discard_const(gss_mech_set_ntlmssp);
1010+
if (desired_mechs == GSS_C_NO_OID_SET) {
1011+
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req,
1012+
"No support for ntlmssp mech");
1013+
goto done;
1014+
}
9541015
break;
9551016

9561017
default:
@@ -1321,16 +1382,8 @@ static const char *mag_use_basic_auth(cmd_parms *parms, void *mconfig, int on)
13211382
}
13221383
#endif
13231384

1324-
static apr_status_t mag_oid_set_destroy(void *ptr)
1325-
{
1326-
uint32_t min;
1327-
gss_OID_set set = (gss_OID_set)ptr;
1328-
(void)gss_release_oid_set(&min, &set);
1329-
return APR_SUCCESS;
1330-
}
1331-
13321385
static bool mag_list_of_mechs(cmd_parms *parms, gss_OID_set *oidset,
1333-
bool add_spnego, const char *w)
1386+
const char *w)
13341387
{
13351388
gss_buffer_desc buf = { 0 };
13361389
uint32_t maj, min;
@@ -1346,17 +1399,6 @@ static bool mag_list_of_mechs(cmd_parms *parms, gss_OID_set *oidset,
13461399
*oidset = GSS_C_NO_OID_SET;
13471400
return false;
13481401
}
1349-
if (add_spnego) {
1350-
oid = discard_const(&gss_mech_spnego);
1351-
maj = gss_add_oid_set_member(&min, oid, &set);
1352-
if (maj != GSS_S_COMPLETE) {
1353-
ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
1354-
"gss_add_oid_set_member() failed.");
1355-
(void)gss_release_oid_set(&min, &set);
1356-
*oidset = GSS_C_NO_OID_SET;
1357-
return false;
1358-
}
1359-
}
13601402
/* register in the pool so it can be released once the server
13611403
* winds down */
13621404
apr_pool_cleanup_register(parms->pool, (void *)set,
@@ -1401,7 +1443,7 @@ static const char *mag_allow_mech(cmd_parms *parms, void *mconfig,
14011443
{
14021444
struct mag_config *cfg = (struct mag_config *)mconfig;
14031445

1404-
if (!mag_list_of_mechs(parms, &cfg->allowed_mechs, true, w))
1446+
if (!mag_list_of_mechs(parms, &cfg->allowed_mechs, w))
14051447
return "Failed to apply GssapiAllowedMech directive";
14061448

14071449
return NULL;
@@ -1483,7 +1525,7 @@ static const char *mag_basic_auth_mechs(cmd_parms *parms, void *mconfig,
14831525
{
14841526
struct mag_config *cfg = (struct mag_config *)mconfig;
14851527

1486-
if (!mag_list_of_mechs(parms, &cfg->basic_mechs, false, w))
1528+
if (!mag_list_of_mechs(parms, &cfg->basic_mechs, w))
14871529
return "Failed to apply GssapiBasicAuthMech directive";
14881530

14891531
return NULL;

0 commit comments

Comments
 (0)