2 * Copyright (c) 2008, 2012, 2013 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
27 #include <sys/types.h>
28 #include <sys/param.h>
29 #include <sys/queue.h>
35 #include "ike_session.h"
36 #include "isakmp_var.h"
37 #include "isakmp_ident.h"
38 #include "isakmp_agg.h"
39 #include "isakmp_quick.h"
40 #include "isakmp_inf.h"
41 #include "vpn_control_var.h"
47 fsm_set_state(int *var
, int state
)
50 plog(ASL_LEVEL_DEBUG
, "****** state changed to: %s\n", s_isakmp_state(0, 0, state
));
54 //================================
55 // Version Agnostic Events
56 //================================
58 fsm_api_handle_connect (struct sockaddr_storage
*remote
, const int connect_mode
)
65 fsm_api_handle_disconnect (struct sockaddr_storage
*remote
, const char *reason
)
72 fsm_pfkey_handle_acquire (phase2_handle_t
*iph2
)
79 fsm_pfkey_getspi_complete (phase2_handle_t
*iph2
)
85 fsm_isakmp_initial_pkt (vchar_t
*pkt
, struct sockaddr_storage
*local
, struct sockaddr_storage
*remote
)
91 //================================
93 //================================
96 fsm_ikev1_phase1_process_payloads (phase1_handle_t
*iph1
, vchar_t
*msg
)
101 struct timeval start
, end
;
103 gettimeofday(&start
, NULL
);
106 switch (iph1
->status
) {
107 case IKEV1_STATE_PHASE1_ESTABLISHED
:
108 return 0; // ignore - already established
110 case IKEV1_STATE_IDENT_I_MSG1SENT
:
111 error
= ident_i2recv(iph1
, msg
);
114 case IKEV1_STATE_IDENT_I_MSG3SENT
:
115 error
= ident_i4recv(iph1
, msg
);
118 case IKEV1_STATE_IDENT_I_MSG5SENT
:
119 error
= ident_i6recv(iph1
, msg
);
122 case IKEV1_STATE_IDENT_R_START
:
123 error
= ident_r1recv(iph1
, msg
);
125 plog(ASL_LEVEL_ERR
, "failed to pre-process packet.\n");
130 case IKEV1_STATE_IDENT_R_MSG2SENT
:
131 error
= ident_r3recv(iph1
, msg
);
134 case IKEV1_STATE_IDENT_R_MSG4SENT
:
135 error
= ident_r5recv(iph1
, msg
);
138 case IKEV1_STATE_AGG_R_START
:
139 error
= agg_r1recv(iph1
, msg
);
141 plog(ASL_LEVEL_ERR
, "failed to pre-process packet.\n");
146 case IKEV1_STATE_AGG_I_MSG1SENT
:
147 error
= agg_i2recv(iph1
, msg
);
150 case IKEV1_STATE_AGG_R_MSG2SENT
:
151 error
= agg_r3recv(iph1
, msg
);
160 return 0; // ignore error and keep phase 1 handle
162 VPTRINIT(iph1
->sendbuf
);
163 /* turn off schedule */
164 SCHED_KILL(iph1
->scr
);
167 plog(ASL_LEVEL_DEBUG
, "===\n");
168 if ((error
= fsm_ikev1_phase1_send_response(iph1
, msg
))) {
169 plog(ASL_LEVEL_ERR
, "failed to process packet.\n");
174 gettimeofday(&end
, NULL
);
175 syslog(LOG_NOTICE
, "%s(%s): %8.6f",
176 "Phase 1", s_isakmp_state(iph1
->etype
, iph1
->side
, iph1
->status
),
177 timedelta(&start
, &end
));
179 if (FSM_STATE_IS_ESTABLISHED(iph1
->status
))
180 ikev1_phase1_established(iph1
);
185 plog(ASL_LEVEL_ERR
, "Phase 1 negotiation failed.\n");
186 ike_session_unlink_phase1(iph1
);
193 fsm_ikev1_phase1_send_response(phase1_handle_t
*iph1
, vchar_t
*msg
)
198 switch (iph1
->status
) {
199 case IKEV1_STATE_IDENT_I_START
:
200 error
= ident_i1send(iph1
, msg
);
203 case IKEV1_STATE_IDENT_I_MSG2RCVD
:
204 error
= ident_i3send(iph1
, msg
);
207 case IKEV1_STATE_IDENT_I_MSG4RCVD
:
208 error
= ident_i5send(iph1
, msg
);
211 case IKEV1_STATE_IDENT_I_MSG6RCVD
:
212 error
= ident_ifinalize(iph1
, msg
);
215 case IKEV1_STATE_IDENT_R_MSG1RCVD
:
216 error
= ident_r2send(iph1
, msg
);
219 case IKEV1_STATE_IDENT_R_MSG3RCVD
:
220 error
= ident_r4send(iph1
, msg
);
223 case IKEV1_STATE_IDENT_R_MSG5RCVD
:
224 error
= ident_r6send(iph1
, msg
);
227 case IKEV1_STATE_AGG_I_START
:
228 error
= agg_i1send(iph1
, msg
);
231 case IKEV1_STATE_AGG_I_MSG2RCVD
:
232 error
= agg_i3send(iph1
, msg
);
235 case IKEV1_STATE_AGG_R_MSG1RCVD
:
236 error
= agg_r2send(iph1
, msg
);
239 case IKEV1_STATE_AGG_R_MSG3RCVD
:
240 error
= agg_rfinalize(iph1
, msg
);
251 if (iph1
->remote
->ss_family
== AF_INET
)
252 address
= ((struct sockaddr_in
*)iph1
->remote
)->sin_addr
.s_addr
;
256 vpncontrol_notify_ike_failed(error
, FROM_LOCAL
, address
, 0, NULL
);
263 fsm_ikev1_phase2_process_payloads (phase2_handle_t
*iph2
, vchar_t
*msg
)
268 struct timeval start
, end
;
270 gettimeofday(&start
, NULL
);
273 switch (iph2
->status
) {
274 /* ignore a packet */
275 case IKEV1_STATE_PHASE2_ESTABLISHED
:
276 case IKEV1_STATE_QUICK_I_GETSPISENT
:
277 case IKEV1_STATE_QUICK_R_GETSPISENT
:
280 case IKEV1_STATE_QUICK_I_MSG1SENT
:
281 error
= quick_i2recv(iph2
, msg
);
284 case IKEV1_STATE_QUICK_I_MSG3SENT
:
285 error
= quick_i4recv(iph2
, msg
);
288 case IKEV1_STATE_QUICK_R_START
:
289 error
= quick_r1recv(iph2
, msg
);
292 case IKEV1_STATE_QUICK_R_MSG2SENT
:
293 error
= quick_r3recv(iph2
, msg
);
303 plog(ASL_LEVEL_ERR
, "failed to pre-process packet.\n");
304 if (error
== ISAKMP_INTERNAL_ERROR
)
306 isakmp_info_send_n1(iph2
->ph1
, error
, NULL
);
310 /* when using commit bit, status will be reached here. */
311 //if (iph2->status == PHASE2ST_ADDSA) //%%% BUG FIX - wrong place
314 /* free resend buffer */
315 if (iph2
->sendbuf
== NULL
&& iph2
->status
!= IKEV1_STATE_QUICK_R_MSG1RCVD
) {
317 "no buffer found as sendbuf\n");
321 VPTRINIT(iph2
->sendbuf
);
323 /* turn off schedule */
324 SCHED_KILL(iph2
->scr
);
326 /* when using commit bit, will be finished here - no more packets to send */
327 if (iph2
->status
== IKEV1_STATE_QUICK_I_ADDSA
)
330 error
= fsm_ikev1_phase2_send_response(iph2
, msg
);
332 plog(ASL_LEVEL_ERR
, "failed to process packet.\n");
337 gettimeofday(&end
, NULL
);
338 syslog(LOG_NOTICE
, "%s(%s): %8.6f",
340 s_isakmp_state(ISAKMP_ETYPE_QUICK
, iph2
->side
, iph2
->status
),
341 timedelta(&start
, &end
));
347 plog(ASL_LEVEL_ERR
, "Phase 2 negotiation failed.\n");
348 ike_session_unlink_phase2(iph2
);
354 fsm_ikev1_phase2_send_response(phase2_handle_t
*iph2
, vchar_t
*msg
)
359 switch (iph2
->status
) {
360 case IKEV1_STATE_QUICK_R_MSG1RCVD
:
361 error
= quick_rprep(iph2
, msg
);
364 case IKEV1_STATE_QUICK_I_GETSPIDONE
:
365 error
= quick_i1send(iph2
, msg
);
368 case IKEV1_STATE_QUICK_I_MSG2RCVD
:
369 error
= quick_i3send(iph2
, msg
);
372 case IKEV1_STATE_QUICK_R_GETSPIDONE
:
373 error
= quick_r2send(iph2
, msg
);
376 case IKEV1_STATE_QUICK_R_MSG3RCVD
:
377 error
= quick_r4send(iph2
, msg
);
380 case IKEV1_STATE_QUICK_R_COMMIT
:
381 error
= quick_rfinalize(iph2
, msg
);