Annotation of embedaddon/strongswan/src/libradius/radius_client.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2009 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 "radius_client.h"
                     17: #include "radius_config.h"
                     18: 
                     19: #include <unistd.h>
                     20: #include <errno.h>
                     21: 
                     22: #include <utils/debug.h>
                     23: #include <networking/host.h>
                     24: #include <collections/linked_list.h>
                     25: #include <threading/condvar.h>
                     26: #include <threading/mutex.h>
                     27: 
                     28: typedef struct private_radius_client_t private_radius_client_t;
                     29: 
                     30: /**
                     31:  * Private data of an radius_client_t object.
                     32:  */
                     33: struct private_radius_client_t {
                     34: 
                     35:        /**
                     36:         * Public radius_client_t interface.
                     37:         */
                     38:        radius_client_t public;
                     39: 
                     40:        /**
                     41:         * Selected RADIUS server configuration
                     42:         */
                     43:        radius_config_t *config;
                     44: 
                     45:        /**
                     46:         * RADIUS servers State attribute
                     47:         */
                     48:        chunk_t state;
                     49: 
                     50:        /**
                     51:         * EAP MSK, from MPPE keys
                     52:         */
                     53:        chunk_t msk;
                     54: };
                     55: 
                     56: /**
                     57:  * Save the state attribute to include in further request
                     58:  */
                     59: static void save_state(private_radius_client_t *this, radius_message_t *msg)
                     60: {
                     61:        enumerator_t *enumerator;
                     62:        int type;
                     63:        chunk_t data;
                     64: 
                     65:        enumerator = msg->create_enumerator(msg);
                     66:        while (enumerator->enumerate(enumerator, &type, &data))
                     67:        {
                     68:                if (type == RAT_STATE)
                     69:                {
                     70:                        free(this->state.ptr);
                     71:                        this->state = chunk_clone(data);
                     72:                        enumerator->destroy(enumerator);
                     73:                        return;
                     74:                }
                     75:        }
                     76:        enumerator->destroy(enumerator);
                     77:        /* no state attribute found, remove state */
                     78:        chunk_free(&this->state);
                     79: }
                     80: 
                     81: METHOD(radius_client_t, request, radius_message_t*,
                     82:        private_radius_client_t *this, radius_message_t *req)
                     83: {
                     84:        radius_socket_t *socket;
                     85:        radius_message_t *res;
                     86:        chunk_t data;
                     87: 
                     88:        /* add our NAS-Identifier */
                     89:        req->add(req, RAT_NAS_IDENTIFIER,
                     90:                         this->config->get_nas_identifier(this->config));
                     91:        /* add State attribute, if server sent one */
                     92:        if (this->state.ptr)
                     93:        {
                     94:                req->add(req, RAT_STATE, this->state);
                     95:        }
                     96:        socket = this->config->get_socket(this->config);
                     97:        DBG1(DBG_CFG, "sending RADIUS %N to server '%s'", radius_message_code_names,
                     98:                 req->get_code(req), this->config->get_name(this->config));
                     99: 
                    100:        res = socket->request(socket, req);
                    101:        if (res)
                    102:        {
                    103:                DBG1(DBG_CFG, "received RADIUS %N from server '%s'",
                    104:                         radius_message_code_names, res->get_code(res),
                    105:                         this->config->get_name(this->config));
                    106:                data = res->get_encoding(res);
                    107:                DBG3(DBG_CFG, "%B", &data);
                    108: 
                    109:                save_state(this, res);
                    110:                if (res->get_code(res) == RMC_ACCESS_ACCEPT)
                    111:                {
                    112:                        chunk_clear(&this->msk);
                    113:                        this->msk = socket->decrypt_msk(socket, req, res);
                    114:                }
                    115:                this->config->put_socket(this->config, socket, TRUE);
                    116:                return res;
                    117:        }
                    118:        this->config->put_socket(this->config, socket, FALSE);
                    119:        return NULL;
                    120: }
                    121: 
                    122: METHOD(radius_client_t, get_msk, chunk_t,
                    123:        private_radius_client_t *this)
                    124: {
                    125:        return this->msk;
                    126: }
                    127: 
                    128: METHOD(radius_client_t, destroy, void,
                    129:        private_radius_client_t *this)
                    130: {
                    131:        this->config->destroy(this->config);
                    132:        chunk_clear(&this->msk);
                    133:        free(this->state.ptr);
                    134:        free(this);
                    135: }
                    136: 
                    137: /**
                    138:  * See header
                    139:  */
                    140: radius_client_t *radius_client_create(radius_config_t *config)
                    141: {
                    142:        private_radius_client_t *this;
                    143: 
                    144:        INIT(this,
                    145:                .public = {
                    146:                        .request = _request,
                    147:                        .get_msk = _get_msk,
                    148:                        .destroy = _destroy,
                    149:                },
                    150:                .config = config,
                    151:        );
                    152: 
                    153:        return &this->public;
                    154: }

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