Annotation of embedaddon/strongswan/src/libcharon/plugins/xauth_generic/xauth_generic.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2011 Tobias Brunner
                      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 "xauth_generic.h"
                     17: 
                     18: #include <daemon.h>
                     19: #include <library.h>
                     20: 
                     21: typedef struct private_xauth_generic_t private_xauth_generic_t;
                     22: 
                     23: /**
                     24:  * Private data of an xauth_generic_t object.
                     25:  */
                     26: struct private_xauth_generic_t {
                     27: 
                     28:        /**
                     29:         * Public interface.
                     30:         */
                     31:        xauth_generic_t public;
                     32: 
                     33:        /**
                     34:         * ID of the server
                     35:         */
                     36:        identification_t *server;
                     37: 
                     38:        /**
                     39:         * ID of the peer
                     40:         */
                     41:        identification_t *peer;
                     42: };
                     43: 
                     44: METHOD(xauth_method_t, initiate_peer, status_t,
                     45:        private_xauth_generic_t *this, cp_payload_t **out)
                     46: {
                     47:        /* peer never initiates */
                     48:        return FAILED;
                     49: }
                     50: 
                     51: METHOD(xauth_method_t, process_peer, status_t,
                     52:        private_xauth_generic_t *this, cp_payload_t *in, cp_payload_t **out)
                     53: {
                     54:        configuration_attribute_t *attr;
                     55:        enumerator_t *enumerator;
                     56:        shared_key_t *shared;
                     57:        cp_payload_t *cp;
                     58:        chunk_t msg;
                     59: 
                     60:        enumerator = in->create_attribute_enumerator(in);
                     61:        while (enumerator->enumerate(enumerator, &attr))
                     62:        {
                     63:                if (attr->get_type(attr) == XAUTH_MESSAGE)
                     64:                {
                     65:                        chunk_printable(attr->get_chunk(attr), &msg, '?');
                     66:                        DBG1(DBG_CFG, "XAuth message: %.*s", (int)msg.len, msg.ptr);
                     67:                        free(msg.ptr);
                     68:                }
                     69:        }
                     70:        enumerator->destroy(enumerator);
                     71: 
                     72:        cp = cp_payload_create_type(PLV1_CONFIGURATION, CFG_REPLY);
                     73: 
                     74:        enumerator = in->create_attribute_enumerator(in);
                     75:        while (enumerator->enumerate(enumerator, &attr))
                     76:        {
                     77:                shared_key_type_t type = SHARED_EAP;
                     78: 
                     79:                switch (attr->get_type(attr))
                     80:                {
                     81:                        case XAUTH_USER_NAME:
                     82:                                cp->add_attribute(cp, configuration_attribute_create_chunk(
                     83:                                                        PLV1_CONFIGURATION_ATTRIBUTE, XAUTH_USER_NAME,
                     84:                                                        this->peer->get_encoding(this->peer)));
                     85:                                break;
                     86:                        case XAUTH_NEXT_PIN:
                     87:                                type = SHARED_PIN;
                     88:                                /* FALL */
                     89:                        case XAUTH_USER_PASSWORD:
                     90:                                shared = lib->credmgr->get_shared(lib->credmgr, type,
                     91:                                                                                                  this->peer, this->server);
                     92:                                if (!shared)
                     93:                                {
                     94:                                        DBG1(DBG_IKE, "no XAuth %s found for '%Y' - '%Y'",
                     95:                                                 type == SHARED_EAP ? "password" : "PIN",
                     96:                                                 this->peer, this->server);
                     97:                                        enumerator->destroy(enumerator);
                     98:                                        cp->destroy(cp);
                     99:                                        return FAILED;
                    100:                                }
                    101:                                cp->add_attribute(cp, configuration_attribute_create_chunk(
                    102:                                                        PLV1_CONFIGURATION_ATTRIBUTE, attr->get_type(attr),
                    103:                                                        shared->get_key(shared)));
                    104:                                shared->destroy(shared);
                    105:                                break;
                    106:                        default:
                    107:                                break;
                    108:                }
                    109:        }
                    110:        enumerator->destroy(enumerator);
                    111: 
                    112:        *out = cp;
                    113:        return NEED_MORE;
                    114: }
                    115: 
                    116: METHOD(xauth_method_t, initiate_server, status_t,
                    117:        private_xauth_generic_t *this, cp_payload_t **out)
                    118: {
                    119:        cp_payload_t *cp;
                    120: 
                    121:        cp = cp_payload_create_type(PLV1_CONFIGURATION, CFG_REQUEST);
                    122:        cp->add_attribute(cp, configuration_attribute_create_chunk(
                    123:                                PLV1_CONFIGURATION_ATTRIBUTE, XAUTH_USER_NAME, chunk_empty));
                    124:        cp->add_attribute(cp, configuration_attribute_create_chunk(
                    125:                                PLV1_CONFIGURATION_ATTRIBUTE, XAUTH_USER_PASSWORD, chunk_empty));
                    126:        *out = cp;
                    127:        return NEED_MORE;
                    128: }
                    129: 
                    130: METHOD(xauth_method_t, process_server, status_t,
                    131:        private_xauth_generic_t *this, cp_payload_t *in, cp_payload_t **out)
                    132: {
                    133:        configuration_attribute_t *attr;
                    134:        enumerator_t *enumerator;
                    135:        shared_key_t *shared;
                    136:        identification_t *id;
                    137:        chunk_t user = chunk_empty, pass = chunk_empty;
                    138:        status_t status = FAILED;
                    139:        int tried = 0;
                    140: 
                    141:        enumerator = in->create_attribute_enumerator(in);
                    142:        while (enumerator->enumerate(enumerator, &attr))
                    143:        {
                    144:                switch (attr->get_type(attr))
                    145:                {
                    146:                        case XAUTH_USER_NAME:
                    147:                                user = attr->get_chunk(attr);
                    148:                                break;
                    149:                        case XAUTH_USER_PASSWORD:
                    150:                                pass = attr->get_chunk(attr);
                    151:                                break;
                    152:                        default:
                    153:                                break;
                    154:                }
                    155:        }
                    156:        enumerator->destroy(enumerator);
                    157: 
                    158:        if (!user.ptr || !pass.ptr)
                    159:        {
                    160:                DBG1(DBG_IKE, "peer did not respond to our XAuth request");
                    161:                return FAILED;
                    162:        }
                    163:        if (user.len)
                    164:        {
                    165:                id = identification_create_from_data(user);
                    166:                if (!id)
                    167:                {
                    168:                        DBG1(DBG_IKE, "failed to parse provided XAuth username");
                    169:                        return FAILED;
                    170:                }
                    171:                this->peer->destroy(this->peer);
                    172:                this->peer = id;
                    173:        }
                    174:        if (pass.len && pass.ptr[pass.len - 1] == 0)
                    175:        {       /* fix null-terminated passwords (Android etc.) */
                    176:                pass.len -= 1;
                    177:        }
                    178: 
                    179:        enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
                    180:                                                                                SHARED_EAP, this->server, this->peer);
                    181:        while (enumerator->enumerate(enumerator, &shared, NULL, NULL))
                    182:        {
                    183:                if (chunk_equals_const(shared->get_key(shared), pass))
                    184:                {
                    185:                        status = SUCCESS;
                    186:                        break;
                    187:                }
                    188:                tried++;
                    189:        }
                    190:        enumerator->destroy(enumerator);
                    191:        if (status != SUCCESS)
                    192:        {
                    193:                if (!tried)
                    194:                {
                    195:                        DBG1(DBG_IKE, "no XAuth secret found for '%Y' - '%Y'",
                    196:                                 this->server, this->peer);
                    197:                }
                    198:                else
                    199:                {
                    200:                        DBG1(DBG_IKE, "none of %d found XAuth secrets for '%Y' - '%Y' "
                    201:                                 "matched", tried, this->server, this->peer);
                    202:                }
                    203:        }
                    204:        return status;
                    205: }
                    206: 
                    207: METHOD(xauth_method_t, get_identity, identification_t*,
                    208:        private_xauth_generic_t *this)
                    209: {
                    210:        return this->peer;
                    211: }
                    212: 
                    213: METHOD(xauth_method_t, destroy, void,
                    214:        private_xauth_generic_t *this)
                    215: {
                    216:        this->server->destroy(this->server);
                    217:        this->peer->destroy(this->peer);
                    218:        free(this);
                    219: }
                    220: 
                    221: /*
                    222:  * Described in header.
                    223:  */
                    224: xauth_generic_t *xauth_generic_create_peer(identification_t *server,
                    225:                                                                                   identification_t *peer,
                    226:                                                                                   char *profile)
                    227: {
                    228:        private_xauth_generic_t *this;
                    229: 
                    230:        INIT(this,
                    231:                .public =  {
                    232:                        .xauth_method = {
                    233:                                .initiate = _initiate_peer,
                    234:                                .process = _process_peer,
                    235:                                .get_identity = _get_identity,
                    236:                                .destroy = _destroy,
                    237:                        },
                    238:                },
                    239:                .server = server->clone(server),
                    240:                .peer = peer->clone(peer),
                    241:        );
                    242: 
                    243:        return &this->public;
                    244: }
                    245: 
                    246: /*
                    247:  * Described in header.
                    248:  */
                    249: xauth_generic_t *xauth_generic_create_server(identification_t *server,
                    250:                                                                                         identification_t *peer,
                    251:                                                                                         char *profile)
                    252: {
                    253:        private_xauth_generic_t *this;
                    254: 
                    255:        INIT(this,
                    256:                .public = {
                    257:                        .xauth_method = {
                    258:                                .initiate = _initiate_server,
                    259:                                .process = _process_server,
                    260:                                .get_identity = _get_identity,
                    261:                                .destroy = _destroy,
                    262:                        },
                    263:                },
                    264:                .server = server->clone(server),
                    265:                .peer = peer->clone(peer),
                    266:        );
                    267: 
                    268:        return &this->public;
                    269: }

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