Пример #1
0
/*
 * Decrypt the ticket in req using an entry in keytab matching server (if
 * given).  Set req->ticket->server to the principal of the keytab entry used.
 * Store the decrypting key in *keyblock_out if it is not NULL.
 */
static krb5_error_code
decrypt_ticket(krb5_context context, const krb5_ap_req *req,
               krb5_const_principal server, krb5_keytab keytab,
               krb5_keyblock *keyblock_out)
{
    krb5_error_code ret;
    krb5_keytab_entry ent;
    krb5_kt_cursor cursor;

#ifdef LEAN_CLIENT
    return KRB5KRB_AP_WRONG_PRINC;
#else
    /* If we have an explicit server principal, try just that one. */
    if (!is_matching(context, server))
        return try_one_princ(context, req, server, keytab, keyblock_out);

    if (keytab->ops->start_seq_get == NULL) {
        /* We can't iterate over the keytab.  Try the principal asserted by the
         * client if it's allowed by the server parameter. */
        if (!krb5_sname_match(context, server, req->ticket->server))
            return KRB5KRB_AP_WRONG_PRINC;
        return try_one_princ(context, req, req->ticket->server, keytab,
                             keyblock_out);
    }

    ret = krb5_kt_start_seq_get(context, keytab, &cursor);
    if (ret)
        goto cleanup;

    while ((ret = krb5_kt_next_entry(context, keytab, &ent, &cursor)) == 0) {
        if (ent.key.enctype == req->ticket->enc_part.enctype &&
            krb5_sname_match(context, server, ent.principal)) {
            ret = try_one_entry(context, req, &ent, keyblock_out);
            if (ret == 0) {
                TRACE_RD_REQ_DECRYPT_ANY(context, ent.principal, &ent.key);
                (void)krb5_free_keytab_entry_contents(context, &ent);
                break;
            }
        }

        (void)krb5_free_keytab_entry_contents(context, &ent);
    }

    (void)krb5_kt_end_seq_get(context, keytab, &cursor);

cleanup:
    switch (ret) {
    case KRB5_KT_KVNONOTFOUND:
    case KRB5_KT_NOTFOUND:
    case KRB5_KT_END:
    case KRB5KRB_AP_ERR_BAD_INTEGRITY:
        ret = KRB5KRB_AP_WRONG_PRINC;
        break;
    default:
        break;
    }

    return ret;
#endif /* LEAN_CLIENT */
}
Пример #2
0
/* https://stackoverflow.com/a/2718114/6049386 , MIT, Feb 2018 */
static const char *match(const char *str)
{
   if (*str == '\0' || is_closing(*str))
      return str;

   if (is_opening(*str)) {
      const char *closer = match(str + 1);

      if (is_matching(*str, *closer))
         return match(closer + 1);

      return str;
   }

   return match(++str);
}
Пример #3
0
/*
 * Decrypt the ticket in req using an entry in keytab matching server (if
 * given).  Set req->ticket->server to the principal of the keytab entry used.
 * Store the decrypting key in *keyblock_out if it is not NULL.
 */
static krb5_error_code
decrypt_ticket(krb5_context context, const krb5_ap_req *req,
               krb5_const_principal server, krb5_keytab keytab,
               krb5_keyblock *keyblock_out)
{
    krb5_error_code ret;
    krb5_keytab_entry ent;
    krb5_kt_cursor cursor;
    krb5_principal tkt_server = req->ticket->server;
    krb5_kvno tkt_kvno = req->ticket->enc_part.kvno;
    krb5_enctype tkt_etype = req->ticket->enc_part.enctype;
    krb5_boolean similar_enctype;
    krb5_boolean tkt_server_mismatch = FALSE, found_server_match = FALSE;
    krb5_boolean found_tkt_server = FALSE, found_enctype = FALSE;
    krb5_boolean found_kvno = FALSE, found_higher_kvno = FALSE;

#ifdef LEAN_CLIENT
    return KRB5KRB_AP_WRONG_PRINC;
#else
    /* If we have an explicit server principal, try just that one. */
    if (!is_matching(context, server)) {
        return try_one_princ(context, req, server, keytab, TRUE,
                             keyblock_out);
    }

    if (keytab->ops->start_seq_get == NULL) {
        /* We can't iterate over the keytab.  Try the principal asserted by the
         * client if it's allowed by the server parameter. */
        if (!krb5_sname_match(context, server, tkt_server))
            return nomatch_error(context, server, tkt_server);
        return try_one_princ(context, req, tkt_server, keytab, FALSE,
                             keyblock_out);
    }

    /* Scan all keys in the keytab, in case the ticket server is an alias for
     * one of the principals in the keytab. */
    ret = krb5_kt_start_seq_get(context, keytab, &cursor);
    if (ret) {
        k5_change_error_message_code(context, ret, KRB5KRB_AP_ERR_NOKEY);
        return KRB5KRB_AP_ERR_NOKEY;
    }
    while ((ret = krb5_kt_next_entry(context, keytab, &ent, &cursor)) == 0) {
        /* Only try keys which match the server principal. */
        if (!krb5_sname_match(context, server, ent.principal)) {
            if (krb5_principal_compare(context, ent.principal, tkt_server))
                tkt_server_mismatch = TRUE;
            continue;
        }
        found_server_match = TRUE;

        if (krb5_c_enctype_compare(context, ent.key.enctype, tkt_etype,
                                   &similar_enctype) != 0)
            similar_enctype = FALSE;

        if (krb5_principal_compare(context, ent.principal, tkt_server)) {
            found_tkt_server = TRUE;
            if (ent.vno == tkt_kvno) {
                found_kvno = TRUE;
                if (similar_enctype)
                    found_enctype = TRUE;
            } else if (ent.vno > tkt_kvno) {
                found_higher_kvno = TRUE;
            }
        }

        /* Only try keys with similar enctypes to the ticket enctype. */
        if (similar_enctype) {
            /* Coerce inexact matches to the request enctype. */
            ent.key.enctype = tkt_etype;
            if (try_one_entry(context, req, &ent, keyblock_out) == 0) {
                TRACE_RD_REQ_DECRYPT_ANY(context, ent.principal, &ent.key);
                (void)krb5_free_keytab_entry_contents(context, &ent);
                break;
            }
        }

        (void)krb5_free_keytab_entry_contents(context, &ent);
    }

    (void)krb5_kt_end_seq_get(context, keytab, &cursor);

    if (ret != KRB5_KT_END)
        return ret;
    return iteration_error(context, server, tkt_server, tkt_kvno, tkt_etype,
                           tkt_server_mismatch, found_server_match,
                           found_tkt_server, found_kvno, found_higher_kvno,
                           found_enctype);
#endif /* LEAN_CLIENT */
}
Пример #4
0
//----------------------------------------------------------------------------------
bool Helper_ProcessFace(IGameMesh * gM,
                        unsigned int Index,
                        const AffineParts & PRS,
                        const Matrix3 & world_to_obj,
                        MatFaceMapType & matface_map,
                        TriMapType     & tri_map,
                        unsigned int & MaxFaceIdx)
{
    FaceEx *pFace		= gM->GetFace(Index);
    IGameMaterial *pIGMat = gM->GetMaterialFromFace(Index);
    bool HasTexVerts	= gM->GetNumberOfTexVerts() ? true : false;
    bool HasCVerts		= gM->GetNumberOfColorVerts() ? true : false;
    unsigned int smg_id = pFace->smGrp; // smooth group
    unsigned int mat_id = ExporterMAX::GetExporter()->FindMaterialIdx(pIGMat);
    IGameSkin *skin = NULL;

    const int numMod = gM->GetNumModifiers();

    if (numMod > 0)
    {
        for (int i = 0; i < numMod; i++)     // check for skin modifier
        {
            IGameModifier *pM = gM->GetIGameModifier(i);
            if (pM->IsSkin()) {
                skin = (IGameSkin*)pM; // skin modifier
            }
        }
    }

    mesh_opt * m_opt = NULL;

    // lets sort by material and find the corresponding mesh_opt
    MatFaceMapIt it_matfacemap = matface_map.find(mat_id);

    if (it_matfacemap == matface_map.end()) // no corresponding mesh, allocate new face holder
    {
        m_opt = new mesh_opt();
        matface_map.insert(MatFaceMapPair(mat_id, m_opt));
    }
    else
    {
        m_opt = (*it_matfacemap).second;
    }

    for (int j = 0; j < 3; ++j) // build the face
    {
        vert_opt face;
        unsigned int idx;
        unsigned int ori_face_idx = pFace->vert[j]; // get index into the vertex array
        unsigned int face_idx = ori_face_idx;

        bool create_face = false;

        // build the face as expected
        face.smg_id = smg_id; // smooth group

        if (HasTexVerts)
        {
            idx = pFace->texCoord[j]; // get index into the standard mapping channel

            if (idx != BAD_IDX)
            {
                face.t.x = gM->GetTexVertex(idx).x;
                face.t.y = gM->GetTexVertex(idx).y;
            }
        }

        if (HasCVerts)
        {
            idx = pFace->color[j];
            face.c.x = gM->GetColorVertex(idx).x;  // get vertex color
            face.c.y = gM->GetColorVertex(idx).y;
            face.c.z = gM->GetColorVertex(idx).z;
            face.c.w = 1.f;

        } else {
            face.c = Vector4f(1.f, 1.f, 1.f, 1.f);
        }

        Tab<int> mapNums = gM->GetActiveMapChannelNum();
        face.num_tmaps = mapNums.Count();

        if (face.num_tmaps)
        {
            face.tmaps = new Vector[face.num_tmaps];
            for (size_t k = 0; k < face.num_tmaps; ++k)
            {
                unsigned long mapfaceidx[3];
                gM->GetMapFaceIndex(mapNums[k], Index, &mapfaceidx[0]);
                idx = mapfaceidx[j];
                face.tmaps[k].x = gM->GetMapVertex(mapNums[k], idx).x;
                face.tmaps[k].y = gM->GetMapVertex(mapNums[k], idx).y;
                face.tmaps[k].z = gM->GetMapVertex(mapNums[k], idx).z;
            }
        }

        // try to find in origin array
        FaceMapIt it_face_map = m_opt->face_map.find(face_idx);  // get face map iter

        if (it_face_map == m_opt->face_map.end()) // if not find such create anyway
        {
            create_face = true;
        }
        else
        {
            if (is_matching((*it_face_map).second, face) == false) // check find vertex not matching
            {
                bool found = false;

                // process vertex multi map
                std::pair<FaceMMapIt,FaceMMapIt> pair_mmap = m_opt->face_mmap.equal_range(ori_face_idx);

                FaceMMapIt it_face_mmap = pair_mmap.first;

                while (it_face_mmap != pair_mmap.second && found == false)
                {
                    idxvert_opt & idxface = (*it_face_mmap).second;

                    if (is_matching(idxface.face, face))
                    {
                        face_idx = idxface.new_idx;
                        found = true;
                    }
                    ++it_face_mmap;
                }

                if (found == false)
                {
                    create_face = true;
                    ++MaxFaceIdx;			// increment max index and
                    face_idx = MaxFaceIdx;	// set index is out of bounds of origin 3DMax's index range
                }
            }
        }

        if (create_face)
        {
            if (skin)
            {
                std::vector<w_offset>   w_offsets;
                for (int k = 0; k < skin->GetNumberOfBones(ori_face_idx); ++k)
                {
                    /*	if (skin->GetWeight(ori_face_idx, k) > m_eps)
                    	{
                    		w_offset w;
                    		w.weight = skin->GetWeight(ori_face_idx, k);

                    		_BoneObject * Bone = ExporterMAX::GetExporter()->Skeleton.AddMaxBone(skin->GetIGameBone(ori_face_idx, k), skin->GetIGameBone(ori_face_idx, k)->GetNodeID());
                    		assert(Bone != NULL);

                    		w.bone_id = Bone->GetID();
                    		w_offsets.push_back(w);
                    	}*/
                }

//				std::sort(w_offsets.begin(), w_offsets.end(), heavier);

                int ILeft = 0;
                for (size_t l = 0; l < w_offsets.size() && l < 4; ++l, ++ILeft)
                {
                    w_offset & w = w_offsets[l];
                    face.weights[l] = w.weight;
                    face.bones[l] = w.bone_id;
                }

                for (; ILeft < 4; ++ILeft)
                {
                    face.weights[ILeft] = 0.f;
                    face.bones[ILeft] = BAD_IDX;
                }

                // check for valid weights...
                float w_sum = 0.f;

                for (int l = 0; l < 4; ++l) {
                    w_sum += face.weights[l];
                }

                if ((w_sum < m_one - m_eps) || (w_sum > m_one + m_eps))
                {
                    for (int l = 0; l < 4; ++l) // renormalizing...
                        face.weights[l] /= w_sum;
                }
            }

            Point3 v_world = gM->GetVertex(ori_face_idx);
            Point3 v_obj = v_world; // * world_to_obj;

            face.v.x = v_obj.x; // * PRS.k.x * PRS.f;
            face.v.y = v_obj.z; // * PRS.k.z * PRS.f;
            face.v.z = v_obj.y; // * PRS.k.y * PRS.f;

            // add the vertex and store its new idx
            face.face_idx = m_opt->count;

            m_opt->face_map.insert(FaceMapPair(face_idx, face));

            if (ori_face_idx != face_idx)  // store the newly created and duplicated independently
            {
                idxvert_opt idxface(face_idx, face);// store new face
                m_opt->face_mmap.insert(FaceMMapPair(ori_face_idx, idxface)); // but store key as a original
            }
            m_opt->count++;
        }

        // add the face indices...
        TriMapIt it = tri_map.find(mat_id);
        if (it != tri_map.end())
        {
            (*it).second->push_back(face_idx);
        }
        else
        {
            IdxType * idx_type = new IdxType;
            idx_type->push_back(face_idx);
            tri_map.insert(TriMapPair(mat_id, idx_type));
        }
    }
    return true;
}