Annotation of embedaddon/strongswan/src/libcharon/plugins/sql/sql_cred.c, revision 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>