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>