Annotation of embedaddon/strongswan/src/libcharon/plugins/ha/ha_child.c, revision 1.1.1.1
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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>