Return to ha_child.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / ha |
1.1 misho 1: /* 2: * Copyright (C) 2008 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_child.h" 17: 18: typedef struct private_ha_child_t private_ha_child_t; 19: 20: /** 21: * Private data of an ha_child_t object. 22: */ 23: struct private_ha_child_t { 24: 25: /** 26: * Public ha_child_t interface. 27: */ 28: ha_child_t public; 29: 30: /** 31: * socket we use for syncing 32: */ 33: ha_socket_t *socket; 34: 35: /** 36: * tunnel securing sync messages 37: */ 38: ha_tunnel_t *tunnel; 39: 40: /** 41: * Segment handling 42: */ 43: ha_segments_t *segments; 44: 45: /** 46: * Kernel helper 47: */ 48: ha_kernel_t *kernel; 49: }; 50: 51: METHOD(listener_t, child_keys, bool, 52: private_ha_child_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, 53: bool initiator, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r) 54: { 55: ha_message_t *m; 56: chunk_t secret; 57: proposal_t *proposal; 58: uint16_t alg, len; 59: linked_list_t *local_ts, *remote_ts; 60: enumerator_t *enumerator; 61: traffic_selector_t *ts; 62: u_int seg_i, seg_o; 63: 64: if (this->tunnel && this->tunnel->is_sa(this->tunnel, ike_sa)) 65: { /* do not sync SA between nodes */ 66: return TRUE; 67: } 68: 69: m = ha_message_create(HA_CHILD_ADD); 70: 71: m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa)); 72: m->add_attribute(m, HA_INITIATOR, (uint8_t)initiator); 73: m->add_attribute(m, HA_INBOUND_SPI, child_sa->get_spi(child_sa, TRUE)); 74: m->add_attribute(m, HA_OUTBOUND_SPI, child_sa->get_spi(child_sa, FALSE)); 75: m->add_attribute(m, HA_INBOUND_CPI, child_sa->get_cpi(child_sa, TRUE)); 76: m->add_attribute(m, HA_OUTBOUND_CPI, child_sa->get_cpi(child_sa, FALSE)); 77: m->add_attribute(m, HA_IPSEC_MODE, child_sa->get_mode(child_sa)); 78: m->add_attribute(m, HA_IPCOMP, child_sa->get_ipcomp(child_sa)); 79: m->add_attribute(m, HA_CONFIG_NAME, child_sa->get_name(child_sa)); 80: 81: proposal = child_sa->get_proposal(child_sa); 82: if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg, &len)) 83: { 84: m->add_attribute(m, HA_ALG_ENCR, alg); 85: if (len) 86: { 87: m->add_attribute(m, HA_ALG_ENCR_LEN, len); 88: } 89: } 90: if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &alg, NULL)) 91: { 92: m->add_attribute(m, HA_ALG_INTEG, alg); 93: } 94: if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &alg, NULL)) 95: { 96: m->add_attribute(m, HA_ALG_DH, alg); 97: } 98: if (proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, &alg, NULL)) 99: { 100: m->add_attribute(m, HA_ESN, alg); 101: } 102: m->add_attribute(m, HA_NONCE_I, nonce_i); 103: m->add_attribute(m, HA_NONCE_R, nonce_r); 104: if (dh && dh->get_shared_secret(dh, &secret)) 105: { 106: m->add_attribute(m, HA_SECRET, secret); 107: chunk_clear(&secret); 108: } 109: 110: local_ts = linked_list_create(); 111: remote_ts = linked_list_create(); 112: 113: enumerator = child_sa->create_ts_enumerator(child_sa, TRUE); 114: while (enumerator->enumerate(enumerator, &ts)) 115: { 116: m->add_attribute(m, HA_LOCAL_TS, ts); 117: local_ts->insert_last(local_ts, ts); 118: } 119: enumerator->destroy(enumerator); 120: 121: enumerator = child_sa->create_ts_enumerator(child_sa, FALSE); 122: while (enumerator->enumerate(enumerator, &ts)) 123: { 124: m->add_attribute(m, HA_REMOTE_TS, ts); 125: remote_ts->insert_last(remote_ts, ts); 126: } 127: enumerator->destroy(enumerator); 128: 129: seg_i = this->kernel->get_segment_spi(this->kernel, 130: ike_sa->get_my_host(ike_sa), child_sa->get_spi(child_sa, TRUE)); 131: seg_o = this->kernel->get_segment_spi(this->kernel, 132: ike_sa->get_other_host(ike_sa), child_sa->get_spi(child_sa, FALSE)); 133: DBG1(DBG_CFG, "handling HA CHILD_SA %s{%d} %#R === %#R " 134: "(segment in: %d%s, out: %d%s)", child_sa->get_name(child_sa), 135: child_sa->get_unique_id(child_sa), local_ts, remote_ts, 136: seg_i, this->segments->is_active(this->segments, seg_i) ? "*" : "", 137: seg_o, this->segments->is_active(this->segments, seg_o) ? "*" : ""); 138: 139: local_ts->destroy(local_ts); 140: remote_ts->destroy(remote_ts); 141: 142: this->socket->push(this->socket, m); 143: m->destroy(m); 144: 145: return TRUE; 146: } 147: 148: METHOD(listener_t, child_state_change, bool, 149: private_ha_child_t *this, ike_sa_t *ike_sa, 150: child_sa_t *child_sa, child_sa_state_t state) 151: { 152: if (!ike_sa || 153: ike_sa->get_state(ike_sa) == IKE_PASSIVE || 154: ike_sa->get_state(ike_sa) == IKE_DESTROYING) 155: { /* only sync active IKE_SAs */ 156: return TRUE; 157: } 158: if (this->tunnel && this->tunnel->is_sa(this->tunnel, ike_sa)) 159: { /* do not sync SA between nodes */ 160: return TRUE; 161: } 162: 163: 164: if (state == CHILD_DESTROYING) 165: { 166: ha_message_t *m; 167: 168: m = ha_message_create(HA_CHILD_DELETE); 169: 170: m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa)); 171: m->add_attribute(m, HA_INBOUND_SPI, 172: child_sa->get_spi(child_sa, TRUE)); 173: this->socket->push(this->socket, m); 174: m->destroy(m); 175: } 176: return TRUE; 177: } 178: 179: METHOD(ha_child_t, destroy, void, 180: private_ha_child_t *this) 181: { 182: free(this); 183: } 184: 185: /** 186: * See header 187: */ 188: ha_child_t *ha_child_create(ha_socket_t *socket, ha_tunnel_t *tunnel, 189: ha_segments_t *segments, ha_kernel_t *kernel) 190: { 191: private_ha_child_t *this; 192: 193: INIT(this, 194: .public = { 195: .listener = { 196: .child_keys = _child_keys, 197: .child_state_change = _child_state_change, 198: }, 199: .destroy = _destroy, 200: }, 201: .socket = socket, 202: .tunnel = tunnel, 203: .segments = segments, 204: .kernel = kernel, 205: ); 206: 207: return &this->public; 208: }