/*
 * Free a SPNEGO context handle. The caller must have acquired
 * the lock before this is called.
 */
OM_uint32 GSSAPI_CALLCONV _gss_spnego_internal_delete_sec_context
           (OM_uint32 *minor_status,
            gss_ctx_id_t *context_handle,
            gss_buffer_t output_token
           )
{
    gssspnego_ctx ctx;
    OM_uint32 ret, minor;

    *minor_status = 0;

    if (context_handle == NULL) {
	return GSS_S_NO_CONTEXT;
    }

    if (output_token != GSS_C_NO_BUFFER) {
	output_token->length = 0;
	output_token->value = NULL;
    }

    ctx = (gssspnego_ctx)*context_handle;
    *context_handle = GSS_C_NO_CONTEXT;

    if (ctx == NULL) {
	return GSS_S_NO_CONTEXT;
    }

    if (ctx->NegTokenInit_mech_types.value)
	free(ctx->NegTokenInit_mech_types.value);

    gss_release_oid(&minor, &ctx->preferred_mech_type);
    ctx->negotiated_mech_type = GSS_C_NO_OID;

    gss_release_oid(&minor, &ctx->selected_mech_type);
    ctx->selected_mech_type = GSS_C_NO_OID;

    gss_release_name(&minor, &ctx->target_name);
    gss_release_name(&minor, &ctx->mech_src_name);

    if (ctx->negotiated_ctx_id != GSS_C_NO_CONTEXT) {
	ret = gss_delete_sec_context(minor_status,
				     &ctx->negotiated_ctx_id,
				     NULL);
	ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT;
    } else {
	ret = GSS_S_COMPLETE;
    }

    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
    HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);

    free(ctx);

    return ret;
}
Example #2
0
static void
pamGssCleanupMech(pam_handle_t *pamh, void *data, int error_status)
{
#ifndef HAVE_HEIMDAL_VERSION
    OM_uint32 minor;

    gss_release_oid(&minor, (gss_OID *)&data);
#endif
}
Example #3
0
OM_uint32
ntlm_gss_delete_sec_context(
                OM_uint32 *minor_status,
                gss_ctx_id_t *context_handle,
                gss_buffer_t output_token)
{
    ntlm_gss_ctx_id_t ntlm_ctx = NULL;
    OM_uint32 ret = GSS_S_COMPLETE;
      
    if (context_handle == NULL)
    {
        return (GSS_S_FAILURE);
    }

    ntlm_ctx = (ntlm_gss_ctx_id_t) *context_handle;
    if (ntlm_ctx->upn_name)
    {
        free(ntlm_ctx->upn_name);
    }

    if (ntlm_ctx->ntlm_session_key)
    {
        free(ntlm_ctx->ntlm_session_key);
    }

    if (ntlm_ctx->ntlm_usr)
    {
        srp_user_delete(ntlm_ctx->ntlm_usr);
        ntlm_ctx->ntlm_usr = NULL;
    }
    
    if (ntlm_ctx->ntlm_ver)
    {
        srp_verifier_delete(ntlm_ctx->ntlm_ver);
        ntlm_ctx->ntlm_ver = NULL;
    }

    if (ntlm_ctx->mech)
    {
        OM_uint32 min_tmp = GSS_S_COMPLETE;
        gss_release_oid(&min_tmp, &ntlm_ctx->mech);
    }

    krb5_free_keyblock(ntlm_ctx->krb5_ctx, ntlm_ctx->keyblock);
    ntlm_ctx->keyblock = NULL;

    krb5_free_context(ntlm_ctx->krb5_ctx);
    ntlm_ctx->krb5_ctx = NULL;

    free(*context_handle);
    *context_handle = NULL;
    return (ret);
}
Example #4
0
uint32_t gp_conv_gssx_to_name(uint32_t *min, gssx_name *in, gss_name_t *out)
{
    gss_buffer_t input_name = GSS_C_NO_BUFFER;
    gss_OID name_type = GSS_C_NO_OID;
    gss_buffer_desc name_buffer;
    uint32_t ret_maj;
    uint32_t ret_min;
    int ret;

    if (in->display_name.octet_string_len != 0) {
        /* ok we have a display name.
         * In this case always import and canonicalize it so we can
         * safely export the name using the original form, even if we
         * already have exported_name */
        ret = gp_conv_gssx_to_buffer_alloc(&in->display_name, &input_name);
        if (ret) {
            ret_maj = GSS_S_FAILURE;
            ret_min = ret;
            goto done;
        }
        ret = gp_conv_gssx_to_oid_alloc(&in->name_type, &name_type);
        if (ret) {
            ret_maj = GSS_S_FAILURE;
            ret_min = ret;
            goto done;
        }

        ret_maj = gss_import_name(&ret_min, input_name, name_type, out);
        if (ret_maj) {
            goto done;
        }
    } else {
        gp_conv_gssx_to_buffer(&in->exported_name, &name_buffer);

        ret_maj = gss_import_name(&ret_min, &name_buffer,
                                  GSS_C_NT_EXPORT_NAME, out);
        if (ret_maj) {
            goto done;
        }
    }

done:
    *min = ret_min;
    gss_release_buffer(&ret_min, input_name);
    gss_release_oid(&ret_min, &name_type);
    return ret_maj;
}
Example #5
0
OM_uint32 KRB5_CALLCONV
gss_inquire_name(OM_uint32 *minor_status,
                 gss_name_t name,
                 int *name_is_MN,
                 gss_OID *MN_mech,
                 gss_buffer_set_t *attrs)
{
    OM_uint32           status, tmp;
    gss_union_name_t    union_name;
    gss_mechanism       mech;

    if (minor_status == NULL)
        return GSS_S_CALL_INACCESSIBLE_WRITE;

    if (name == GSS_C_NO_NAME)
        return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME;

    if (MN_mech != NULL)
        *MN_mech = GSS_C_NO_OID;

    if (attrs != NULL)
        *attrs = GSS_C_NO_BUFFER_SET;

    *minor_status = 0;
    union_name = (gss_union_name_t)name;

    if (union_name->mech_type == GSS_C_NO_OID) {
        /* We don't yet support non-mechanism attributes */
        if (name_is_MN != NULL)
            name_is_MN = 0;
        *minor_status = 0;
        return GSS_S_COMPLETE;
    }

    if (name_is_MN != NULL)
        *name_is_MN = 1;

    if (MN_mech != NULL) {
        status = generic_gss_copy_oid(minor_status,
                                      union_name->mech_type,
                                      MN_mech);
        if (GSS_ERROR(status))
            return status;
    }

    mech = gssint_get_mechanism(name->mech_type);
    if (mech == NULL) {
        gss_release_oid(&tmp, MN_mech);
        return GSS_S_BAD_NAME;
    }

    if (mech->gss_inquire_name == NULL) {
        gss_release_oid(&tmp, MN_mech);
        return GSS_S_UNAVAILABLE;
    }

    status = (*mech->gss_inquire_name)(minor_status,
                                       union_name->mech_name,
                                       NULL,
                                       NULL,
                                       attrs);
    if (status != GSS_S_COMPLETE) {
        generic_gss_release_oid(&tmp, MN_mech);
        map_error(minor_status, mech);
    }

    return status;
}
Example #6
0
int
pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
    int status, confFlags = 0;
    char hostNameBufBuf[5 + MAXHOSTNAMELEN + 1] = "host@";
    int isConvPasswordBuf = 0;

    OM_uint32 major, minor;
    gss_buffer_desc userNameBuf = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc hostNameBuf = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc passwordBuf = GSS_C_EMPTY_BUFFER;
    gss_name_t userName = GSS_C_NO_NAME;
    gss_name_t hostName = GSS_C_NO_NAME;
    gss_cred_id_t initiatorCred = GSS_C_NO_CREDENTIAL;
    gss_cred_id_t acceptorCred = GSS_C_NO_CREDENTIAL;
    gss_OID mech = &gss_spnego_mechanism_oid_desc;
    gss_OID_set_desc mechOids;

    confFlags = readConfFlags(argc, argv);

    status = readConfMechOid(argc, argv, &mech);
    BAIL_ON_PAM_ERROR(status);

    if (flags & PAM_DISALLOW_NULL_AUTHTOK)
        confFlags &= ~(FLAG_NULLOK);

    status = pam_get_user(pamh, (void *)&userNameBuf.value, NULL);
    BAIL_ON_PAM_ERROR(status);

    userNameBuf.length = strlen((char *)userNameBuf.value);

    major = gss_import_name(&minor, &userNameBuf, GSS_C_NT_USER_NAME, &userName);
    BAIL_ON_GSS_ERROR(major, minor);

    if (gethostname(&hostNameBufBuf[5], MAXHOSTNAMELEN) != 0) {
        status = PAM_SYSTEM_ERR;
        goto cleanup;
    }

    hostNameBuf.length = strlen(hostNameBufBuf);
    hostNameBuf.value = hostNameBufBuf;

    major = gss_import_name(&minor, &hostNameBuf, GSS_C_NT_HOSTBASED_SERVICE, &hostName);
    BAIL_ON_GSS_ERROR(major, minor);

    mechOids.count = 1;
    mechOids.elements = mech;

    major = gss_acquire_cred(&minor, hostName, GSS_C_INDEFINITE, &mechOids,
                             GSS_C_ACCEPT, &acceptorCred, NULL, NULL);
    BAIL_ON_GSS_ERROR(major, minor);

    status = PAM_AUTHINFO_UNAVAIL;

    if (confFlags & (FLAG_USE_FIRST_PASS | FLAG_TRY_FIRST_PASS)) {
        status = pam_get_item(pamh, PAM_AUTHTOK, (void *)&passwordBuf.value);
        BAIL_ON_PAM_ERROR(status);

        if (passwordBuf.value != NULL)
            passwordBuf.length = strlen((char *)passwordBuf.value);

        status = pamGssAcquireCred(pamh, confFlags, userName, &passwordBuf,
                                   mech, &initiatorCred);
        if (status == PAM_SUCCESS)
            status = pamGssInitAcceptSecContext(pamh, confFlags, initiatorCred,
                                                acceptorCred, hostName, mech);
        if (confFlags & FLAG_USE_FIRST_PASS)
            BAIL_ON_PAM_ERROR(status);
    }

    if (status != PAM_SUCCESS) {
        isConvPasswordBuf = 1;

        if (flags & PAM_SILENT)
            goto cleanup;

        status = pamGssGetAuthTok(pamh, confFlags, &passwordBuf);
        BAIL_ON_PAM_ERROR(status);

        gss_release_cred(&minor, &initiatorCred);

        status = pamGssAcquireCred(pamh, confFlags, userName, &passwordBuf,
                                   mech, &initiatorCred);
        if (status == PAM_SUCCESS)
            status = pamGssInitAcceptSecContext(pamh, confFlags, initiatorCred,
                                                acceptorCred, hostName, mech);
        BAIL_ON_PAM_ERROR(status);
    }

    status = pam_set_data(pamh, GSS_CRED_DATA, initiatorCred, pamGssCleanupCred);
    BAIL_ON_PAM_ERROR(status);

    initiatorCred = GSS_C_NO_CREDENTIAL;

cleanup:
    gss_release_name(&minor, &userName);
    gss_release_name(&minor, &hostName);
    gss_release_cred(&minor, &initiatorCred);
    gss_release_cred(&minor, &acceptorCred);
#ifdef __APPLE__
    if (mech != &gss_spnego_mechanism_oid_desc)
        gss_release_oid(&minor, &mech);
#endif
    if (isConvPasswordBuf) {
        memset((char *)passwordBuf.value, 0, passwordBuf.length);
        free(passwordBuf.value);
    }

    return status;
}
int gp_import_and_canon_name(struct gp_call_ctx *gpcall,
                             union gp_rpc_arg *arg,
                             union gp_rpc_res *res)
{
    struct gssx_arg_import_and_canon_name *icna;
    struct gssx_res_import_and_canon_name *icnr;
    gss_OID mech = GSS_C_NO_OID;
    gss_name_t import_name = GSS_C_NO_NAME;
    gss_name_t output_name = GSS_C_NO_NAME;
    uint32_t ret_maj = 0;
    uint32_t ret_min = 0;
    int ret;

    icna = &arg->import_and_canon_name;
    icnr = &res->import_and_canon_name;

    if (icna->input_name.display_name.octet_string_len == 0 &&
        icna->input_name.exported_name.octet_string_len == 0) {
        ret = EINVAL;
        goto done;
    }

    ret_maj = gp_conv_gssx_to_name(&ret_min, &icna->input_name, &import_name);
    if (ret_maj) {
        goto done;
    }

    if (icna->mech.octet_string_len != 0) {

        ret = gp_conv_gssx_to_oid_alloc(&icna->mech, &mech);
        if (ret) {
            ret_maj = GSS_S_FAILURE;
            ret_min = ret;
            goto done;
        }

        ret_maj = gss_canonicalize_name(&ret_min, import_name,
                                        mech, &output_name);
        if (ret_maj) {
            goto done;
        }

        ret_maj = gp_conv_name_to_gssx_alloc(&ret_min,
                                             output_name, &icnr->output_name);
    } else {
        ret_maj = gp_conv_name_to_gssx_alloc(&ret_min,
                                             import_name, &icnr->output_name);
    }

    /* TODO: check also icna->input_name.exported_composite_name */
    /* TODO: icna->name_attributes */

done:
    ret = gp_conv_status_to_gssx(&icna->call_ctx,
                                 ret_maj, ret_min, mech,
                                 &icnr->status);

    gss_release_oid(&ret_min, &mech);
    gss_release_name(&ret_min, &import_name);
    gss_release_name(&ret_min, &output_name);
    return ret;
}
Example #8
0
OM_uint32 gssi_inquire_context(OM_uint32 *minor_status,
                              gss_ctx_id_t context_handle,
                              gss_name_t *src_name,
                              gss_name_t *targ_name,
                              OM_uint32 *lifetime_rec,
                              gss_OID *mech_type,
                              OM_uint32 *ctx_flags,
                              int *locally_initiated,
                              int *open)
{
    struct gpp_context_handle *ctx_handle;
    struct gpp_name_handle *s_name = NULL;
    struct gpp_name_handle *t_name = NULL;
    gss_OID mech_oid;
    OM_uint32 maj, min;

    GSSI_TRACE();

    if (!context_handle) {
        return GSS_S_CALL_INACCESSIBLE_READ;
    }

    ctx_handle = (struct gpp_context_handle *)context_handle;
    if (!ctx_handle->local &&
        !ctx_handle->remote) {
        return GSS_S_CALL_INACCESSIBLE_READ;
    }

    if (src_name) {
        s_name = calloc(1, sizeof(struct gpp_name_handle));
        if (!s_name) {
            min = ENOMEM;
            maj = GSS_S_FAILURE;
            goto done;
        }
    }
    if (targ_name) {
        t_name = calloc(1, sizeof(struct gpp_name_handle));
        if (!t_name) {
            min = ENOMEM;
            maj = GSS_S_FAILURE;
            goto done;
        }
    }

    if (ctx_handle->local) {
        maj = gss_inquire_context(&min,
                                  ctx_handle->local,
                                  s_name ? &s_name->local : NULL,
                                  t_name ? &t_name->local : NULL,
                                  lifetime_rec,
                                  &mech_oid,
                                  ctx_flags,
                                  locally_initiated,
                                  open);
    } else {
        maj = gpm_inquire_context(&min,
                                  ctx_handle->remote,
                                  s_name ? &s_name->remote : NULL,
                                  t_name ? &t_name->remote : NULL,
                                  lifetime_rec,
                                  &mech_oid,
                                  ctx_flags,
                                  locally_initiated,
                                  open);
    }

    if (maj != GSS_S_COMPLETE) {
        goto done;
    }

    if (s_name) {
        maj = gpp_copy_oid(&min, mech_oid, &s_name->mech_type);
        if (maj != GSS_S_COMPLETE) {
            goto done;
        }
    }

    if (t_name) {
        maj = gpp_copy_oid(&min, mech_oid, &t_name->mech_type);
        if (maj != GSS_S_COMPLETE) {
            goto done;
        }
    }

done:
    *minor_status = gpp_map_error(min);
    if (maj == GSS_S_COMPLETE) {
        if (mech_type) {
            *mech_type = mech_oid;
        } else {
            (void)gss_release_oid(&min, &mech_oid);
        }
        if (src_name) {
            *src_name = (gss_name_t)s_name;
        }
        if (targ_name) {
            *targ_name = (gss_name_t)t_name;
        }
    } else {
        (void)gss_release_oid(&min, &mech_oid);
        (void)gssi_release_name(&min, (gss_name_t *)&s_name);
        (void)gssi_release_name(&min, (gss_name_t *)&t_name);
    }
    return maj;
}
Example #9
0
void *server_thread(void *pvt)
{
    const char **argv;
    struct athread *data;
    char buffer[MAX_RPC_SIZE];
    uint32_t buflen;
    gss_buffer_desc in_token = GSS_C_EMPTY_BUFFER;
    uint32_t ret_maj;
    uint32_t ret_min;
    struct gssx_ctx *context_handle = NULL;
    struct gssx_cred *cred_handle = NULL;
    struct gssx_name *src_name = NULL;
    gss_buffer_desc out_token = GSS_C_EMPTY_BUFFER;
    struct gssx_cred *deleg_cred = NULL;
    gss_OID_set mech_set = GSS_C_NO_OID_SET;
    gss_OID_set mech_names = GSS_C_NO_OID_SET;
    gss_OID_set mech_types = GSS_C_NO_OID_SET;
    gss_OID_set mech_attrs = GSS_C_NO_OID_SET;
    gss_OID_set known_mech_attrs = GSS_C_NO_OID_SET;
    gss_buffer_desc sasl_mech_name = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc mech_name = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc mech_description = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc name = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc short_desc = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc long_desc = GSS_C_EMPTY_BUFFER;
    gss_OID_set mechs = GSS_C_NO_OID_SET;
    gss_buffer_desc target_buf;
    struct gssx_name *target_name = NULL;
    struct gssx_name *canon_name = NULL;
    gss_buffer_desc out_name_buf = GSS_C_EMPTY_BUFFER;
    gss_OID out_name_type = GSS_C_NO_OID;
    gss_buffer_desc msg_token = GSS_C_EMPTY_BUFFER;
    int ret;
    gss_buffer_desc input_message_buffer = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc output_message_buffer = GSS_C_EMPTY_BUFFER;
    gss_qop_t qop_state;
    int conf_state;

    data = (struct athread *)pvt;
    argv = data->argv;

    target_buf.value = (void *)data->target;
    target_buf.length = strlen(data->target) + 1;

    /* import name family functions tests */
    ret_maj = gpm_import_name(&ret_min, &target_buf,
                              GSS_C_NT_HOSTBASED_SERVICE, &target_name);
    if (ret_maj) {
        DEBUG("gssproxy returned an error: %d\n", ret_maj);
        gp_log_failure(GSS_C_NO_OID, ret_maj, ret_min);
        goto done;
    }
    ret_maj = gpm_canonicalize_name(&ret_min, target_name,
                                    discard_const(gss_mech_krb5),
                                    &canon_name);
    if (ret_maj) {
        DEBUG("gssproxy returned an error: %d\n", ret_maj);
        gp_log_failure(GSS_C_NO_OID, ret_maj, ret_min);
        goto done;
    }
    ret_maj = gpm_display_name(&ret_min, canon_name,
                               &out_name_buf, &out_name_type);
    if (ret_maj) {
        DEBUG("gssproxy returned an error: %d\n", ret_maj);
        gp_log_failure(GSS_C_NO_OID, ret_maj, ret_min);
        goto done;
    }
    DEBUG("Acquiring for: %s\n", (char *)out_name_buf.value);

    /* indicate mechs family functions tests */
    ret_maj = gpm_indicate_mechs(&ret_min, &mech_set);
    if (ret_maj) {
        DEBUG("gssproxy returned an error: %d\n", ret_maj);
        gp_log_failure(GSS_C_NO_OID, ret_maj, ret_min);
        goto done;
    }

    ret_maj = gpm_inquire_names_for_mech(&ret_min,
                                         &mech_set->elements[0],
                                         &mech_names);
    if (ret_maj) {
        DEBUG("gssproxy returned an error: %d\n", ret_maj);
        gp_log_failure(&mech_set->elements[0], ret_maj, ret_min);
        goto done;
    }
    ret_maj = gpm_inquire_attrs_for_mech(&ret_min,
                                         &mech_set->elements[0],
                                         &mech_attrs,
                                         &known_mech_attrs);
    if (ret_maj) {
        DEBUG("gssproxy returned an error: %d\n", ret_maj);
        gp_log_failure(&mech_set->elements[0], ret_maj, ret_min);
        goto done;
    }
    ret_maj = gpm_inquire_saslname_for_mech(&ret_min,
                                            &mech_set->elements[0],
                                            &sasl_mech_name,
                                            &mech_name,
                                            &mech_description);
    if (ret_maj) {
        DEBUG("gssproxy returned an error: %d\n", ret_maj);
        gp_log_failure(&mech_set->elements[0], ret_maj, ret_min);
        goto done;
    }
    ret_maj = gpm_display_mech_attr(&ret_min,
                                    &mech_attrs->elements[0],
                                    &name, &short_desc, &long_desc);
    if (ret_maj) {
        DEBUG("gssproxy returned an error: %d\n", ret_maj);
        gp_log_failure(GSS_C_NO_OID, ret_maj, ret_min);
        goto done;
    }
    ret_maj = gpm_indicate_mechs_by_attrs(&ret_min,
                                          GSS_C_NO_OID_SET,
                                          GSS_C_NO_OID_SET,
                                          GSS_C_NO_OID_SET,
                                          &mechs);
    if (ret_maj) {
        DEBUG("gssproxy returned an error: %d\n", ret_maj);
        gp_log_failure(GSS_C_NO_OID, ret_maj, ret_min);
        goto done;
    }
    ret_maj = gpm_inquire_mechs_for_name(&ret_min, target_name, &mech_types);
    if (ret_maj) {
        DEBUG("gssproxy returned an error: %d\n", ret_maj);
        gp_log_failure(GSS_C_NO_OID, ret_maj, ret_min);
        goto done;
    }

    ret_maj = gpm_acquire_cred(&ret_min,
                               NULL, NULL,
                               GSS_C_INDEFINITE,
                               mech_set,
                               GSS_C_ACCEPT,
                               false,
                               &cred_handle,
                               NULL,
                               NULL);
    if (ret_maj) {
        DEBUG("gssproxy returned an error: %d\n", ret_maj);
        gp_log_failure(GSS_C_NO_OID, ret_maj, ret_min);
        goto done;
    }

    ret = t_recv_buffer(data->srv_pipe[0], buffer, &buflen);
    if (ret) {
        DEBUG("Failed to get data from client!\n");
        goto done;
    }

    in_token.value = buffer;
    in_token.length = buflen;

    ret_maj = gpm_accept_sec_context(&ret_min,
                                     &context_handle,
                                     cred_handle,
                                     &in_token,
                                     GSS_C_NO_CHANNEL_BINDINGS,
                                     &src_name,
                                     NULL,
                                     &out_token,
                                     NULL,
                                     NULL,
                                     &deleg_cred);
    if (ret_maj) {
        DEBUG("gssproxy returned an error: %d\n", ret_maj);
        gp_log_failure(GSS_C_NO_OID, ret_maj, ret_min);
        goto done;
    }

    if (out_token.length) {
        ret = t_send_buffer(data->cli_pipe[1],
                             out_token.value, out_token.length);
        if (ret) {
            DEBUG("Failed to send data to client!\n");
            goto done;
        }
    }

    /* receive message from client */
    ret = t_recv_buffer(data->srv_pipe[0], buffer, &buflen);
    if (ret) {
        DEBUG("Failed to get data from client!\n");
        goto done;
    }
    in_token.value = buffer;
    in_token.length = buflen;

    /* receive signature from client */
    ret = t_recv_buffer(data->srv_pipe[0],
                         &buffer[in_token.length], &buflen);
    if (ret) {
        DEBUG("Failed to get data from client!\n");
        goto done;
    }
    msg_token.value = &buffer[in_token.length];
    msg_token.length = buflen;

    ret_maj = gpm_verify_mic(&ret_min, context_handle,
                             &in_token, &msg_token, NULL);
    if (ret_maj) {
        DEBUG("gpm_verify_mic failed: %d\n", ret_maj);
        gp_log_failure(GSS_C_NO_OID, ret_maj, ret_min);
        goto done;
    }

    DEBUG("Received valid msg from client: [%s]\n", buffer);

    ret = t_recv_buffer(data->srv_pipe[0], buffer, &buflen);
    if (ret) {
        DEBUG("Failed to get data from client!\n");
        goto done;
    }

    input_message_buffer.value = buffer;
    input_message_buffer.length = buflen;

    ret_maj = gpm_unwrap(&ret_min,
                         context_handle,
                         &input_message_buffer,
                         &output_message_buffer,
                         &conf_state,
                         &qop_state);
    if (ret_maj) {
        DEBUG("gpm_unwrap failed: %d\n", ret_maj);
        gp_log_failure(GSS_C_NO_OID, ret_maj, ret_min);
        goto done;
    }

    DEBUG("Received valid msg from client: [%s]\n",
        (char *)output_message_buffer.value);

done:
    gpm_release_name(&ret_min, &src_name);
    gpm_release_buffer(&ret_min, &out_token);
    gpm_release_buffer(&ret_min, &output_message_buffer);
    gpm_release_cred(&ret_min, &deleg_cred);
    gpm_delete_sec_context(&ret_min, &context_handle, GSS_C_NO_BUFFER);
    gss_release_oid_set(&ret_min, &mech_set);
    gss_release_oid_set(&ret_min, &mech_names);
    gss_release_oid_set(&ret_min, &mech_types);
    gss_release_oid_set(&ret_min, &mech_attrs);
    gss_release_oid_set(&ret_min, &known_mech_attrs);
    gss_release_buffer(&ret_min, &sasl_mech_name);
    gss_release_buffer(&ret_min, &mech_name);
    gss_release_buffer(&ret_min, &mech_description);
    gss_release_buffer(&ret_min, &name);
    gss_release_buffer(&ret_min, &short_desc);
    gss_release_buffer(&ret_min, &long_desc);
    gss_release_oid_set(&ret_min, &mechs);
    gpm_release_name(&ret_min, &target_name);
    gpm_release_name(&ret_min, &canon_name);
    gss_release_buffer(&ret_min, &out_name_buf);
    gss_release_oid(&ret_min, &out_name_type);
    close(data->srv_pipe[0]);
    close(data->cli_pipe[1]);
    pthread_exit(NULL);
}
Example #10
0
static bool mag_list_of_mechs(cmd_parms *parms, gss_OID_set *oidset,
                              bool add_spnego, const char *w)
{
    gss_buffer_desc buf = { 0 };
    uint32_t maj, min;
    gss_OID_set set;
    gss_OID oid;
    bool release_oid = false;

    if (NULL == *oidset) {
        maj = gss_create_empty_oid_set(&min, &set);
        if (maj != GSS_S_COMPLETE) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
                         "gss_create_empty_oid_set() failed.");
            *oidset = GSS_C_NO_OID_SET;
            return false;
        }
        if (add_spnego) {
            oid = discard_const(&gss_mech_spnego);
            maj = gss_add_oid_set_member(&min, oid, &set);
            if (maj != GSS_S_COMPLETE) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
                             "gss_add_oid_set_member() failed.");
                (void)gss_release_oid_set(&min, &set);
                *oidset = GSS_C_NO_OID_SET;
                return false;
            }
        }
        /* register in the pool so it can be released once the server
         * winds down */
        apr_pool_cleanup_register(parms->pool, (void *)set,
                                  mag_oid_set_destroy,
                                  apr_pool_cleanup_null);
        *oidset = set;
    } else {
        set = *oidset;
    }

    if (strcmp(w, "krb5") == 0) {
        oid = discard_const(gss_mech_krb5);
    } else if (strcmp(w, "iakerb") == 0) {
        oid = discard_const(gss_mech_iakerb);
    } else if (strcmp(w, "ntlmssp") == 0) {
        oid = discard_const(gss_mech_ntlmssp);
    } else {
        buf.value = discard_const(w);
        buf.length = strlen(w);
        maj = gss_str_to_oid(&min, &buf, &oid);
        if (maj != GSS_S_COMPLETE) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
                         "Unrecognized GSSAPI Mechanism: [%s]", w);
            return false;
        }
        release_oid = true;
    }
    maj = gss_add_oid_set_member(&min, oid, &set);
    if (maj != GSS_S_COMPLETE) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
                         "gss_add_oid_set_member() failed for [%s].", w);
    }
    if (release_oid) {
        (void)gss_release_oid(&min, &oid);
    }

    return true;
}
Example #11
0
static OM_uint32
initAcceptSecContext(OM_uint32 *minor, gss_cred_id_t claimant_cred_handle,
                     gss_cred_id_t verifier_cred_handle,
                     gss_cred_id_t *deleg_cred_handle)
{
    OM_uint32 major, tmp_minor;
    gss_buffer_desc token, tmp;
    gss_ctx_id_t initiator_context = GSS_C_NO_CONTEXT;
    gss_ctx_id_t acceptor_context = GSS_C_NO_CONTEXT;
    gss_name_t source_name = GSS_C_NO_NAME;
    gss_name_t target_name = GSS_C_NO_NAME;
    OM_uint32 time_rec;
    gss_OID mech = GSS_C_NO_OID;

    token.value = NULL;
    token.length = 0;

    tmp.value = NULL;
    tmp.length = 0;

    *deleg_cred_handle = GSS_C_NO_CREDENTIAL;

    major = gss_inquire_cred(minor, verifier_cred_handle,
                             &target_name, NULL, NULL, NULL);
    if (GSS_ERROR(major)) {
        displayStatus("gss_inquire_cred", major, *minor);
        return major;
    }

    displayCanonName(minor, target_name, "Target name");

    mech = use_spnego ? (gss_OID)&spnego_mech : (gss_OID)gss_mech_krb5;
    displayOID(minor, mech, "Target mech");

    major = gss_init_sec_context(minor,
                                 claimant_cred_handle,
                                 &initiator_context,
                                 target_name,
                                 mech,
                                 GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG,
                                 GSS_C_INDEFINITE,
                                 GSS_C_NO_CHANNEL_BINDINGS,
                                 GSS_C_NO_BUFFER,
                                 NULL,
                                 &token,
                                 NULL,
                                 &time_rec);

    if (target_name != GSS_C_NO_NAME)
        (void) gss_release_name(&tmp_minor, &target_name);

    if (GSS_ERROR(major)) {
        displayStatus("gss_init_sec_context", major, *minor);
        return major;
    }

    mech = GSS_C_NO_OID;

    major = gss_accept_sec_context(minor,
                                   &acceptor_context,
                                   verifier_cred_handle,
                                   &token,
                                   GSS_C_NO_CHANNEL_BINDINGS,
                                   &source_name,
                                   &mech,
                                   &tmp,
                                   NULL,
                                   &time_rec,
                                   deleg_cred_handle);

    if (GSS_ERROR(major))
        displayStatus("gss_accept_sec_context", major, *minor);
    else {
        testPrf(minor, initiator_context, acceptor_context, GSS_C_PRF_KEY_FULL);
        testPrf(minor, initiator_context, acceptor_context, GSS_C_PRF_KEY_PARTIAL);
    }

    (void) gss_release_name(&tmp_minor, &source_name);
    (void) gss_delete_sec_context(&tmp_minor, &acceptor_context, NULL);
    (void) gss_delete_sec_context(minor, &initiator_context, NULL);
    (void) gss_release_buffer(&tmp_minor, &token);
    (void) gss_release_buffer(&tmp_minor, &tmp);
    (void) gss_release_oid(&tmp_minor, &mech);

    return major;
}