Return to mock_ipsec.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / tests / utils |
1.1 misho 1: /* 2: * Copyright (C) 2016-2017 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 "mock_ipsec.h" 18: 19: #include <daemon.h> 20: #include <collections/hashtable.h> 21: #include <collections/array.h> 22: 23: #include <assert.h> 24: 25: typedef struct private_kernel_ipsec_t private_kernel_ipsec_t; 26: 27: /** 28: * Private data 29: */ 30: struct private_kernel_ipsec_t { 31: 32: /** 33: * Public interface 34: */ 35: kernel_ipsec_t public; 36: 37: /** 38: * Rekey listener 39: */ 40: listener_t listener; 41: 42: /** 43: * Allocated SPI 44: */ 45: refcount_t spi; 46: 47: /** 48: * Installed SAs 49: */ 50: hashtable_t *sas; 51: }; 52: 53: /** 54: * Global instance 55: */ 56: static private_kernel_ipsec_t *instance; 57: 58: /** 59: * Data about installed IPsec SAs 60: */ 61: typedef struct { 62: /** 63: * SPI of the SA 64: */ 65: uint32_t spi; 66: 67: /** 68: * Associated IKE_SA 69: */ 70: ike_sa_t *ike_sa; 71: 72: /** 73: * TRUE if this was an allocated SPI 74: */ 75: bool alloc; 76: 77: } entry_t; 78: 79: /** 80: * Hash an IPsec SA entry 81: */ 82: static u_int entry_hash(const void *key) 83: { 84: entry_t *entry = (entry_t*)key; 85: return chunk_hash_inc(chunk_from_thing(entry->spi), 86: chunk_hash(chunk_from_thing(entry->ike_sa))); 87: } 88: 89: /** 90: * Compare an IPsec SA entry 91: */ 92: static bool entry_equals(const void *key, const void *other_key) 93: { 94: entry_t *a = (entry_t*)key, *b = (entry_t*)other_key; 95: return a->spi == b->spi && a->ike_sa == b->ike_sa; 96: } 97: 98: METHOD(kernel_ipsec_t, get_spi, status_t, 99: private_kernel_ipsec_t *this, host_t *src, host_t *dst, uint8_t protocol, 100: uint32_t *spi) 101: { 102: entry_t *entry; 103: 104: *spi = (uint32_t)ref_get(&this->spi); 105: INIT(entry, 106: .spi = *spi, 107: .ike_sa = charon->bus->get_sa(charon->bus), 108: .alloc = TRUE, 109: ); 110: entry = this->sas->put(this->sas, entry, entry); 111: assert(!entry); 112: return SUCCESS; 113: } 114: 115: METHOD(kernel_ipsec_t, get_cpi, status_t, 116: private_kernel_ipsec_t *this, host_t *src, host_t *dst, uint16_t *cpi) 117: { 118: return FAILED; 119: } 120: 121: METHOD(kernel_ipsec_t, add_sa, status_t, 122: private_kernel_ipsec_t *this, kernel_ipsec_sa_id_t *id, 123: kernel_ipsec_add_sa_t *data) 124: { 125: entry_t *entry; 126: 127: INIT(entry, 128: .spi = id->spi, 129: .ike_sa = charon->bus->get_sa(charon->bus), 130: ); 131: if (data->inbound) 132: { 133: entry = this->sas->put(this->sas, entry, entry); 134: assert(entry && entry->alloc); 135: free(entry); 136: } 137: else 138: { 139: entry = this->sas->put(this->sas, entry, entry); 140: assert(!entry); 141: } 142: return SUCCESS; 143: } 144: 145: METHOD(kernel_ipsec_t, update_sa, status_t, 146: private_kernel_ipsec_t *this, kernel_ipsec_sa_id_t *id, 147: kernel_ipsec_update_sa_t *data) 148: { 149: return SUCCESS; 150: } 151: 152: METHOD(kernel_ipsec_t, query_sa, status_t, 153: private_kernel_ipsec_t *this, kernel_ipsec_sa_id_t *id, 154: kernel_ipsec_query_sa_t *data, uint64_t *bytes, uint64_t *packets, 155: time_t *time) 156: { 157: return NOT_SUPPORTED; 158: } 159: 160: METHOD(kernel_ipsec_t, del_sa, status_t, 161: private_kernel_ipsec_t *this, kernel_ipsec_sa_id_t *id, 162: kernel_ipsec_del_sa_t *data) 163: { 164: entry_t *entry, lookup = { 165: .spi = id->spi, 166: .ike_sa = charon->bus->get_sa(charon->bus), 167: }; 168: 169: entry = this->sas->remove(this->sas, &lookup); 170: assert(entry); 171: free(entry); 172: return SUCCESS; 173: } 174: 175: METHOD(listener_t, ike_rekey, bool, 176: listener_t *listener, ike_sa_t *old, ike_sa_t *new) 177: { 178: enumerator_t *enumerator; 179: array_t *sas = NULL; 180: entry_t *entry; 181: 182: enumerator = instance->sas->create_enumerator(instance->sas); 183: while (enumerator->enumerate(enumerator, &entry, NULL)) 184: { 185: if (entry->ike_sa == old) 186: { 187: instance->sas->remove_at(instance->sas, enumerator); 188: array_insert_create(&sas, ARRAY_TAIL, entry); 189: } 190: } 191: enumerator->destroy(enumerator); 192: enumerator = array_create_enumerator(sas); 193: while (enumerator->enumerate(enumerator, &entry)) 194: { 195: array_remove_at(sas, enumerator); 196: entry->ike_sa = new; 197: entry = instance->sas->put(instance->sas, entry, entry); 198: assert(!entry); 199: } 200: enumerator->destroy(enumerator); 201: array_destroy(sas); 202: return TRUE; 203: } 204: 205: METHOD(kernel_ipsec_t, add_policy, status_t, 206: private_kernel_ipsec_t *this, kernel_ipsec_policy_id_t *id, 207: kernel_ipsec_manage_policy_t *data) 208: { 209: return SUCCESS; 210: } 211: 212: METHOD(kernel_ipsec_t, query_policy, status_t, 213: private_kernel_ipsec_t *this, kernel_ipsec_policy_id_t *id, 214: kernel_ipsec_query_policy_t *data, time_t *use_time) 215: { 216: *use_time = 1; 217: return SUCCESS; 218: } 219: 220: METHOD(kernel_ipsec_t, del_policy, status_t, 221: private_kernel_ipsec_t *this, kernel_ipsec_policy_id_t *id, 222: kernel_ipsec_manage_policy_t *data) 223: { 224: return SUCCESS; 225: } 226: 1.1.1.2 ! misho 227: CALLBACK(destroy_spis, void, ! 228: entry_t *entry, const void* key) ! 229: { ! 230: /* only free allocated SPIs, other SAs that were not properly deleted will ! 231: * cause a leak */ ! 232: if (entry->alloc) ! 233: { ! 234: free(entry); ! 235: } ! 236: } ! 237: 1.1 misho 238: METHOD(kernel_ipsec_t, destroy, void, 239: private_kernel_ipsec_t *this) 240: { 241: charon->bus->remove_listener(charon->bus, &this->listener); 1.1.1.2 ! misho 242: this->sas->destroy_function(this->sas, destroy_spis); 1.1 misho 243: free(this); 244: } 245: 246: /* 247: * Described in header 248: */ 249: kernel_ipsec_t *mock_ipsec_create() 250: { 251: private_kernel_ipsec_t *this; 252: 253: INIT(this, 254: .public = { 255: .get_spi = _get_spi, 256: .get_cpi = _get_cpi, 257: .add_sa = _add_sa, 258: .update_sa = _update_sa, 259: .query_sa = _query_sa, 260: .del_sa = _del_sa, 261: .flush_sas = (void*)return_failed, 262: .add_policy = _add_policy, 263: .query_policy = _query_policy, 264: .del_policy = _del_policy, 265: .flush_policies = (void*)return_failed, 266: .bypass_socket = (void*)return_true, 267: .enable_udp_decap = (void*)return_true, 268: .destroy = _destroy, 269: }, 270: .listener = { 271: .ike_rekey = _ike_rekey, 272: }, 273: .sas = hashtable_create(entry_hash, entry_equals, 8), 274: ); 275: 276: instance = this; 277: 278: charon->bus->add_listener(charon->bus, &this->listener); 279: 280: return &this->public; 281: } 282: 283: 284: CALLBACK(filter_sas, bool, 285: void *data, enumerator_t *orig, va_list args) 286: { 287: entry_t *entry; 288: ike_sa_t **ike_sa; 289: uint32_t *spi; 290: 291: VA_ARGS_VGET(args, ike_sa, spi); 292: 293: while (orig->enumerate(orig, &entry, NULL)) 294: { 295: if (entry->alloc) 296: { 297: continue; 298: } 299: *ike_sa = entry->ike_sa; 300: *spi = entry->spi; 301: return TRUE; 302: } 303: return FALSE; 304: } 305: 306: /* 307: * Described in header 308: */ 309: enumerator_t *mock_ipsec_create_sa_enumerator() 310: { 311: return enumerator_create_filter( 312: instance->sas->create_enumerator(instance->sas), 313: filter_sas, NULL, NULL); 314: }