2 * Copyright (C) 2010-2012 Tobias Brunner
3 * Copyright (C) 2012 Giuliano Grassi
4 * Copyright (C) 2012 Ralf Sager
5 * Hochschule fuer Technik Rapperswil
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 #include "android_service.h"
19 #include "../charonservice.h"
23 #include <processing/jobs/callback_job.h>
25 typedef struct private_android_service_t private_android_service_t
;
28 * private data of Android service
30 struct private_android_service_t
{
35 android_service_t
public;
59 METHOD(listener_t
, child_updown
, bool,
60 private_android_service_t
*this, ike_sa_t
*ike_sa
, child_sa_t
*child_sa
,
63 if (this->ike_sa
== ike_sa
)
67 /* disable the hooks registered to catch initiation failures */
68 this->public.listener
.ike_updown
= NULL
;
69 this->public.listener
.ike_state_change
= NULL
;
70 charonservice
->update_status(charonservice
,
71 CHARONSERVICE_CHILD_STATE_UP
);
75 charonservice
->update_status(charonservice
,
76 CHARONSERVICE_CHILD_STATE_DOWN
);
83 METHOD(listener_t
, ike_updown
, bool,
84 private_android_service_t
*this, ike_sa_t
*ike_sa
, bool up
)
86 /* this callback is only registered during initiation, so if the IKE_SA
87 * goes down we assume an authentication error */
88 if (this->ike_sa
== ike_sa
&& !up
)
90 charonservice
->update_status(charonservice
,
91 CHARONSERVICE_AUTH_ERROR
);
97 METHOD(listener_t
, ike_state_change
, bool,
98 private_android_service_t
*this, ike_sa_t
*ike_sa
, ike_sa_state_t state
)
100 /* this call back is only registered during initiation */
101 if (this->ike_sa
== ike_sa
&& state
== IKE_DESTROYING
)
103 charonservice
->update_status(charonservice
,
104 CHARONSERVICE_UNREACHABLE_ERROR
);
110 METHOD(listener_t
, alert
, bool,
111 private_android_service_t
*this, ike_sa_t
*ike_sa
, alert_t alert
,
114 if (this->ike_sa
== ike_sa
)
118 case ALERT_PEER_ADDR_FAILED
:
119 charonservice
->update_status(charonservice
,
120 CHARONSERVICE_LOOKUP_ERROR
);
122 case ALERT_PEER_AUTH_FAILED
:
123 charonservice
->update_status(charonservice
,
124 CHARONSERVICE_PEER_AUTH_ERROR
);
133 METHOD(listener_t
, ike_rekey
, bool,
134 private_android_service_t
*this, ike_sa_t
*old
, ike_sa_t
*new)
136 if (this->ike_sa
== old
)
143 static job_requeue_t
initiate(private_android_service_t
*this)
145 identification_t
*gateway
, *user
;
147 peer_cfg_t
*peer_cfg
;
148 child_cfg_t
*child_cfg
;
149 traffic_selector_t
*ts
;
152 lifetime_cfg_t lifetime
= {
154 .life
= 10800, /* 3h */
155 .rekey
= 10200, /* 2h50min */
156 .jitter
= 300 /* 5min */
160 ike_cfg
= ike_cfg_create(TRUE
, TRUE
, this->local_address
, FALSE
,
161 charon
->socket
->get_port(charon
->socket
, FALSE
),
162 this->gateway
, FALSE
, IKEV2_UDP_PORT
);
163 ike_cfg
->add_proposal(ike_cfg
, proposal_create_default(PROTO_IKE
));
165 peer_cfg
= peer_cfg_create("android", IKEV2
, ike_cfg
, CERT_SEND_IF_ASKED
,
166 UNIQUE_REPLACE
, 1, /* keyingtries */
167 36000, 0, /* rekey 10h, reauth none */
168 600, 600, /* jitter, over 10min */
169 TRUE
, FALSE
, /* mobike, aggressive */
170 0, 0, /* DPD delay, timeout */
171 host_create_from_string("0.0.0.0", 0) /* virt */,
172 NULL
, FALSE
, NULL
, NULL
); /* pool, mediation */
175 auth
= auth_cfg_create();
176 auth
->add(auth
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_EAP
);
177 user
= identification_create_from_string(this->username
);
178 auth
->add(auth
, AUTH_RULE_IDENTITY
, user
);
179 peer_cfg
->add_auth_cfg(peer_cfg
, auth
, TRUE
);
180 auth
= auth_cfg_create();
181 auth
->add(auth
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_PUBKEY
);
182 gateway
= identification_create_from_string(this->gateway
);
183 auth
->add(auth
, AUTH_RULE_IDENTITY
, gateway
);
184 peer_cfg
->add_auth_cfg(peer_cfg
, auth
, FALSE
);
186 child_cfg
= child_cfg_create("android", &lifetime
, NULL
, TRUE
, MODE_TUNNEL
,
187 ACTION_NONE
, ACTION_NONE
, ACTION_NONE
, FALSE
,
188 0, 0, NULL
, NULL
, 0);
189 child_cfg
->add_proposal(child_cfg
, proposal_create_default(PROTO_ESP
));
190 ts
= traffic_selector_create_dynamic(0, 0, 65535);
191 child_cfg
->add_traffic_selector(child_cfg
, TRUE
, ts
);
192 ts
= traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE
, "0.0.0.0",
193 0, "255.255.255.255", 65535);
194 child_cfg
->add_traffic_selector(child_cfg
, FALSE
, ts
);
195 peer_cfg
->add_child_cfg(peer_cfg
, child_cfg
);
197 /* get us an IKE_SA */
198 ike_sa
= charon
->ike_sa_manager
->checkout_by_config(charon
->ike_sa_manager
,
202 peer_cfg
->destroy(peer_cfg
);
203 charonservice
->update_status(charonservice
,
204 CHARONSERVICE_GENERIC_ERROR
);
205 return JOB_REQUEUE_NONE
;
207 if (!ike_sa
->get_peer_cfg(ike_sa
))
209 ike_sa
->set_peer_cfg(ike_sa
, peer_cfg
);
211 peer_cfg
->destroy(peer_cfg
);
213 /* store the IKE_SA so we can track its progress */
214 this->ike_sa
= ike_sa
;
216 /* get an additional reference because initiate consumes one */
217 child_cfg
->get_ref(child_cfg
);
218 if (ike_sa
->initiate(ike_sa
, child_cfg
, 0, NULL
, NULL
) != SUCCESS
)
220 DBG1(DBG_CFG
, "failed to initiate tunnel");
221 charon
->ike_sa_manager
->checkin_and_destroy(charon
->ike_sa_manager
,
223 return JOB_REQUEUE_NONE
;
225 charon
->ike_sa_manager
->checkin(charon
->ike_sa_manager
, ike_sa
);
226 return JOB_REQUEUE_NONE
;
229 METHOD(android_service_t
, destroy
, void,
230 private_android_service_t
*this)
232 charon
->bus
->remove_listener(charon
->bus
, &this->public.listener
);
233 free(this->local_address
);
234 free(this->username
);
242 android_service_t
*android_service_create(char *local_address
, char *gateway
,
245 private_android_service_t
*this;
250 .ike_rekey
= _ike_rekey
,
251 .ike_updown
= _ike_updown
,
252 .ike_state_change
= _ike_state_change
,
253 .child_updown
= _child_updown
,
258 .local_address
= local_address
,
259 .username
= username
,
263 charon
->bus
->add_listener(charon
->bus
, &this->public.listener
);
265 lib
->processor
->queue_job(lib
->processor
,
266 (job_t
*)callback_job_create((callback_job_cb_t
)initiate
, this,
268 return &this->public;