Annotation of embedaddon/strongswan/src/libpttls/sasl/sasl_plain/sasl_plain.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2013 Martin Willi
                      3:  * Copyright (C) 2013 revosec AG
                      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 "sasl_plain.h"
                     17: 
                     18: #include <utils/debug.h>
                     19: 
                     20: typedef struct private_sasl_plain_t private_sasl_plain_t;
                     21: 
                     22: /**
                     23:  * Private data of an sasl_plain_t object.
                     24:  */
                     25: struct private_sasl_plain_t {
                     26: 
                     27:        /**
                     28:         * Public sasl_plain_t interface.
                     29:         */
                     30:        sasl_plain_t public;
                     31: 
                     32:        /**
                     33:         * Client identity
                     34:         */
                     35:        identification_t *client;
                     36: };
                     37: 
                     38: METHOD(sasl_mechanism_t, get_client, identification_t*,
                     39:        private_sasl_plain_t *this)
                     40: {
                     41:        return this->client;
                     42: }
                     43: 
                     44: METHOD(sasl_mechanism_t, get_name, char*,
                     45:        private_sasl_plain_t *this)
                     46: {
                     47:        return "PLAIN";
                     48: }
                     49: 
                     50: METHOD(sasl_mechanism_t, build_server, status_t,
                     51:        private_sasl_plain_t *this, chunk_t *message)
                     52: {
                     53:        /* gets never called */
                     54:        return FAILED;
                     55: }
                     56: 
                     57: METHOD(sasl_mechanism_t, process_server, status_t,
                     58:        private_sasl_plain_t *this, chunk_t message)
                     59: {
                     60:        chunk_t authz, authi, password;
                     61:        shared_key_t *shared;
                     62:        u_char *pos;
                     63: 
                     64:        pos = memchr(message.ptr, 0, message.len);
                     65:        if (!pos)
                     66:        {
                     67:                DBG1(DBG_CFG, "invalid authz encoding");
                     68:                return FAILED;
                     69:        }
                     70:        authz = chunk_create(message.ptr, pos - message.ptr);
                     71:        message = chunk_skip(message, authz.len + 1);
                     72:        pos = memchr(message.ptr, 0, message.len);
                     73:        if (!pos)
                     74:        {
                     75:                DBG1(DBG_CFG, "invalid authi encoding");
                     76:                return FAILED;
                     77:        }
                     78:        authi = chunk_create(message.ptr, pos - message.ptr);
                     79:        password = chunk_skip(message, authi.len + 1);
                     80:        DESTROY_IF(this->client);
                     81:        this->client = identification_create_from_data(authi);
                     82:        shared = lib->credmgr->get_shared(lib->credmgr, SHARED_EAP, this->client,
                     83:                                                                          NULL);
                     84:        if (!shared)
                     85:        {
                     86:                DBG1(DBG_CFG, "no shared secret found for '%Y'", this->client);
                     87:                return FAILED;
                     88:        }
                     89:        if (!chunk_equals_const(shared->get_key(shared), password))
                     90:        {
                     91:                DBG1(DBG_CFG, "shared secret for '%Y' does not match", this->client);
                     92:                shared->destroy(shared);
                     93:                return FAILED;
                     94:        }
                     95:        shared->destroy(shared);
                     96:        return SUCCESS;
                     97: }
                     98: 
                     99: METHOD(sasl_mechanism_t, build_client, status_t,
                    100:        private_sasl_plain_t *this, chunk_t *message)
                    101: {
                    102:        shared_key_t *shared;
                    103:        chunk_t password;
                    104:        char buf[256];
                    105:        ssize_t len;
                    106: 
                    107:        /* we currently use the EAP type of shared secret */
                    108:        shared = lib->credmgr->get_shared(lib->credmgr, SHARED_EAP,
                    109:                                                                          this->client, NULL);
                    110:        if (!shared)
                    111:        {
                    112:                DBG1(DBG_CFG, "no shared secret found for %Y", this->client);
                    113:                return FAILED;
                    114:        }
                    115: 
                    116:        password = shared->get_key(shared);
                    117:        len = snprintf(buf, sizeof(buf), "%s%c%Y%c%.*s",
                    118:                                   "", 0, this->client, 0,
                    119:                                   (int)password.len, password.ptr);
                    120:        shared->destroy(shared);
                    121: 
                    122:        if (len < 0 || len >= sizeof(buf))
                    123:        {
                    124:                return FAILED;
                    125:        }
                    126:        *message = chunk_clone(chunk_create(buf, len));
                    127: 
                    128:        return NEED_MORE;
                    129: }
                    130: 
                    131: METHOD(sasl_mechanism_t, process_client, status_t,
                    132:        private_sasl_plain_t *this, chunk_t message)
                    133: {
                    134:        /* if the server sends a result, authentication successful */
                    135:        return SUCCESS;
                    136: }
                    137: 
                    138: METHOD(sasl_mechanism_t, destroy, void,
                    139:        private_sasl_plain_t *this)
                    140: {
                    141:        DESTROY_IF(this->client);
                    142:        free(this);
                    143: }
                    144: 
                    145: /**
                    146:  * See header
                    147:  */
                    148: sasl_plain_t *sasl_plain_create(char *name, identification_t *client)
                    149: {
                    150:        private_sasl_plain_t *this;
                    151: 
                    152:        if (!streq(get_name(NULL), name))
                    153:        {
                    154:                return NULL;
                    155:        }
                    156: 
                    157:        INIT(this,
                    158:                .public = {
                    159:                        .sasl = {
                    160:                                .get_name = _get_name,
                    161:                                .get_client = _get_client,
                    162:                                .destroy = _destroy,
                    163:                        },
                    164:                },
                    165:        );
                    166: 
                    167:        if (client)
                    168:        {
                    169:                this->public.sasl.build = _build_client;
                    170:                this->public.sasl.process = _process_client;
                    171:                this->client = client->clone(client);
                    172:        }
                    173:        else
                    174:        {
                    175:                this->public.sasl.build = _build_server;
                    176:                this->public.sasl.process = _process_server;
                    177:        }
                    178:        return &this->public;
                    179: }

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