Annotation of embedaddon/strongswan/src/libcharon/plugins/sql/sql_cred.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2010-2019 Tobias Brunner
3: * Copyright (C) 2008 Martin Willi
4: * HSR Hochschule fuer Technik Rapperswil
5: *
6: * This program is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2 of the License, or (at your
9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10: *
11: * This program is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14: * for more details.
15: */
16:
17: #include <string.h>
18:
19: #include "sql_cred.h"
20:
21: #include <daemon.h>
22:
23: typedef struct private_sql_cred_t private_sql_cred_t;
24:
25: /**
26: * Private data of an sql_cred_t object
27: */
28: struct private_sql_cred_t {
29:
30: /**
31: * Public part
32: */
33: sql_cred_t public;
34:
35: /**
36: * database connection
37: */
38: database_t *db;
39: };
40:
41:
42: /**
43: * enumerator over private keys
44: */
45: typedef struct {
46: /** implements enumerator */
47: enumerator_t public;
48: /** inner SQL enumerator */
49: enumerator_t *inner;
50: /** currently enumerated private key */
51: private_key_t *current;
52: } private_enumerator_t;
53:
54: METHOD(enumerator_t, private_enumerator_enumerate, bool,
55: private_enumerator_t *this, va_list args)
56: {
57: private_key_t **key;
58: chunk_t blob;
59: int type;
60:
61: VA_ARGS_VGET(args, key);
62:
63: DESTROY_IF(this->current);
64: while (this->inner->enumerate(this->inner, &type, &blob))
65: {
66: this->current = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
67: BUILD_BLOB_PEM, blob,
68: BUILD_END);
69: if (this->current)
70: {
71: *key = this->current;
72: return TRUE;
73: }
74: }
75: this->current = NULL;
76: return FALSE;
77: }
78:
79: METHOD(enumerator_t, private_enumerator_destroy, void,
80: private_enumerator_t *this)
81: {
82: DESTROY_IF(this->current);
83: this->inner->destroy(this->inner);
84: free(this);
85: }
86:
87: METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
88: private_sql_cred_t *this, key_type_t type, identification_t *id)
89: {
90: private_enumerator_t *e;
91:
92: INIT(e,
93: .public = {
94: .enumerate = enumerator_enumerate_default,
95: .venumerate = _private_enumerator_enumerate,
96: .destroy = _private_enumerator_destroy,
97: },
98: );
99: if (id && id->get_type(id) != ID_ANY)
100: {
101: e->inner = this->db->query(this->db,
102: "SELECT p.type, p.data FROM private_keys AS p "
103: "JOIN private_key_identity AS pi ON p.id = pi.private_key "
104: "JOIN identities AS i ON pi.identity = i.id "
105: "WHERE i.type = ? AND i.data = ? AND (? OR p.type = ?)",
106: DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id),
107: DB_INT, type == KEY_ANY, DB_INT, type,
108: DB_INT, DB_BLOB);
109: }
110: else
111: {
112: e->inner = this->db->query(this->db,
113: "SELECT p.type, p.data FROM private_keys AS p "
114: "WHERE (? OR p.type = ?)",
115: DB_INT, type == KEY_ANY, DB_INT, type,
116: DB_INT, DB_BLOB);
117: }
118: if (!e->inner)
119: {
120: free(e);
121: return NULL;
122: }
123: return &e->public;
124: }
125:
126:
127: /**
128: * enumerator over certificates
129: */
130: typedef struct {
131: /** implements enumerator */
132: enumerator_t public;
133: /** inner SQL enumerator */
134: enumerator_t *inner;
135: /** currently enumerated cert */
136: certificate_t *current;
137: } cert_enumerator_t;
138:
139: METHOD(enumerator_t, cert_enumerator_enumerate, bool,
140: cert_enumerator_t *this, va_list args)
141: {
142: certificate_t **cert;
143: chunk_t blob;
144: int type;
145:
146: VA_ARGS_VGET(args, cert);
147:
148: DESTROY_IF(this->current);
149: while (this->inner->enumerate(this->inner, &type, &blob))
150: {
151: this->current = lib->creds->create(lib->creds, CRED_CERTIFICATE, type,
152: BUILD_BLOB_PEM, blob,
153: BUILD_END);
154: if (this->current)
155: {
156: *cert = this->current;
157: return TRUE;
158: }
159: }
160: this->current = NULL;
161: return FALSE;
162: }
163:
164: METHOD(enumerator_t, cert_enumerator_destroy, void,
165: cert_enumerator_t *this)
166: {
167: DESTROY_IF(this->current);
168: this->inner->destroy(this->inner);
169: free(this);
170: }
171:
172: METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
173: private_sql_cred_t *this, certificate_type_t cert, key_type_t key,
174: identification_t *id, bool trusted)
175: {
176: cert_enumerator_t *e;
177:
178: INIT(e,
179: .public = {
180: .enumerate = enumerator_enumerate_default,
181: .venumerate = _cert_enumerator_enumerate,
182: .destroy = _cert_enumerator_destroy,
183: },
184: );
185: if (id && id->get_type(id) != ID_ANY)
186: {
187: e->inner = this->db->query(this->db,
188: "SELECT c.type, c.data FROM certificates AS c "
189: "JOIN certificate_identity AS ci ON c.id = ci.certificate "
190: "JOIN identities AS i ON ci.identity = i.id "
191: "WHERE i.type = ? AND i.data = ? AND "
192: "(? OR c.type = ?) AND (? OR c.keytype = ?)",
193: DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id),
194: DB_INT, cert == CERT_ANY, DB_INT, cert,
195: DB_INT, key == KEY_ANY, DB_INT, key,
196: DB_INT, DB_BLOB);
197: }
198: else
199: {
200: e->inner = this->db->query(this->db,
201: "SELECT c.type, c.data FROM certificates AS c WHERE "
202: "(? OR c.type = ?) AND (? OR c.keytype = ?)",
203: DB_INT, cert == CERT_ANY, DB_INT, cert,
204: DB_INT, key == KEY_ANY, DB_INT, key,
205: DB_INT, DB_BLOB);
206: }
207: if (!e->inner)
208: {
209: free(e);
210: return NULL;
211: }
212: return &e->public;
213: }
214:
215:
216: /**
217: * enumerator over shared keys
218: */
219: typedef struct {
220: /** implements enumerator */
221: enumerator_t public;
222: /** inner SQL enumerator */
223: enumerator_t *inner;
224: /** own identity is defined */
225: bool me_defined;
226: /** remote identity is defined */
227: bool other_defined;
228: /** currently enumerated private key */
229: shared_key_t *current;
230: } shared_enumerator_t;
231:
232: METHOD(enumerator_t, shared_enumerator_enumerate, bool,
233: shared_enumerator_t *this, va_list args)
234: {
235: shared_key_t **shared;
236: id_match_t *me, *other;
237: chunk_t blob;
238: int type;
239:
240: VA_ARGS_VGET(args, shared, me, other);
241:
242: DESTROY_IF(this->current);
243: while (this->inner->enumerate(this->inner, &type, &blob))
244: {
245: this->current = shared_key_create(type, chunk_clone(blob));
246: if (this->current)
247: {
248: *shared = this->current;
249: if (me)
250: {
251: *me = this->me_defined ? ID_MATCH_PERFECT : ID_MATCH_ANY;
252: }
253: if (other)
254: {
255: *other = this->other_defined ? ID_MATCH_PERFECT : ID_MATCH_ANY;
256: }
257: return TRUE;
258: }
259: }
260: this->current = NULL;
261: return FALSE;
262: }
263:
264: METHOD(enumerator_t, shared_enumerator_destroy, void,
265: shared_enumerator_t *this)
266: {
267: DESTROY_IF(this->current);
268: this->inner->destroy(this->inner);
269: free(this);
270: }
271:
272: METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
273: private_sql_cred_t *this, shared_key_type_t type,
274: identification_t *me, identification_t *other)
275: {
276: shared_enumerator_t *e;
277: bool me_defined, other_defined;
278:
279: me_defined = me && me->get_type(me) != ID_ANY;
280: other_defined = other && other->get_type(other) != ID_ANY;
281:
282: INIT(e,
283: .public = {
284: .enumerate = enumerator_enumerate_default,
285: .venumerate = _shared_enumerator_enumerate,
286: .destroy = _shared_enumerator_destroy,
287: },
288: .me_defined = me_defined,
289: .other_defined = other_defined,
290: );
291: if (!me_defined && !other_defined)
292: {
293: e->inner = this->db->query(this->db,
294: "SELECT s.type, s.data FROM shared_secrets AS s "
295: "WHERE (? OR s.type = ?)",
296: DB_INT, type == SHARED_ANY, DB_INT, type,
297: DB_INT, DB_BLOB);
298: }
299: else if (me_defined && other_defined)
300: {
301: e->inner = this->db->query(this->db,
302: "SELECT s.type, s.data FROM shared_secrets AS s "
303: "JOIN shared_secret_identity AS sm ON s.id = sm.shared_secret "
304: "JOIN identities AS m ON sm.identity = m.id "
305: "JOIN shared_secret_identity AS so ON s.id = so.shared_secret "
306: "JOIN identities AS o ON so.identity = o.id "
307: "WHERE m.type = ? AND m.data = ? AND o.type = ? AND o.data = ? "
308: "AND (? OR s.type = ?)",
309: DB_INT, me->get_type(me), DB_BLOB, me->get_encoding(me),
310: DB_INT, other->get_type(other), DB_BLOB, other->get_encoding(other),
311: DB_INT, type == SHARED_ANY, DB_INT, type,
312: DB_INT, DB_BLOB);
313: }
314: else
315: {
316: identification_t *id = me_defined ? me : other;
317:
318: e->inner = this->db->query(this->db,
319: "SELECT s.type, s.data FROM shared_secrets AS s "
320: "JOIN shared_secret_identity AS si ON s.id = si.shared_secret "
321: "JOIN identities AS i ON si.identity = i.id "
322: "WHERE i.type = ? AND i.data = ? AND (? OR s.type = ?)",
323: DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id),
324: DB_INT, type == SHARED_ANY, DB_INT, type,
325: DB_INT, DB_BLOB);
326: }
327: if (!e->inner)
328: {
329: free(e);
330: return NULL;
331: }
332: return &e->public;
333: }
334:
335:
336: /**
337: * enumerator over CDPs
338: */
339: typedef struct {
340: /** implements enumerator_t */
341: enumerator_t public;
342: /** inner SQL enumerator */
343: enumerator_t *inner;
344: /** currently enumerated string */
345: char *current;
346: } cdp_enumerator_t;
347:
348: /**
349: * types of CDPs
350: */
351: typedef enum {
352: /** any available CDP */
353: CDP_TYPE_ANY = 0,
354: /** CRL */
355: CDP_TYPE_CRL,
356: /** OCSP Responder */
357: CDP_TYPE_OCSP,
358: } cdp_type_t;
359:
360: METHOD(enumerator_t, cdp_enumerator_enumerate, bool,
361: cdp_enumerator_t *this, va_list args)
362: {
363: char *text, **uri;
364:
365: VA_ARGS_VGET(args, uri);
366:
367: free(this->current);
368: while (this->inner->enumerate(this->inner, &text))
369: {
370: *uri = this->current = strdup(text);
371: return TRUE;
372: }
373: this->current = NULL;
374: return FALSE;
375: }
376:
377: METHOD(enumerator_t, cdp_enumerator_destroy, void,
378: cdp_enumerator_t *this)
379: {
380: free(this->current);
381: this->inner->destroy(this->inner);
382: free(this);
383: }
384:
385: METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*,
386: private_sql_cred_t *this, certificate_type_t type, identification_t *id)
387: {
388: cdp_enumerator_t *e;
389: cdp_type_t cdp_type;
390:
391: switch (type)
392: { /* we serve CRLs and OCSP responders */
393: case CERT_X509_CRL:
394: cdp_type = CDP_TYPE_CRL;
395: break;
396: case CERT_X509_OCSP_RESPONSE:
397: cdp_type = CDP_TYPE_OCSP;
398: break;
399: case CERT_ANY:
400: cdp_type = CDP_TYPE_ANY;
401: break;
402: default:
403: return NULL;
404: }
405: INIT(e,
406: .public = {
407: .enumerate = enumerator_enumerate_default,
408: .venumerate = _cdp_enumerator_enumerate,
409: .destroy = _cdp_enumerator_destroy,
410: },
411: );
412: if (id && id->get_type(id) != ID_ANY)
413: {
414: e->inner = this->db->query(this->db,
415: "SELECT dp.uri FROM certificate_distribution_points AS dp "
416: "JOIN certificate_authorities AS ca ON ca.id = dp.ca "
417: "JOIN certificates AS c ON c.id = ca.certificate "
418: "JOIN certificate_identity AS ci ON c.id = ci.certificate "
419: "JOIN identities AS i ON ci.identity = i.id "
420: "WHERE i.type = ? AND i.data = ? AND (? OR dp.type = ?)",
421: DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id),
422: DB_INT, cdp_type == CDP_TYPE_ANY, DB_INT, cdp_type,
423: DB_TEXT);
424: }
425: else
426: {
427: e->inner = this->db->query(this->db,
428: "SELECT dp.uri FROM certificate_distribution_points AS dp "
429: "WHERE (? OR dp.type = ?)",
430: DB_INT, cdp_type == CDP_TYPE_ANY, DB_INT, cdp_type,
431: DB_TEXT);
432: }
433: if (!e->inner)
434: {
435: free(e);
436: return NULL;
437: }
438: return &e->public;
439: }
440:
441: METHOD(credential_set_t, cache_cert, void,
442: private_sql_cred_t *this, certificate_t *cert)
443: {
444: /* TODO: implement CRL caching to database */
445: }
446:
447: METHOD(sql_cred_t, destroy, void,
448: private_sql_cred_t *this)
449: {
450: free(this);
451: }
452:
453: /**
454: * Described in header.
455: */
456: sql_cred_t *sql_cred_create(database_t *db)
457: {
458: private_sql_cred_t *this;
459:
460: INIT(this,
461: .public = {
462: .set = {
463: .create_private_enumerator = _create_private_enumerator,
464: .create_cert_enumerator = _create_cert_enumerator,
465: .create_shared_enumerator = _create_shared_enumerator,
466: .create_cdp_enumerator = _create_cdp_enumerator,
467: .cache_cert = _cache_cert,
468: },
469: .destroy = _destroy,
470: },
471: .db = db,
472: );
473:
474: return &this->public;
475: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>