Return to ha_tunnel.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / ha |
1.1 misho 1: /* 2: * Copyright (C) 2009 Martin Willi 3: * HSR Hochschule fuer Technik Rapperswil 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 "ha_tunnel.h" 17: #include "ha_plugin.h" 18: 19: #include <daemon.h> 20: #include <utils/identification.h> 21: #include <processing/jobs/callback_job.h> 22: 23: #define HA_CFG_NAME "ha" 24: 25: typedef struct private_ha_tunnel_t private_ha_tunnel_t; 26: typedef struct ha_backend_t ha_backend_t; 27: typedef struct ha_creds_t ha_creds_t; 28: 29: /** 30: * Serves credentials for the HA SA 31: */ 32: struct ha_creds_t { 33: 34: /** 35: * Implements credential_set_t 36: */ 37: credential_set_t public; 38: 39: /** 40: * own identity 41: */ 42: identification_t *local; 43: 44: /** 45: * peer identity 46: */ 47: identification_t *remote; 48: 49: /** 50: * Shared key to serve 51: */ 52: shared_key_t *key; 53: }; 54: 55: /** 56: * Serves configurations for the HA SA 57: */ 58: struct ha_backend_t { 59: 60: /** 61: * Implements backend_t 62: */ 63: backend_t public; 64: 65: /** 66: * peer config we serve 67: */ 68: peer_cfg_t *cfg; 69: }; 70: 71: /** 72: * Private data of an ha_tunnel_t object. 73: */ 74: struct private_ha_tunnel_t { 75: 76: /** 77: * Public ha_tunnel_t interface. 78: */ 79: ha_tunnel_t public; 80: 81: /** 82: * Reqid of installed trap 83: */ 84: uint32_t trap; 85: 86: /** 87: * backend for HA SA 88: */ 89: ha_backend_t backend; 90: 91: /** 92: * credential set for HA SA 93: */ 94: ha_creds_t creds; 95: }; 96: 97: METHOD(ha_tunnel_t, is_sa, bool, 98: private_ha_tunnel_t *this, ike_sa_t *ike_sa) 99: { 100: peer_cfg_t *cfg = this->backend.cfg; 101: 102: return cfg && ike_sa->get_ike_cfg(ike_sa) == cfg->get_ike_cfg(cfg); 103: } 104: 105: /** 106: * Enumerator over HA shared_key 107: */ 108: typedef struct { 109: /** Implements enumerator_t */ 110: enumerator_t public; 111: /** a single secret we serve */ 112: shared_key_t *key; 113: } shared_enum_t; 114: 115: METHOD(enumerator_t, shared_enumerate, bool, 116: shared_enum_t *this, va_list args) 117: { 118: shared_key_t **key; 119: id_match_t *me, *other; 120: 121: VA_ARGS_VGET(args, key, me, other); 122: if (this->key) 123: { 124: if (me) 125: { 126: *me = ID_MATCH_PERFECT; 127: } 128: if (other) 129: { 130: *other = ID_MATCH_PERFECT; 131: } 132: *key = this->key; 133: this->key = NULL; 134: return TRUE; 135: } 136: return FALSE; 137: } 138: 139: METHOD(ha_creds_t, create_shared_enumerator, enumerator_t*, 140: ha_creds_t *this, shared_key_type_t type, 141: identification_t *me, identification_t *other) 142: { 143: shared_enum_t *enumerator; 144: 145: if (type != SHARED_IKE && type != SHARED_ANY) 146: { 147: return NULL; 148: } 149: if (me && !me->equals(me, this->local)) 150: { 151: return NULL; 152: } 153: if (other && !other->equals(other, this->remote)) 154: { 155: return NULL; 156: } 157: 158: INIT(enumerator, 159: .public = { 160: .enumerate = enumerator_enumerate_default, 161: .venumerate = _shared_enumerate, 162: .destroy = (void*)free, 163: }, 164: .key = this->key, 165: ); 166: 167: return &enumerator->public; 168: } 169: 170: METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, 171: ha_backend_t *this, identification_t *me, identification_t *other) 172: { 173: return enumerator_create_single(this->cfg, NULL); 174: } 175: 176: METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, 177: ha_backend_t *this, host_t *me, host_t *other) 178: { 179: return enumerator_create_single(this->cfg->get_ike_cfg(this->cfg), NULL); 180: } 181: 182: /** 183: * Install configs and a a trap for secured HA message exchange 184: */ 185: static void setup_tunnel(private_ha_tunnel_t *this, 186: char *local, char *remote, char *secret) 187: { 188: peer_cfg_t *peer_cfg; 189: ike_cfg_t *ike_cfg; 190: auth_cfg_t *auth_cfg; 191: child_cfg_t *child_cfg; 192: traffic_selector_t *ts; 193: ike_cfg_create_t ike = { 194: .version = IKEV2, 195: .local = local, 196: .local_port = charon->socket->get_port(charon->socket, FALSE), 197: .remote = remote, 198: .remote_port = IKEV2_UDP_PORT, 199: .no_certreq = TRUE, 200: }; 201: peer_cfg_create_t peer = { 202: .cert_policy = CERT_NEVER_SEND, 203: .unique = UNIQUE_KEEP, 204: .rekey_time = 86400, /* 24h */ 205: .jitter_time = 7200, /* 2h */ 206: .over_time = 3600, /* 1h */ 207: .no_mobike = TRUE, 208: .dpd = 30, 209: }; 210: child_cfg_create_t child = { 211: .lifetime = { 212: .time = { 213: .life = 21600, .rekey = 20400, .jitter = 400, 214: }, 215: }, 216: .mode = MODE_TRANSPORT, 217: }; 218: 219: /* setup credentials */ 220: this->creds.local = identification_create_from_string(local); 221: this->creds.remote = identification_create_from_string(remote); 222: this->creds.key = shared_key_create(SHARED_IKE, 223: chunk_clone(chunk_create(secret, strlen(secret)))); 224: this->creds.public.create_private_enumerator = (void*)return_null; 225: this->creds.public.create_cert_enumerator = (void*)return_null; 226: this->creds.public.create_shared_enumerator = (void*)_create_shared_enumerator; 227: this->creds.public.create_cdp_enumerator = (void*)return_null; 228: this->creds.public.cache_cert = (void*)nop; 229: 230: lib->credmgr->add_set(lib->credmgr, &this->creds.public); 231: 232: /* create config and backend */ 233: ike_cfg = ike_cfg_create(&ike); 234: ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE)); 235: ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE)); 236: peer_cfg = peer_cfg_create(HA_CFG_NAME, ike_cfg, &peer); 237: 238: auth_cfg = auth_cfg_create(); 239: auth_cfg->add(auth_cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK); 240: auth_cfg->add(auth_cfg, AUTH_RULE_IDENTITY, 241: identification_create_from_string(local)); 242: peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, TRUE); 243: 244: auth_cfg = auth_cfg_create(); 245: auth_cfg->add(auth_cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK); 246: auth_cfg->add(auth_cfg, AUTH_RULE_IDENTITY, 247: identification_create_from_string(remote)); 248: peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, FALSE); 249: 250: child_cfg = child_cfg_create(HA_CFG_NAME, &child); 251: ts = traffic_selector_create_dynamic(IPPROTO_UDP, HA_PORT, HA_PORT); 252: child_cfg->add_traffic_selector(child_cfg, TRUE, ts); 253: ts = traffic_selector_create_dynamic(IPPROTO_ICMP, 0, 65535); 254: child_cfg->add_traffic_selector(child_cfg, TRUE, ts); 255: ts = traffic_selector_create_dynamic(IPPROTO_UDP, HA_PORT, HA_PORT); 256: child_cfg->add_traffic_selector(child_cfg, FALSE, ts); 257: ts = traffic_selector_create_dynamic(IPPROTO_ICMP, 0, 65535); 258: child_cfg->add_traffic_selector(child_cfg, FALSE, ts); 259: child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP)); 260: child_cfg->add_proposal(child_cfg, proposal_create_default_aead(PROTO_ESP)); 261: peer_cfg->add_child_cfg(peer_cfg, child_cfg); 262: 263: this->backend.cfg = peer_cfg; 264: this->backend.public.create_peer_cfg_enumerator = (void*)_create_peer_cfg_enumerator; 265: this->backend.public.create_ike_cfg_enumerator = (void*)_create_ike_cfg_enumerator; 266: this->backend.public.get_peer_cfg_by_name = (void*)return_null; 267: 268: charon->backends->add_backend(charon->backends, &this->backend.public); 269: 270: /* install an acquiring trap */ 271: charon->traps->install(charon->traps, peer_cfg, child_cfg); 272: } 273: 274: METHOD(ha_tunnel_t, destroy, void, 275: private_ha_tunnel_t *this) 276: { 277: if (this->backend.cfg) 278: { 279: charon->backends->remove_backend(charon->backends, &this->backend.public); 280: this->backend.cfg->destroy(this->backend.cfg); 281: } 282: if (this->creds.key) 283: { 284: lib->credmgr->remove_set(lib->credmgr, &this->creds.public); 285: this->creds.key->destroy(this->creds.key); 286: } 287: this->creds.local->destroy(this->creds.local); 288: this->creds.remote->destroy(this->creds.remote); 289: charon->traps->uninstall(charon->traps, HA_CFG_NAME, HA_CFG_NAME); 290: free(this); 291: } 292: 293: /** 294: * See header 295: */ 296: ha_tunnel_t *ha_tunnel_create(char *local, char *remote, char *secret) 297: { 298: private_ha_tunnel_t *this; 299: 300: INIT(this, 301: .public = { 302: .is_sa = _is_sa, 303: .destroy = _destroy, 304: }, 305: ); 306: 307: setup_tunnel(this, local, remote, secret); 308: 309: return &this->public; 310: }