Return to whitelist_listener.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / whitelist |
1.1 misho 1: /* 2: * Copyright (C) 2011 Martin Willi 3: * Copyright (C) 2011 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 "whitelist_listener.h" 17: 18: #include <daemon.h> 19: #include <collections/hashtable.h> 20: #include <threading/rwlock.h> 21: 22: typedef struct private_whitelist_listener_t private_whitelist_listener_t; 23: 24: /** 25: * Private data of an whitelist_listener_t object. 26: */ 27: struct private_whitelist_listener_t { 28: 29: /** 30: * Public whitelist_listener_t interface. 31: */ 32: whitelist_listener_t public; 33: 34: /** 35: * Lock for hashtable 36: */ 37: rwlock_t *lock; 38: 39: /** 40: * Hashtable with whitelisted identities 41: */ 42: hashtable_t *ids; 43: 44: /** 45: * Whitelist checking enabled 46: */ 47: bool enabled; 48: }; 49: 50: /** 51: * Hashtable hash function 52: */ 53: static u_int hash(identification_t *key) 54: { 55: return key->hash(key, 0); 56: } 57: 58: /** 59: * Hashtable equals function 60: */ 61: static bool equals(identification_t *a, identification_t *b) 62: { 63: return a->equals(a, b); 64: } 65: 66: METHOD(listener_t, authorize, bool, 67: private_whitelist_listener_t *this, ike_sa_t *ike_sa, 68: bool final, bool *success) 69: { 70: /* check each authentication round */ 71: if (this->enabled && !final) 72: { 73: bool whitelisted = FALSE; 74: identification_t *id; 75: auth_cfg_t *auth; 76: 77: auth = ike_sa->get_auth_cfg(ike_sa, FALSE); 78: /* for authenticated with EAP, check EAP identity */ 79: id = auth->get(auth, AUTH_RULE_EAP_IDENTITY); 80: if (!id) 81: { 82: id = auth->get(auth, AUTH_RULE_IDENTITY); 83: } 84: if (id) 85: { 86: this->lock->read_lock(this->lock); 87: whitelisted = this->ids->get(this->ids, id) != NULL; 88: this->lock->unlock(this->lock); 89: } 90: if (whitelisted) 91: { 92: DBG2(DBG_CFG, "peer identity '%Y' whitelisted", id); 93: } 94: else 95: { 96: DBG1(DBG_CFG, "peer identity '%Y' not whitelisted", id); 97: *success = FALSE; 98: } 99: } 100: return TRUE; 101: } 102: 103: METHOD(whitelist_listener_t, add, void, 104: private_whitelist_listener_t *this, identification_t *id) 105: { 106: id = id->clone(id); 107: this->lock->write_lock(this->lock); 108: id = this->ids->put(this->ids, id, id); 109: this->lock->unlock(this->lock); 110: DESTROY_IF(id); 111: } 112: 113: METHOD(whitelist_listener_t, remove_, void, 114: private_whitelist_listener_t *this, identification_t *id) 115: { 116: this->lock->write_lock(this->lock); 117: id = this->ids->remove(this->ids, id); 118: this->lock->unlock(this->lock); 119: DESTROY_IF(id); 120: } 121: 122: CALLBACK(whitelist_filter, bool, 123: rwlock_t *lock, enumerator_t *orig, va_list args) 124: { 125: identification_t *key, *value, **out; 126: 127: VA_ARGS_VGET(args, out); 128: 129: if (orig->enumerate(orig, &key, &value)) 130: { 131: *out = value; 132: return TRUE; 133: } 134: return FALSE; 135: } 136: 137: METHOD(whitelist_listener_t, create_enumerator, enumerator_t*, 138: private_whitelist_listener_t *this) 139: { 140: this->lock->read_lock(this->lock); 141: return enumerator_create_filter(this->ids->create_enumerator(this->ids), 142: whitelist_filter, this->lock, 143: (void*)this->lock->unlock); 144: } 145: 146: METHOD(whitelist_listener_t, flush, void, 147: private_whitelist_listener_t *this, identification_t *id) 148: { 149: enumerator_t *enumerator; 150: identification_t *key, *value; 151: 152: this->lock->write_lock(this->lock); 153: enumerator = this->ids->create_enumerator(this->ids); 154: while (enumerator->enumerate(enumerator, &key, &value)) 155: { 156: if (value->matches(value, id)) 157: { 158: this->ids->remove_at(this->ids, enumerator); 159: value->destroy(value); 160: } 161: } 162: enumerator->destroy(enumerator); 163: this->lock->unlock(this->lock); 164: } 165: 166: METHOD(whitelist_listener_t, set_active, void, 167: private_whitelist_listener_t *this, bool enable) 168: { 169: DBG1(DBG_CFG, "whitelist functionality %s%sabled", 170: (this->enabled == enable) ? "was already " : "", enable ? "en" : "dis"); 171: this->enabled = enable; 172: } 173: 174: METHOD(whitelist_listener_t, destroy, void, 175: private_whitelist_listener_t *this) 176: { 177: identification_t *key, *value; 178: enumerator_t *enumerator; 179: 180: enumerator = this->ids->create_enumerator(this->ids); 181: while (enumerator->enumerate(enumerator, &key, &value)) 182: { 183: value->destroy(value); 184: } 185: enumerator->destroy(enumerator); 186: this->ids->destroy(this->ids); 187: this->lock->destroy(this->lock); 188: free(this); 189: } 190: 191: /** 192: * See header 193: */ 194: whitelist_listener_t *whitelist_listener_create() 195: { 196: private_whitelist_listener_t *this; 197: 198: INIT(this, 199: .public = { 200: .listener = { 201: .authorize = _authorize, 202: }, 203: .add = _add, 204: .remove = _remove_, 205: .create_enumerator = _create_enumerator, 206: .flush = _flush, 207: .set_active = _set_active, 208: .destroy = _destroy, 209: }, 210: .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), 211: .ids = hashtable_create((hashtable_hash_t)hash, 212: (hashtable_equals_t)equals, 32), 213: .enabled = lib->settings->get_bool(lib->settings, 214: "%s.plugins.whitelist.enable", FALSE, lib->ns), 215: ); 216: 217: return &this->public; 218: }