Annotation of embedaddon/strongswan/src/libsimaka/simaka_manager.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2008 Martin Willi
        !             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 "simaka_manager.h"
        !            17: 
        !            18: #include <utils/debug.h>
        !            19: #include <collections/linked_list.h>
        !            20: #include <threading/rwlock.h>
        !            21: 
        !            22: typedef struct private_simaka_manager_t private_simaka_manager_t;
        !            23: 
        !            24: /**
        !            25:  * Private data of an simaka_manager_t object.
        !            26:  */
        !            27: struct private_simaka_manager_t {
        !            28: 
        !            29:        /**
        !            30:         * Public simaka_manager_t interface.
        !            31:         */
        !            32:        simaka_manager_t public;
        !            33: 
        !            34:        /**
        !            35:         * list of added cards
        !            36:         */
        !            37:        linked_list_t *cards;
        !            38: 
        !            39:        /**
        !            40:         * list of added provider
        !            41:         */
        !            42:        linked_list_t *providers;
        !            43: 
        !            44:        /**
        !            45:         * list of added hooks
        !            46:         */
        !            47:        linked_list_t *hooks;
        !            48: 
        !            49:        /**
        !            50:         * lock for lists above
        !            51:         */
        !            52:        rwlock_t *lock;
        !            53: };
        !            54: 
        !            55: /**
        !            56:  * Described in header.
        !            57:  */
        !            58: void libsimaka_init(void)
        !            59: {
        !            60:        /* empty */
        !            61: }
        !            62: 
        !            63: METHOD(simaka_manager_t, add_card, void,
        !            64:        private_simaka_manager_t *this, simaka_card_t *card)
        !            65: {
        !            66:        this->lock->write_lock(this->lock);
        !            67:        this->cards->insert_last(this->cards, card);
        !            68:        this->lock->unlock(this->lock);
        !            69: }
        !            70: 
        !            71: METHOD(simaka_manager_t, remove_card, void,
        !            72:        private_simaka_manager_t *this, simaka_card_t *card)
        !            73: {
        !            74:        this->lock->write_lock(this->lock);
        !            75:        this->cards->remove(this->cards, card, NULL);
        !            76:        this->lock->unlock(this->lock);
        !            77: }
        !            78: 
        !            79: METHOD(simaka_manager_t, card_get_triplet, bool,
        !            80:        private_simaka_manager_t *this, identification_t *id,
        !            81:        char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
        !            82: {
        !            83:        enumerator_t *enumerator;
        !            84:        simaka_card_t *card;
        !            85:        int tried = 0;
        !            86: 
        !            87:        this->lock->read_lock(this->lock);
        !            88:        enumerator = this->cards->create_enumerator(this->cards);
        !            89:        while (enumerator->enumerate(enumerator, &card))
        !            90:        {
        !            91:                if (card->get_triplet(card, id, rand, sres, kc))
        !            92:                {
        !            93:                        enumerator->destroy(enumerator);
        !            94:                        this->lock->unlock(this->lock);
        !            95:                        return TRUE;
        !            96:                }
        !            97:                tried++;
        !            98:        }
        !            99:        enumerator->destroy(enumerator);
        !           100:        this->lock->unlock(this->lock);
        !           101:        DBG1(DBG_LIB, "tried %d SIM cards, but none has triplets for '%Y'",
        !           102:                 tried, id);
        !           103:        return FALSE;
        !           104: }
        !           105: 
        !           106: METHOD(simaka_manager_t, card_get_quintuplet, status_t,
        !           107:        private_simaka_manager_t *this, identification_t *id, char rand[AKA_RAND_LEN],
        !           108:        char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN],
        !           109:        char res[AKA_RES_MAX], int *res_len)
        !           110: {
        !           111:        enumerator_t *enumerator;
        !           112:        simaka_card_t *card;
        !           113:        status_t status = NOT_FOUND;
        !           114:        int tried = 0;
        !           115: 
        !           116:        this->lock->read_lock(this->lock);
        !           117:        enumerator = this->cards->create_enumerator(this->cards);
        !           118:        while (enumerator->enumerate(enumerator, &card))
        !           119:        {
        !           120:                status = card->get_quintuplet(card, id, rand, autn, ck, ik, res, res_len);
        !           121:                switch (status)
        !           122:                {       /* try next on error, but not on INVALID_STATE */
        !           123:                        case SUCCESS:
        !           124:                        case INVALID_STATE:
        !           125:                                enumerator->destroy(enumerator);
        !           126:                                this->lock->unlock(this->lock);
        !           127:                                return status;
        !           128:                        case NOT_SUPPORTED:
        !           129:                        case FAILED:
        !           130:                        default:
        !           131:                                tried++;
        !           132:                                continue;
        !           133:                }
        !           134:        }
        !           135:        enumerator->destroy(enumerator);
        !           136:        this->lock->unlock(this->lock);
        !           137:        DBG1(DBG_LIB, "tried %d SIM cards, but none has quintuplets for '%Y'",
        !           138:                 tried, id);
        !           139:        return status;
        !           140: }
        !           141: 
        !           142: METHOD(simaka_manager_t, card_resync, bool,
        !           143:        private_simaka_manager_t *this, identification_t *id,
        !           144:        char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
        !           145: {
        !           146:        enumerator_t *enumerator;
        !           147:        simaka_card_t *card;
        !           148: 
        !           149:        this->lock->read_lock(this->lock);
        !           150:        enumerator = this->cards->create_enumerator(this->cards);
        !           151:        while (enumerator->enumerate(enumerator, &card))
        !           152:        {
        !           153:                if (card->resync(card, id, rand, auts))
        !           154:                {
        !           155:                        enumerator->destroy(enumerator);
        !           156:                        this->lock->unlock(this->lock);
        !           157:                        return TRUE;
        !           158:                }
        !           159:        }
        !           160:        enumerator->destroy(enumerator);
        !           161:        this->lock->unlock(this->lock);
        !           162:        return FALSE;
        !           163: }
        !           164: 
        !           165: METHOD(simaka_manager_t, card_set_pseudonym, void,
        !           166:        private_simaka_manager_t *this, identification_t *id,
        !           167:        identification_t *pseudonym)
        !           168: {
        !           169:        enumerator_t *enumerator;
        !           170:        simaka_card_t *card;
        !           171: 
        !           172:        DBG1(DBG_LIB, "storing pseudonym '%Y' for '%Y'", pseudonym, id);
        !           173: 
        !           174:        this->lock->read_lock(this->lock);
        !           175:        enumerator = this->cards->create_enumerator(this->cards);
        !           176:        while (enumerator->enumerate(enumerator, &card))
        !           177:        {
        !           178:                card->set_pseudonym(card, id, pseudonym);
        !           179:        }
        !           180:        enumerator->destroy(enumerator);
        !           181:        this->lock->unlock(this->lock);
        !           182: }
        !           183: 
        !           184: METHOD(simaka_manager_t, card_get_pseudonym, identification_t*,
        !           185:        private_simaka_manager_t *this, identification_t *id)
        !           186: {
        !           187:        enumerator_t *enumerator;
        !           188:        simaka_card_t *card;
        !           189:        identification_t *pseudonym = NULL;
        !           190: 
        !           191:        this->lock->read_lock(this->lock);
        !           192:        enumerator = this->cards->create_enumerator(this->cards);
        !           193:        while (enumerator->enumerate(enumerator, &card))
        !           194:        {
        !           195:                pseudonym = card->get_pseudonym(card, id);
        !           196:                if (pseudonym)
        !           197:                {
        !           198:                        DBG1(DBG_LIB, "using stored pseudonym identity '%Y' "
        !           199:                                 "instead of '%Y'", pseudonym, id);
        !           200:                        break;
        !           201:                }
        !           202:        }
        !           203:        enumerator->destroy(enumerator);
        !           204:        this->lock->unlock(this->lock);
        !           205:        return pseudonym;
        !           206: }
        !           207: 
        !           208: METHOD(simaka_manager_t, card_set_reauth, void,
        !           209:        private_simaka_manager_t *this, identification_t *id, identification_t *next,
        !           210:        char mk[HASH_SIZE_SHA1], uint16_t counter)
        !           211: {
        !           212:        enumerator_t *enumerator;
        !           213:        simaka_card_t *card;
        !           214: 
        !           215:        DBG1(DBG_LIB, "storing next reauthentication identity '%Y' for '%Y'",
        !           216:                 next, id);
        !           217: 
        !           218:        this->lock->read_lock(this->lock);
        !           219:        enumerator = this->cards->create_enumerator(this->cards);
        !           220:        while (enumerator->enumerate(enumerator, &card))
        !           221:        {
        !           222:                card->set_reauth(card, id, next, mk, counter);
        !           223:        }
        !           224:        enumerator->destroy(enumerator);
        !           225:        this->lock->unlock(this->lock);
        !           226: }
        !           227: 
        !           228: METHOD(simaka_manager_t, card_get_reauth, identification_t*,
        !           229:        private_simaka_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1],
        !           230:        uint16_t *counter)
        !           231: {
        !           232:        enumerator_t *enumerator;
        !           233:        simaka_card_t *card;
        !           234:        identification_t *reauth = NULL;
        !           235: 
        !           236:        this->lock->read_lock(this->lock);
        !           237:        enumerator = this->cards->create_enumerator(this->cards);
        !           238:        while (enumerator->enumerate(enumerator, &card))
        !           239:        {
        !           240:                reauth = card->get_reauth(card, id, mk, counter);
        !           241:                if (reauth)
        !           242:                {
        !           243:                        DBG1(DBG_LIB, "using stored reauthentication identity '%Y' "
        !           244:                                 "instead of '%Y'", reauth, id);
        !           245:                        break;
        !           246:                }
        !           247:        }
        !           248:        enumerator->destroy(enumerator);
        !           249:        this->lock->unlock(this->lock);
        !           250:        return reauth;
        !           251: }
        !           252: 
        !           253: METHOD(simaka_manager_t, add_provider, void,
        !           254:        private_simaka_manager_t *this, simaka_provider_t *provider)
        !           255: {
        !           256:        this->lock->write_lock(this->lock);
        !           257:        this->providers->insert_last(this->providers, provider);
        !           258:        this->lock->unlock(this->lock);
        !           259: }
        !           260: 
        !           261: METHOD(simaka_manager_t, remove_provider, void,
        !           262:        private_simaka_manager_t *this, simaka_provider_t *provider)
        !           263: {
        !           264:        this->lock->write_lock(this->lock);
        !           265:        this->providers->remove(this->providers, provider, NULL);
        !           266:        this->lock->unlock(this->lock);
        !           267: }
        !           268: 
        !           269: METHOD(simaka_manager_t, provider_get_triplet, bool,
        !           270:        private_simaka_manager_t *this, identification_t *id,
        !           271:        char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
        !           272: {
        !           273:        enumerator_t *enumerator;
        !           274:        simaka_provider_t *provider;
        !           275:        int tried = 0;
        !           276: 
        !           277:        this->lock->read_lock(this->lock);
        !           278:        enumerator = this->providers->create_enumerator(this->providers);
        !           279:        while (enumerator->enumerate(enumerator, &provider))
        !           280:        {
        !           281:                if (provider->get_triplet(provider, id, rand, sres, kc))
        !           282:                {
        !           283:                        enumerator->destroy(enumerator);
        !           284:                        this->lock->unlock(this->lock);
        !           285:                        return TRUE;
        !           286:                }
        !           287:                tried++;
        !           288:        }
        !           289:        enumerator->destroy(enumerator);
        !           290:        this->lock->unlock(this->lock);
        !           291:        DBG1(DBG_LIB, "tried %d SIM providers, but none had a triplet for '%Y'",
        !           292:                 tried, id);
        !           293:        return FALSE;
        !           294: }
        !           295: 
        !           296: METHOD(simaka_manager_t, provider_get_quintuplet, bool,
        !           297:        private_simaka_manager_t *this, identification_t *id,
        !           298:        char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len,
        !           299:        char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN])
        !           300: {
        !           301:        enumerator_t *enumerator;
        !           302:        simaka_provider_t *provider;
        !           303:        int tried = 0;
        !           304: 
        !           305:        this->lock->read_lock(this->lock);
        !           306:        enumerator = this->providers->create_enumerator(this->providers);
        !           307:        while (enumerator->enumerate(enumerator, &provider))
        !           308:        {
        !           309:                if (provider->get_quintuplet(provider, id, rand, xres, xres_len,
        !           310:                                                                         ck, ik, autn))
        !           311:                {
        !           312:                        enumerator->destroy(enumerator);
        !           313:                        this->lock->unlock(this->lock);
        !           314:                        return TRUE;
        !           315:                }
        !           316:        }
        !           317:        enumerator->destroy(enumerator);
        !           318:        this->lock->unlock(this->lock);
        !           319:        DBG1(DBG_LIB, "tried %d SIM providers, but none had a quintuplet for '%Y'",
        !           320:                 tried, id);
        !           321:        return FALSE;
        !           322: }
        !           323: 
        !           324: METHOD(simaka_manager_t, provider_resync, bool,
        !           325:        private_simaka_manager_t *this, identification_t *id,
        !           326:        char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
        !           327: {
        !           328:        enumerator_t *enumerator;
        !           329:        simaka_provider_t *provider;
        !           330: 
        !           331:        this->lock->read_lock(this->lock);
        !           332:        enumerator = this->providers->create_enumerator(this->providers);
        !           333:        while (enumerator->enumerate(enumerator, &provider))
        !           334:        {
        !           335:                if (provider->resync(provider, id, rand, auts))
        !           336:                {
        !           337:                        enumerator->destroy(enumerator);
        !           338:                        this->lock->unlock(this->lock);
        !           339:                        return TRUE;
        !           340:                }
        !           341:        }
        !           342:        enumerator->destroy(enumerator);
        !           343:        this->lock->unlock(this->lock);
        !           344:        return FALSE;
        !           345: }
        !           346: 
        !           347: METHOD(simaka_manager_t, provider_is_pseudonym, identification_t*,
        !           348:        private_simaka_manager_t *this, identification_t *id)
        !           349: {
        !           350:        enumerator_t *enumerator;
        !           351:        simaka_provider_t *provider;
        !           352:        identification_t *permanent = NULL;
        !           353: 
        !           354:        this->lock->read_lock(this->lock);
        !           355:        enumerator = this->providers->create_enumerator(this->providers);
        !           356:        while (enumerator->enumerate(enumerator, &provider))
        !           357:        {
        !           358:                permanent = provider->is_pseudonym(provider, id);
        !           359:                if (permanent)
        !           360:                {
        !           361:                        DBG1(DBG_LIB, "received pseudonym identity '%Y' "
        !           362:                                 "mapping to '%Y'", id, permanent);
        !           363:                        break;
        !           364:                }
        !           365:        }
        !           366:        enumerator->destroy(enumerator);
        !           367:        this->lock->unlock(this->lock);
        !           368:        return permanent;
        !           369: }
        !           370: 
        !           371: METHOD(simaka_manager_t, provider_gen_pseudonym, identification_t*,
        !           372:        private_simaka_manager_t *this, identification_t *id)
        !           373: {
        !           374:        enumerator_t *enumerator;
        !           375:        simaka_provider_t *provider;
        !           376:        identification_t *pseudonym = NULL;
        !           377: 
        !           378:        this->lock->read_lock(this->lock);
        !           379:        enumerator = this->providers->create_enumerator(this->providers);
        !           380:        while (enumerator->enumerate(enumerator, &provider))
        !           381:        {
        !           382:                pseudonym = provider->gen_pseudonym(provider, id);
        !           383:                if (pseudonym)
        !           384:                {
        !           385:                        DBG1(DBG_LIB, "proposing new pseudonym '%Y'", pseudonym);
        !           386:                        break;
        !           387:                }
        !           388:        }
        !           389:        enumerator->destroy(enumerator);
        !           390:        this->lock->unlock(this->lock);
        !           391:        return pseudonym;
        !           392: }
        !           393: 
        !           394: METHOD(simaka_manager_t, provider_is_reauth, identification_t*,
        !           395:        private_simaka_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1],
        !           396:        uint16_t *counter)
        !           397: {
        !           398:        enumerator_t *enumerator;
        !           399:        simaka_provider_t *provider;
        !           400:        identification_t *permanent = NULL;
        !           401: 
        !           402:        this->lock->read_lock(this->lock);
        !           403:        enumerator = this->providers->create_enumerator(this->providers);
        !           404:        while (enumerator->enumerate(enumerator, &provider))
        !           405:        {
        !           406:                permanent = provider->is_reauth(provider, id, mk, counter);
        !           407:                if (permanent)
        !           408:                {
        !           409:                        DBG1(DBG_LIB, "received reauthentication identity '%Y' "
        !           410:                                 "mapping to '%Y'", id, permanent);
        !           411:                        break;
        !           412:                }
        !           413:        }
        !           414:        enumerator->destroy(enumerator);
        !           415:        this->lock->unlock(this->lock);
        !           416:        return permanent;
        !           417: }
        !           418: 
        !           419: METHOD(simaka_manager_t, provider_gen_reauth, identification_t*,
        !           420:        private_simaka_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1])
        !           421: {
        !           422:        enumerator_t *enumerator;
        !           423:        simaka_provider_t *provider;
        !           424:        identification_t *reauth = NULL;
        !           425: 
        !           426:        this->lock->read_lock(this->lock);
        !           427:        enumerator = this->providers->create_enumerator(this->providers);
        !           428:        while (enumerator->enumerate(enumerator, &provider))
        !           429:        {
        !           430:                reauth = provider->gen_reauth(provider, id, mk);
        !           431:                if (reauth)
        !           432:                {
        !           433:                        DBG1(DBG_LIB, "proposing new reauthentication identity '%Y'", reauth);
        !           434:                        break;
        !           435:                }
        !           436:        }
        !           437:        enumerator->destroy(enumerator);
        !           438:        this->lock->unlock(this->lock);
        !           439:        return reauth;
        !           440: }
        !           441: 
        !           442: METHOD(simaka_manager_t, add_hooks, void,
        !           443:        private_simaka_manager_t *this, simaka_hooks_t *hooks)
        !           444: {
        !           445:        this->lock->write_lock(this->lock);
        !           446:        this->hooks->insert_last(this->hooks, hooks);
        !           447:        this->lock->unlock(this->lock);
        !           448: }
        !           449: 
        !           450: METHOD(simaka_manager_t, remove_hooks, void,
        !           451:        private_simaka_manager_t *this, simaka_hooks_t *hooks)
        !           452: {
        !           453:        this->lock->write_lock(this->lock);
        !           454:        this->hooks->remove(this->hooks, hooks, NULL);
        !           455:        this->lock->unlock(this->lock);
        !           456: }
        !           457: 
        !           458: METHOD(simaka_manager_t, message_hook, void,
        !           459:        private_simaka_manager_t *this, simaka_message_t *message,
        !           460:        bool inbound, bool decrypted)
        !           461: {
        !           462:        enumerator_t *enumerator;
        !           463:        simaka_hooks_t *hooks;
        !           464: 
        !           465:        this->lock->read_lock(this->lock);
        !           466:        enumerator = this->hooks->create_enumerator(this->hooks);
        !           467:        while (enumerator->enumerate(enumerator, &hooks))
        !           468:        {
        !           469:                hooks->message(hooks, message, inbound, decrypted);
        !           470:        }
        !           471:        enumerator->destroy(enumerator);
        !           472:        this->lock->unlock(this->lock);
        !           473: }
        !           474: 
        !           475: METHOD(simaka_manager_t, key_hook, void,
        !           476:        private_simaka_manager_t *this, chunk_t k_encr, chunk_t k_auth)
        !           477: {
        !           478:        enumerator_t *enumerator;
        !           479:        simaka_hooks_t *hooks;
        !           480: 
        !           481:        this->lock->read_lock(this->lock);
        !           482:        enumerator = this->hooks->create_enumerator(this->hooks);
        !           483:        while (enumerator->enumerate(enumerator, &hooks))
        !           484:        {
        !           485:                hooks->keys(hooks, k_encr, k_auth);
        !           486:        }
        !           487:        enumerator->destroy(enumerator);
        !           488:        this->lock->unlock(this->lock);
        !           489: }
        !           490: 
        !           491: METHOD(simaka_manager_t, destroy, void,
        !           492:        private_simaka_manager_t *this)
        !           493: {
        !           494:        this->cards->destroy(this->cards);
        !           495:        this->providers->destroy(this->providers);
        !           496:        this->hooks->destroy(this->hooks);
        !           497:        this->lock->destroy(this->lock);
        !           498:        free(this);
        !           499: }
        !           500: 
        !           501: /**
        !           502:  * See header
        !           503:  */
        !           504: simaka_manager_t *simaka_manager_create()
        !           505: {
        !           506:        private_simaka_manager_t *this;
        !           507: 
        !           508:        INIT(this,
        !           509:                .public = {
        !           510:                        .add_card = _add_card,
        !           511:                        .remove_card = _remove_card,
        !           512:                        .card_get_triplet = _card_get_triplet,
        !           513:                        .card_get_quintuplet = _card_get_quintuplet,
        !           514:                        .card_resync = _card_resync,
        !           515:                        .card_set_pseudonym = _card_set_pseudonym,
        !           516:                        .card_get_pseudonym = _card_get_pseudonym,
        !           517:                        .card_set_reauth = _card_set_reauth,
        !           518:                        .card_get_reauth = _card_get_reauth,
        !           519:                        .add_provider = _add_provider,
        !           520:                        .remove_provider = _remove_provider,
        !           521:                        .provider_get_triplet = _provider_get_triplet,
        !           522:                        .provider_get_quintuplet = _provider_get_quintuplet,
        !           523:                        .provider_resync = _provider_resync,
        !           524:                        .provider_is_pseudonym = _provider_is_pseudonym,
        !           525:                        .provider_gen_pseudonym = _provider_gen_pseudonym,
        !           526:                        .provider_is_reauth = _provider_is_reauth,
        !           527:                        .provider_gen_reauth = _provider_gen_reauth,
        !           528:                        .add_hooks = _add_hooks,
        !           529:                        .remove_hooks = _remove_hooks,
        !           530:                        .message_hook = _message_hook,
        !           531:                        .key_hook = _key_hook,
        !           532:                        .destroy = _destroy,
        !           533:                },
        !           534:                .cards = linked_list_create(),
        !           535:                .providers = linked_list_create(),
        !           536:                .hooks = linked_list_create(),
        !           537:                .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
        !           538:        );
        !           539: 
        !           540:        return &this->public;
        !           541: }
        !           542: 
        !           543: /**
        !           544:  * (Un-)register a provider to a simaka manager
        !           545:  */
        !           546: static bool register_card(char *mgr_name, bool reg, simaka_card_t *card)
        !           547: {
        !           548:        simaka_manager_t *mgr;
        !           549: 
        !           550:        if (!card)
        !           551:        {
        !           552:                return FALSE;
        !           553:        }
        !           554:        mgr = lib->get(lib, mgr_name);
        !           555:        if (mgr)
        !           556:        {
        !           557:                if (reg)
        !           558:                {
        !           559:                        mgr->add_card(mgr, card);
        !           560:                }
        !           561:                else
        !           562:                {
        !           563:                        mgr->remove_card(mgr, card);
        !           564:                }
        !           565:                return TRUE;
        !           566:        }
        !           567:        return FALSE;
        !           568: }
        !           569: 
        !           570: /**
        !           571:  * (Un-)register a provider to a simaka manager
        !           572:  */
        !           573: static bool register_provider(char *mgr_name, bool reg,
        !           574:                                                          simaka_provider_t *provider)
        !           575: {
        !           576:        simaka_manager_t *mgr;
        !           577: 
        !           578:        if (!provider)
        !           579:        {
        !           580:                return FALSE;
        !           581:        }
        !           582:        mgr = lib->get(lib, mgr_name);
        !           583:        if (mgr)
        !           584:        {
        !           585:                if (reg)
        !           586:                {
        !           587:                        mgr->add_provider(mgr, provider);
        !           588:                }
        !           589:                else
        !           590:                {
        !           591:                        mgr->remove_provider(mgr, provider);
        !           592:                }
        !           593:                return TRUE;
        !           594:        }
        !           595:        return FALSE;
        !           596: }
        !           597: 
        !           598: /**
        !           599:  * See header
        !           600:  */
        !           601: bool simaka_manager_register(plugin_t *plugin, plugin_feature_t *feature,
        !           602:                                                         bool reg, void *data)
        !           603: {
        !           604:        simaka_manager_register_cb_t get = (simaka_manager_register_cb_t)data;
        !           605: 
        !           606:        if (feature->type == FEATURE_CUSTOM)
        !           607:        {
        !           608:                if (streq(feature->arg.custom, "aka-card"))
        !           609:                {
        !           610:                        return register_card("aka-manager", reg, get(plugin));
        !           611:                }
        !           612:                else if (streq(feature->arg.custom, "aka-provider"))
        !           613:                {
        !           614:                        return register_provider("aka-manager", reg, get(plugin));
        !           615:                }
        !           616:                else if (streq(feature->arg.custom, "sim-card"))
        !           617:                {
        !           618:                        return register_card("sim-manager", reg, get(plugin));
        !           619:                }
        !           620:                else if (streq(feature->arg.custom, "sim-provider"))
        !           621:                {
        !           622:                        return register_provider("sim-manager", reg, get(plugin));
        !           623:                }
        !           624:        }
        !           625:        return FALSE;
        !           626: }

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