Annotation of embedaddon/strongswan/src/libtnccs/plugins/tnc_imv/tnc_imv_recommendations.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2010-2012 Andreas Steffen
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: #include <tncifimv.h>
                     17: #include <tncif_names.h>
                     18: #include <tncif_policy.h>
                     19: 
                     20: #include <tnc/tnc.h>
                     21: #include <tnc/imv/imv.h>
                     22: #include <tnc/imv/imv_manager.h>
                     23: #include <tnc/imv/imv_recommendations.h>
                     24: 
                     25: #include <utils/debug.h>
                     26: #include <collections/linked_list.h>
                     27: 
                     28: typedef struct private_tnc_imv_recommendations_t private_tnc_imv_recommendations_t;
                     29: typedef struct recommendation_entry_t recommendation_entry_t;
                     30: 
                     31: /**
                     32:  * Recommendation entry
                     33:  */
                     34: struct recommendation_entry_t {
                     35: 
                     36:        /**
                     37:         * IMV ID
                     38:         */
                     39:        TNC_IMVID id;
                     40: 
                     41:        /**
                     42:         * Received a recommendation message from this IMV?
                     43:         */
                     44:        bool have_recommendation;
                     45: 
                     46:        /**
                     47:         * Action Recommendation provided by IMV instance
                     48:         */
                     49:        TNC_IMV_Action_Recommendation rec;
                     50: 
                     51:        /**
                     52:         * Evaluation Result provided by IMV instance
                     53:         */
                     54:        TNC_IMV_Evaluation_Result eval;
                     55: 
                     56:        /**
                     57:         * Reason string provided by IMV instance
                     58:         */
                     59:        chunk_t reason;
                     60: 
                     61:        /**
                     62:         * Reason language provided by IMV instance
                     63:         */
                     64:        chunk_t reason_language;
                     65: };
                     66: 
                     67: /**
                     68:  * Private data of a recommendations_t object.
                     69:  */
                     70: struct private_tnc_imv_recommendations_t {
                     71: 
                     72:        /**
                     73:         * Public members of recommendations_t.
                     74:         */
                     75:        recommendations_t public;
                     76: 
                     77:        /**
                     78:         * list of recommendations and evaluations provided by IMVs
                     79:         */
                     80:        linked_list_t *recs;
                     81: 
                     82:        /**
                     83:         * Preferred language for remediation messages
                     84:         */
                     85:        chunk_t preferred_language;
                     86: };
                     87: 
                     88: METHOD(recommendations_t, provide_recommendation, TNC_Result,
                     89:        private_tnc_imv_recommendations_t* this, TNC_IMVID id,
                     90:                                                                                         TNC_IMV_Action_Recommendation rec,
                     91:                                                                                         TNC_IMV_Evaluation_Result eval)
                     92: {
                     93:        enumerator_t *enumerator;
                     94:        recommendation_entry_t *entry;
                     95:        bool found = FALSE;
                     96: 
                     97:        DBG2(DBG_TNC, "IMV %u provides recommendation '%N' and evaluation '%N'", id,
                     98:                 TNC_IMV_Action_Recommendation_names, rec,
                     99:                 TNC_IMV_Evaluation_Result_names, eval);
                    100: 
                    101:        enumerator = this->recs->create_enumerator(this->recs);
                    102:        while (enumerator->enumerate(enumerator, &entry))
                    103:        {
                    104:                if (entry->id == id)
                    105:                {
                    106:                        found = TRUE;
                    107:                        entry->have_recommendation = TRUE;
                    108:                        entry->rec = rec;
                    109:                        entry->eval = eval;
                    110:                        break;
                    111:                }
                    112:        }
                    113:        enumerator->destroy(enumerator);
                    114:        return found ? TNC_RESULT_SUCCESS : TNC_RESULT_FATAL;
                    115: }
                    116: 
                    117: METHOD(recommendations_t, have_recommendation, bool,
                    118:        private_tnc_imv_recommendations_t *this, TNC_IMV_Action_Recommendation *rec,
                    119:                                                                                         TNC_IMV_Evaluation_Result *eval)
                    120: {
                    121:        enumerator_t *enumerator;
                    122:        recommendation_entry_t *entry;
                    123:        recommendation_policy_t policy;
                    124:        TNC_IMV_Action_Recommendation final_rec;
                    125:        TNC_IMV_Evaluation_Result final_eval;
                    126:        bool first = TRUE, incomplete = FALSE;
                    127: 
                    128:        final_rec  = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION;
                    129:        final_eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW;
                    130:        if (rec && eval)
                    131:        {
                    132:                *rec  = final_rec;
                    133:                *eval = final_eval;
                    134:        }
                    135: 
                    136:        if (this->recs->get_count(this->recs) == 0)
                    137:        {
                    138:                DBG1(DBG_TNC, "there are no IMVs to make a recommendation");
                    139:                return TRUE;
                    140:        }
                    141:        policy = tnc->imvs->get_recommendation_policy(tnc->imvs);
                    142: 
                    143:        enumerator = this->recs->create_enumerator(this->recs);
                    144:        while (enumerator->enumerate(enumerator, &entry))
                    145:        {
                    146:                if (!entry->have_recommendation)
                    147:                {
                    148:                        incomplete = TRUE;
                    149:                        break;
                    150:                }
                    151:                if (first)
                    152:                {
                    153:                        final_rec = entry->rec;
                    154:                        final_eval = entry->eval;
                    155:                        first = FALSE;
                    156:                        continue;
                    157:                }
                    158:                switch (policy)
                    159:                {
                    160:                        case RECOMMENDATION_POLICY_DEFAULT:
                    161:                                final_rec = tncif_policy_update_recommendation(final_rec,
                    162:                                                                                                                           entry->rec);
                    163:                                final_eval = tncif_policy_update_evaluation(final_eval,
                    164:                                                                                                                        entry->eval);
                    165:                                break;
                    166: 
                    167:                        case RECOMMENDATION_POLICY_ALL:
                    168:                                if (entry->rec != final_rec)
                    169:                                {
                    170:                                        final_rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION;
                    171:                                }
                    172:                                if (entry->eval != final_eval)
                    173:                                {
                    174:                                        final_eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW;
                    175:                                }
                    176:                                break;
                    177: 
                    178:                        case RECOMMENDATION_POLICY_ANY:
                    179:                                switch (entry->rec)
                    180:                                {
                    181:                                        case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
                    182:                                                final_rec = entry->rec;
                    183:                                                break;
                    184:                                        case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
                    185:                                                if (final_rec != TNC_IMV_ACTION_RECOMMENDATION_ALLOW)
                    186:                                                {
                    187:                                                        final_rec = entry->rec;
                    188:                                                };
                    189:                                                break;
                    190:                                        case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
                    191:                                                if (final_rec == TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION)
                    192:                                                {
                    193:                                                        final_rec = entry->rec;
                    194:                                                };
                    195:                                                break;
                    196:                                        case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
                    197:                                                break;
                    198:                                }
                    199:                                switch (entry->eval)
                    200:                                {
                    201:                                        case TNC_IMV_EVALUATION_RESULT_COMPLIANT:
                    202:                                                final_eval = entry->eval;
                    203:                                                break;
                    204:                                        case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR:
                    205:                                                if (final_eval != TNC_IMV_EVALUATION_RESULT_COMPLIANT)
                    206:                                                {
                    207:                                                        final_eval = entry->eval;
                    208:                                                }
                    209:                                                break;
                    210:                                        case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR:
                    211:                                                if (final_eval != TNC_IMV_EVALUATION_RESULT_COMPLIANT &&
                    212:                                                        final_eval != TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR)
                    213:                                                {
                    214:                                                        final_eval = entry->eval;
                    215:                                                }
                    216:                                                break;
                    217:                                        case TNC_IMV_EVALUATION_RESULT_ERROR:
                    218:                                                if (final_eval == TNC_IMV_EVALUATION_RESULT_DONT_KNOW)
                    219:                                                {
                    220:                                                        final_eval = entry->eval;
                    221:                                                }
                    222:                                                break;
                    223:                                        case TNC_IMV_EVALUATION_RESULT_DONT_KNOW:
                    224:                                                break;
                    225:                                }
                    226:                }
                    227:        }
                    228:        enumerator->destroy(enumerator);
                    229: 
                    230:        if (incomplete)
                    231:        {
                    232:                return FALSE;
                    233:        }
                    234:        if (rec && eval)
                    235:        {
                    236:                *rec  = final_rec;
                    237:                *eval = final_eval;
                    238:        }
                    239:        return TRUE;
                    240: }
                    241: 
                    242: METHOD(recommendations_t, clear_recommendation, void,
                    243:        private_tnc_imv_recommendations_t *this)
                    244: {
                    245:        enumerator_t *enumerator;
                    246:        recommendation_entry_t *entry;
                    247: 
                    248:        enumerator = this->recs->create_enumerator(this->recs);
                    249:        while (enumerator->enumerate(enumerator, &entry))
                    250:        {
                    251:                entry->have_recommendation = FALSE;
                    252:                entry->rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION;
                    253:                entry->eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW;
                    254:                chunk_clear(&entry->reason);
                    255:                chunk_clear(&entry->reason_language);
                    256:        }
                    257:        enumerator->destroy(enumerator);
                    258: }
                    259: 
                    260: METHOD(recommendations_t, get_preferred_language, chunk_t,
                    261:        private_tnc_imv_recommendations_t *this)
                    262: {
                    263:        return this->preferred_language;
                    264: }
                    265: 
                    266: METHOD(recommendations_t, set_preferred_language, void,
                    267:        private_tnc_imv_recommendations_t *this, chunk_t pref_lang)
                    268: {
                    269:        free(this->preferred_language.ptr);
                    270:        this->preferred_language = chunk_clone(pref_lang);
                    271: }
                    272: 
                    273: METHOD(recommendations_t, set_reason_string, TNC_Result,
                    274:        private_tnc_imv_recommendations_t *this, TNC_IMVID id, chunk_t reason)
                    275: {
                    276:        enumerator_t *enumerator;
                    277:        recommendation_entry_t *entry;
                    278:        bool found = FALSE;
                    279: 
                    280:        DBG2(DBG_TNC, "IMV %u is setting reason string to '%.*s'",
                    281:                 id, (int)reason.len, reason.ptr);
                    282: 
                    283:        enumerator = this->recs->create_enumerator(this->recs);
                    284:        while (enumerator->enumerate(enumerator, &entry))
                    285:        {
                    286:                if (entry->id == id)
                    287:                {
                    288:                        found = TRUE;
                    289:                        free(entry->reason.ptr);
                    290:                        entry->reason = chunk_clone(reason);
                    291:                        break;
                    292:                }
                    293:        }
                    294:        enumerator->destroy(enumerator);
                    295:        return found ? TNC_RESULT_SUCCESS : TNC_RESULT_INVALID_PARAMETER;
                    296: }
                    297: 
                    298: METHOD(recommendations_t, set_reason_language, TNC_Result,
                    299:        private_tnc_imv_recommendations_t *this, TNC_IMVID id, chunk_t reason_lang)
                    300: {
                    301:        enumerator_t *enumerator;
                    302:        recommendation_entry_t *entry;
                    303:        bool found = FALSE;
                    304: 
                    305:        DBG2(DBG_TNC, "IMV %u is setting reason language to '%.*s'",
                    306:                 id, (int)reason_lang.len, reason_lang.ptr);
                    307: 
                    308:        enumerator = this->recs->create_enumerator(this->recs);
                    309:        while (enumerator->enumerate(enumerator, &entry))
                    310:        {
                    311:                if (entry->id == id)
                    312:                {
                    313:                        found = TRUE;
                    314:                        free(entry->reason_language.ptr);
                    315:                        entry->reason_language = chunk_clone(reason_lang);
                    316:                        break;
                    317:                }
                    318:        }
                    319:        enumerator->destroy(enumerator);
                    320:        return found ? TNC_RESULT_SUCCESS : TNC_RESULT_INVALID_PARAMETER;
                    321: }
                    322: 
                    323: CALLBACK(reason_filter, bool,
                    324:        void *null, enumerator_t *orig, va_list args)
                    325: {
                    326:        recommendation_entry_t *entry;
                    327:        TNC_IMVID *id;
                    328:        chunk_t *reason, *reason_language;
                    329: 
                    330:        VA_ARGS_VGET(args, id, reason, reason_language);
                    331: 
                    332:        while (orig->enumerate(orig, &entry))
                    333:        {
                    334:                if (entry->reason.len)
                    335:                {
                    336:                        *id = entry->id;
                    337:                        *reason = entry->reason;
                    338:                        *reason_language = entry->reason_language;
                    339:                        return TRUE;
                    340:                }
                    341:        }
                    342:        return FALSE;
                    343: }
                    344: 
                    345: METHOD(recommendations_t, create_reason_enumerator, enumerator_t*,
                    346:        private_tnc_imv_recommendations_t *this)
                    347: {
                    348:        return enumerator_create_filter(this->recs->create_enumerator(this->recs),
                    349:                                                                        reason_filter, NULL, NULL);
                    350: }
                    351: 
                    352: METHOD(recommendations_t, destroy, void,
                    353:        private_tnc_imv_recommendations_t *this)
                    354: {
                    355:        recommendation_entry_t *entry;
                    356: 
                    357:        while (this->recs->remove_last(this->recs, (void**)&entry) == SUCCESS)
                    358:        {
                    359:                free(entry->reason.ptr);
                    360:                free(entry->reason_language.ptr);
                    361:                free(entry);
                    362:        }
                    363:        this->recs->destroy(this->recs);
                    364:        free(this->preferred_language.ptr);
                    365:        free(this);
                    366: }
                    367: 
                    368: /**
                    369:  * Described in header.
                    370:  */
                    371: recommendations_t* tnc_imv_recommendations_create(linked_list_t *imv_list)
                    372: {
                    373:        private_tnc_imv_recommendations_t *this;
                    374:        recommendation_entry_t *entry;
                    375:        enumerator_t *enumerator;
                    376:        imv_t *imv;
                    377: 
                    378:        INIT(this,
                    379:                .public = {
                    380:                        .provide_recommendation = _provide_recommendation,
                    381:                        .have_recommendation = _have_recommendation,
                    382:                        .clear_recommendation = _clear_recommendation,
                    383:                        .get_preferred_language = _get_preferred_language,
                    384:                        .set_preferred_language = _set_preferred_language,
                    385:                        .set_reason_string = _set_reason_string,
                    386:                        .set_reason_language = _set_reason_language,
                    387:                        .create_reason_enumerator = _create_reason_enumerator,
                    388:                        .destroy = _destroy,
                    389:                },
                    390:                .recs = linked_list_create(),
                    391:        );
                    392: 
                    393:        enumerator = imv_list->create_enumerator(imv_list);
                    394:        while (enumerator->enumerate(enumerator, &imv))
                    395:        {
                    396:                entry = malloc_thing(recommendation_entry_t);
                    397:                entry->id = imv->get_id(imv);
                    398:                entry->have_recommendation = FALSE;
                    399:                entry->rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION;
                    400:                entry->eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW;
                    401:                entry->reason = chunk_empty;
                    402:                entry->reason_language = chunk_empty;
                    403:                this->recs->insert_last(this->recs, entry);
                    404:        }
                    405:        enumerator->destroy(enumerator);
                    406: 
                    407:        return &this->public;
                    408: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>