Blame src/gp_rpc_indicate_mechs.c

Packit Service 9f2c4a
/* Copyright (C) 2011 the GSS-PROXY contributors, see COPYING for license */
Packit Service 9f2c4a
Packit Service 9f2c4a
#include "gp_rpc_process.h"
Packit Service 9f2c4a
#include "gp_debug.h"
Packit Service 9f2c4a
Packit Service 9f2c4a
int gp_indicate_mechs(struct gp_call_ctx *gpcall UNUSED,
Packit Service 9f2c4a
                      union gp_rpc_arg *arg,
Packit Service 9f2c4a
                      union gp_rpc_res *res)
Packit Service 9f2c4a
{
Packit Service 9f2c4a
    struct gssx_arg_indicate_mechs *ima;
Packit Service 9f2c4a
    struct gssx_res_indicate_mechs *imr;
Packit Service 9f2c4a
    gss_OID_set mech_set = GSS_C_NO_OID_SET;
Packit Service 9f2c4a
    gss_OID_set name_types = GSS_C_NO_OID_SET;
Packit Service 9f2c4a
    gss_OID_set mech_attrs = GSS_C_NO_OID_SET;
Packit Service 9f2c4a
    gss_OID_set known_mech_attrs = GSS_C_NO_OID_SET;
Packit Service 9f2c4a
    gss_buffer_desc sasl_mech_name = GSS_C_EMPTY_BUFFER;
Packit Service 9f2c4a
    gss_buffer_desc mech_name = GSS_C_EMPTY_BUFFER;
Packit Service 9f2c4a
    gss_buffer_desc mech_desc = GSS_C_EMPTY_BUFFER;
Packit Service 9f2c4a
    gss_OID_set attr_set = GSS_C_NO_OID_SET;
Packit Service 9f2c4a
    gss_buffer_desc name = GSS_C_EMPTY_BUFFER;
Packit Service 9f2c4a
    gss_buffer_desc short_desc = GSS_C_EMPTY_BUFFER;
Packit Service 9f2c4a
    gss_buffer_desc long_desc = GSS_C_EMPTY_BUFFER;
Packit Service 9f2c4a
    gssx_mech_info *mi;
Packit Service 9f2c4a
    gssx_mech_attr *ma;
Packit Service 9f2c4a
    uint32_t ret_maj;
Packit Service 9f2c4a
    uint32_t ret_min;
Packit Service 9f2c4a
    int present;
Packit Service 9f2c4a
     int ret;
Packit Service 9f2c4a
Packit Service 9f2c4a
    ima = &arg->indicate_mechs;
Packit Service 9f2c4a
    imr = &res->indicate_mechs;
Packit Service 9f2c4a
Packit Service 9f2c4a
    GPRPCDEBUG(gssx_arg_indicate_mechs, ima);
Packit Service 9f2c4a
Packit Service 9f2c4a
    /* get all mechs */
Packit Service 9f2c4a
    ret_maj = gss_indicate_mechs(&ret_min, &mech_set);
Packit Service 9f2c4a
    if (ret_maj) {
Packit Service 9f2c4a
        goto done;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    ret_maj = gss_create_empty_oid_set(&ret_min, &attr_set);
Packit Service 9f2c4a
    if (ret_maj) {
Packit Service 9f2c4a
        goto done;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    /* fill up gssx_mech_info */
Packit Service 9f2c4a
Packit Service 9f2c4a
    imr->mechs.mechs_val = calloc(mech_set->count, sizeof(gssx_mech_info));
Packit Service 9f2c4a
    if (!imr->mechs.mechs_val) {
Packit Service 9f2c4a
        ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
        ret_min = ENOMEM;
Packit Service 9f2c4a
        goto done;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    imr->mechs.mechs_len = mech_set->count;
Packit Service 9f2c4a
Packit Service 9f2c4a
    for (unsigned i = 0, h = 0; i < mech_set->count; i++, h++) {
Packit Service 9f2c4a
        mi = &imr->mechs.mechs_val[h];
Packit Service 9f2c4a
Packit Service 9f2c4a
        ret = gp_conv_oid_to_gssx(&mech_set->elements[i], &mi->mech);
Packit Service 9f2c4a
        if (ret) {
Packit Service 9f2c4a
            ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
            ret_min = ret;
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
Packit Service 9f2c4a
        ret_maj = gss_inquire_names_for_mech(&ret_min,
Packit Service 9f2c4a
                                             &mech_set->elements[i],
Packit Service 9f2c4a
                                             &name_types);
Packit Service 9f2c4a
        if (ret_maj) {
Packit Service 9f2c4a
            gp_log_failure(&mech_set->elements[i], ret_maj, ret_min);
Packit Service 9f2c4a
Packit Service 9f2c4a
            /* temporarily skip any offender */
Packit Service 9f2c4a
            imr->mechs.mechs_len--;
Packit Service 9f2c4a
            h--;
Packit Service 9f2c4a
            xdr_free((xdrproc_t)xdr_gssx_OID, (char *)&mi->mech);
Packit Service 9f2c4a
            continue;
Packit Service 9f2c4a
#if 0
Packit Service 9f2c4a
            ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
            ret_min = EINVAL;
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
#endif
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
Packit Service 9f2c4a
        ret = gp_conv_oid_set_to_gssx(name_types, &mi->name_types);
Packit Service 9f2c4a
        if (ret) {
Packit Service 9f2c4a
            ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
            ret_min = ret;
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
        gss_release_oid_set(&ret_min, &name_types);
Packit Service 9f2c4a
Packit Service 9f2c4a
        ret_maj = gss_inquire_attrs_for_mech(&ret_min,
Packit Service 9f2c4a
                                             &mech_set->elements[i],
Packit Service 9f2c4a
                                             &mech_attrs,
Packit Service 9f2c4a
                                             &known_mech_attrs);
Packit Service 9f2c4a
        if (ret_maj) {
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
Packit Service 9f2c4a
        ret = gp_conv_oid_set_to_gssx(mech_attrs, &mi->mech_attrs);
Packit Service 9f2c4a
        if (ret) {
Packit Service 9f2c4a
            ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
            ret_min = ret;
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
        for (unsigned j = 0; j < mech_attrs->count; j++) {
Packit Service 9f2c4a
            ret_maj = gss_test_oid_set_member(&ret_min,
Packit Service 9f2c4a
                                              &mech_attrs->elements[j],
Packit Service 9f2c4a
                                              attr_set,
Packit Service 9f2c4a
                                              &present);
Packit Service 9f2c4a
            if (ret_maj) {
Packit Service 9f2c4a
                goto done;
Packit Service 9f2c4a
            }
Packit Service 9f2c4a
Packit Service 9f2c4a
            if (present) {
Packit Service 9f2c4a
                continue;
Packit Service 9f2c4a
            }
Packit Service 9f2c4a
Packit Service 9f2c4a
            ret_maj = gss_add_oid_set_member(&ret_min,
Packit Service 9f2c4a
                                             &mech_attrs->elements[j],
Packit Service 9f2c4a
                                             &attr_set);
Packit Service 9f2c4a
            if (ret_maj) {
Packit Service 9f2c4a
                goto done;
Packit Service 9f2c4a
            }
Packit Service 9f2c4a
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
        gss_release_oid_set(&ret_min, &mech_attrs);
Packit Service 9f2c4a
Packit Service 9f2c4a
        ret = gp_conv_oid_set_to_gssx(known_mech_attrs,
Packit Service 9f2c4a
                                      &mi->known_mech_attrs);
Packit Service 9f2c4a
        if (ret) {
Packit Service 9f2c4a
            ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
            ret_min = ret;
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
Packit Service 9f2c4a
        for (unsigned j = 0; j < known_mech_attrs->count; j++) {
Packit Service 9f2c4a
            ret_maj = gss_test_oid_set_member(&ret_min,
Packit Service 9f2c4a
                                              &known_mech_attrs->elements[j],
Packit Service 9f2c4a
                                              attr_set,
Packit Service 9f2c4a
                                              &present);
Packit Service 9f2c4a
            if (ret_maj) {
Packit Service 9f2c4a
                goto done;
Packit Service 9f2c4a
            }
Packit Service 9f2c4a
Packit Service 9f2c4a
            if (present) {
Packit Service 9f2c4a
                continue;
Packit Service 9f2c4a
            }
Packit Service 9f2c4a
Packit Service 9f2c4a
            ret_maj = gss_add_oid_set_member(&ret_min,
Packit Service 9f2c4a
                                             &known_mech_attrs->elements[j],
Packit Service 9f2c4a
                                             &attr_set);
Packit Service 9f2c4a
            if (ret_maj) {
Packit Service 9f2c4a
                goto done;
Packit Service 9f2c4a
            }
Packit Service 9f2c4a
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
        gss_release_oid_set(&ret_min, &known_mech_attrs);
Packit Service 9f2c4a
Packit Service 9f2c4a
        ret_maj = gss_inquire_saslname_for_mech(&ret_min,
Packit Service 9f2c4a
                                                &mech_set->elements[i],
Packit Service 9f2c4a
                                                &sasl_mech_name,
Packit Service 9f2c4a
                                                &mech_name,
Packit Service 9f2c4a
                                                &mech_desc);
Packit Service 9f2c4a
        if (ret_maj) {
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
Packit Service 9f2c4a
        ret = gp_conv_buffer_to_gssx(&sasl_mech_name, &mi->saslname_sasl_mech_name);
Packit Service 9f2c4a
        if (ret) {
Packit Service 9f2c4a
            ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
            ret_min = ret;
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
        gss_release_buffer(&ret_min, &sasl_mech_name);
Packit Service 9f2c4a
Packit Service 9f2c4a
        ret = gp_conv_buffer_to_gssx(&mech_name, &mi->saslname_mech_name);
Packit Service 9f2c4a
        if (ret) {
Packit Service 9f2c4a
            ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
            ret_min = ret;
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
        gss_release_buffer(&ret_min, &mech_name);
Packit Service 9f2c4a
Packit Service 9f2c4a
        ret = gp_conv_buffer_to_gssx(&mech_desc, &mi->saslname_mech_desc);
Packit Service 9f2c4a
        if (ret) {
Packit Service 9f2c4a
            ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
            ret_min = ret;
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
        gss_release_buffer(&ret_min, &mech_desc);
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
    /* fill up gssx_mech_attr */
Packit Service 9f2c4a
Packit Service 9f2c4a
    imr->mech_attr_descs.mech_attr_descs_val = calloc(attr_set->count,
Packit Service 9f2c4a
                                                      sizeof(gssx_mech_attr));
Packit Service 9f2c4a
    if (!imr->mech_attr_descs.mech_attr_descs_val) {
Packit Service 9f2c4a
        ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
        ret_min = ENOMEM;
Packit Service 9f2c4a
        goto done;
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
    imr->mech_attr_descs.mech_attr_descs_len = attr_set->count;
Packit Service 9f2c4a
Packit Service 9f2c4a
    for (unsigned i = 0; i < attr_set->count; i++) {
Packit Service 9f2c4a
        ma = &imr->mech_attr_descs.mech_attr_descs_val[i];
Packit Service 9f2c4a
Packit Service 9f2c4a
        ret = gp_conv_oid_to_gssx(&attr_set->elements[i], &ma->attr);
Packit Service 9f2c4a
        if (ret) {
Packit Service 9f2c4a
            ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
            ret_min = ret;
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
Packit Service 9f2c4a
        ret_maj = gss_display_mech_attr(&ret_min,
Packit Service 9f2c4a
                                        &attr_set->elements[i],
Packit Service 9f2c4a
                                        &name,
Packit Service 9f2c4a
                                        &short_desc,
Packit Service 9f2c4a
                                        &long_desc);
Packit Service 9f2c4a
        if (ret_maj) {
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
Packit Service 9f2c4a
        ret = gp_conv_buffer_to_gssx(&name, &ma->name);
Packit Service 9f2c4a
        if (ret) {
Packit Service 9f2c4a
            ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
            ret_min = ret;
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
        gss_release_buffer(&ret_min, &name);
Packit Service 9f2c4a
Packit Service 9f2c4a
        ret = gp_conv_buffer_to_gssx(&short_desc, &ma->short_desc);
Packit Service 9f2c4a
        if (ret) {
Packit Service 9f2c4a
            ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
            ret_min = ret;
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
        gss_release_buffer(&ret_min, &short_desc);
Packit Service 9f2c4a
Packit Service 9f2c4a
        ret = gp_conv_buffer_to_gssx(&long_desc, &ma->long_desc);
Packit Service 9f2c4a
        if (ret) {
Packit Service 9f2c4a
            ret_maj = GSS_S_FAILURE;
Packit Service 9f2c4a
            ret_min = ret;
Packit Service 9f2c4a
            goto done;
Packit Service 9f2c4a
        }
Packit Service 9f2c4a
        gss_release_buffer(&ret_min, &long_desc);
Packit Service 9f2c4a
    }
Packit Service 9f2c4a
Packit Service 9f2c4a
done:
Packit Service 9f2c4a
    ret = gp_conv_status_to_gssx(ret_maj, ret_min, GSS_C_NO_OID,
Packit Service 9f2c4a
                                 &imr->status);
Packit Service 9f2c4a
    GPRPCDEBUG(gssx_res_indicate_mechs, imr);
Packit Service 9f2c4a
Packit Service 9f2c4a
    gss_release_buffer(&ret_min, &long_desc);
Packit Service 9f2c4a
    gss_release_buffer(&ret_min, &short_desc);
Packit Service 9f2c4a
    gss_release_buffer(&ret_min, &name);
Packit Service 9f2c4a
    gss_release_oid_set(&ret_min, &attr_set);
Packit Service 9f2c4a
    gss_release_buffer(&ret_min, &mech_desc);
Packit Service 9f2c4a
    gss_release_buffer(&ret_min, &mech_name);
Packit Service 9f2c4a
    gss_release_buffer(&ret_min, &sasl_mech_name);
Packit Service 9f2c4a
    gss_release_oid_set(&ret_min, &known_mech_attrs);
Packit Service 9f2c4a
    gss_release_oid_set(&ret_min, &mech_attrs);
Packit Service 9f2c4a
    gss_release_oid_set(&ret_min, &name_types);
Packit Service 9f2c4a
    gss_release_oid_set(&ret_min, &mech_set);
Packit Service 9f2c4a
    return ret;
Packit Service 9f2c4a
}