Annotation of embedaddon/strongswan/src/libpttls/sasl/sasl_plain/sasl_plain.c, revision 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>