52 # endif
53 #endif
54 #include <arpa/inet.h>
55
56 #include "racoon.h"
57 #include "ike_pfkey.h"
58 #include "isakmp_impl.h"
59 #include "ikev2_impl.h"
60 #include "debug.h"
61 #ifdef IKEV1
62 # include "oakley.h"
63 # include "ikev1_impl.h"
64 # include "ikev1/handler.h"
65 #endif
66
67 extern int debug_pfkey;
68 static void dump_param(char *, struct rcpfk_msg *);
69
70 static int sadb_getspi(struct rcpfk_msg *);
71 static int sadb_acquire_error(struct rcpfk_msg *);
72 static int sadb_update(struct rcpfk_msg *);
73 static int sadb_get(struct rcpfk_msg *);
74 static int sadb_add(struct rcpfk_msg *);
75 static int sadb_responder_error(struct rcpfk_msg *);
76 static int sadb_delete(struct rcpfk_msg *);
77
78 static int
79 null_proc()
80 {
81 return 0;
82 }
83
84 /* sadb_initiator_request_method used in response to SADB_ACQUIRE */
85 struct sadb_request_method sadb_initiator_request_method = {
86 sadb_getspi,
87 sadb_acquire_error,
88 sadb_update,
89 sadb_add,
90 sadb_delete,
91 sadb_get,
92 };
93
94 /* sadb_responder_request_method for use when receiving IKE_SA_INIT packet */
95 struct sadb_request_method sadb_responder_request_method = {
96 sadb_getspi,
97 sadb_responder_error,
98 sadb_update,
99 sadb_add,
100 sadb_delete,
101 sadb_get,
102 };
103
104 /* sadb_rekey_request_method for use when rekeying soft-expired IPsec SA */
105 struct sadb_request_method sadb_rekey_request_method = {
106 sadb_getspi,
107 sadb_responder_error,
108 sadb_update,
109 sadb_add,
110 sadb_delete,
111 sadb_get,
112 };
113
114 /* sadb_null_method for informational exchange SA */
115 struct sadb_request_method sadb_null_method = {
116 null_proc, null_proc, null_proc, null_proc, null_proc, null_proc
117 };
118
119 /* sadb_force_initiate_method for use with isakmp_force_initiate() */
120 struct sadb_request_method sadb_force_initiate_method = {
121 sadb_getspi,
122 sadb_responder_error, /* to ignore error */
123 sadb_update,
124 sadb_add,
125 sadb_delete,
126 sadb_get,
127 };
128
129 static SADB_LIST_HEAD(sadb_request_list_head, sadb_request) sadb_request_list_head;
130
131 static int pfkey_socket;
132 static uint32_t sadb_msg_seq;
133
134 static int sadb_getspi_callback(struct rcpfk_msg *param);
135 static int sadb_update_callback(struct rcpfk_msg *param);
136 static int sadb_get_callback(struct rcpfk_msg *param);
137 static int sadb_expire_callback(struct rcpfk_msg *param);
138 static int sadb_acquire_callback(struct rcpfk_msg *param);
139 static int sadb_delete_callback(struct rcpfk_msg *param);
140 #ifdef SADB_X_MIGRATE
141 static int sadb_x_migrate_callback(struct rcpfk_msg *param);
142 #endif
143
144 static struct rcpfk_cb ike_rcpfk_callback = {
145 sadb_getspi_callback,
146 sadb_update_callback,
147 0, /* sadb_add_callback, */
148 sadb_expire_callback,
149 sadb_acquire_callback,
150 sadb_delete_callback,
151 sadb_get_callback,
152 0, /* sadb_spdupdate_callback, */
153 0, /* sadb_spdadd_callback, */
154 0, /* sadb_spddelete_callback, */
155 0, /* sadb_spddelete2_callback, */
156 0, /* sadb_spdexpire_callbcak, */
157 0, /* sadb_spdget_callback */
158 0, /* sadb_spddump_callback */
159 #ifdef SADB_X_MIGRATE
160 sadb_x_migrate_callback,
161 #endif
162 };
163
164 int
165 sadb_init(void)
166 {
167 struct rcpfk_msg param;
168
169 SADB_LIST_INIT(&sadb_request_list_head);
170 if (debug_pfkey)
171 return 0;
172
173 param.flags = 0;
174
175 if (rcpfk_init(¶m, &ike_rcpfk_callback) != 0)
176 return -1;
177 pfkey_socket = param.so;
178 TRACE((PLOGLOC, "pfkey_socket: %d\n", pfkey_socket));
179 return 0;
180 }
181
182 #ifdef DEBUG
183 void
184 sadb_list_dump(void)
185 {
186 struct sadb_request *req;
187
188 plog(PLOG_DEBUG, PLOGLOC, 0, "sadb request list:\n");
190 !SADB_LIST_END(req);
191 req = SADB_LIST_NEXT(req)) {
192 plog(PLOG_DEBUG, PLOGLOC, 0,
193 "req %p method:%p seqno:%lx sa:%p\n",
194 req, req->method, (unsigned long)req->seqno,
195 req->sa);
196 }
197 plog(PLOG_DEBUG, PLOGLOC, 0, "end\n");
198 }
199 #endif
200
201 int
202 sadb_socket(void)
203 {
204 return pfkey_socket;
205 }
206
207 uint32_t
208 sadb_new_seq(void)
209 {
210 return ++sadb_msg_seq;
211 }
212
213 static void
214 log_rcpfk_error(const char *msg, struct rcpfk_msg *param)
215 {
216 if (param->eno) {
217 isakmp_log(0, 0, 0, 0,
218 PLOG_INTERR, PLOGLOC,
219 "%s: %s\n", msg, param->estr);
220 } else {
221 isakmp_log(0, 0, 0, 0,
222 PLOG_INTERR, PLOGLOC,
223 "%s: unknown error\n", msg);
224 }
225 }
226
227 void
228 sadb_poll(void)
229 {
230 struct rcpfk_msg rcpfk_param;
231
232 rcpfk_param.so = pfkey_socket;
233 rcpfk_param.flags = 0;
234 if (rcpfk_handler(&rcpfk_param) != 0) {
235 log_rcpfk_error("sadb_poll", &rcpfk_param);
236 }
237 }
238
239 void
240 sadb_request_initialize(struct sadb_request *req,
241 struct sadb_request_method *m,
242 struct sadb_response_method *r,
243 uint32_t seqno, void *sa)
244 {
245 req->method = m;
246 req->callback = r;
247 req->seqno = seqno;
248 req->sa = sa;
249 SADB_LIST_LINK(&sadb_request_list_head, req);
250 }
251
281 * send SADB_ACQUIRE with error to inform kernel of SA creation failure
282 */
283 static int
284 sadb_acquire_error(struct rcpfk_msg *param)
285 {
286 int err;
287
288 TRACE((PLOGLOC,
289 "sadb_acquire_error: seq=%d, satype=%d, errno=%d\n",
290 param->seq, param->satype, param->eno));
291
292 /* param: so, satype, seq, eno */
293 param->so = pfkey_socket;
294 param->flags = 0;
295 err = rcpfk_send_acquire(param);
296 if (err)
297 log_rcpfk_error("sadb_acquire_error", param);
298 return err;
299 }
300
301 static void
302 sadb_log_add(char *op, struct rcpfk_msg *param)
303 {
304 if (param->satype == RCT_SATYPE_ESP) {
305 INFO((PLOGLOC,
306 "%s ul_proto=%d src=%s dst=%s satype=%s samode=%s spi=0x%08x authtype=%s enctype=%s lifetime soft time=%"
307 PRIu64 " bytes=%" PRIu64 " hard time=%" PRIu64 " bytes=%" PRIu64 "\n",
308 op, param->ul_proto, rcs_sa2str(param->sa_src),
309 rcs_sa2str(param->sa_dst), rct2str(param->satype),
310 rct2str(param->samode), ntohl(param->spi),
311 rct2str(param->authtype), rct2str(param->enctype),
312 param->lft_soft_time, param->lft_soft_bytes,
313 param->lft_hard_time, param->lft_hard_bytes));
314 } else {
315 INFO((PLOGLOC,
316 "%s ul_proto=%d src=%s dst=%s satype=%s samode=%s spi=0x%08x authtype=%s lifetime soft time=%"
317 PRIu64 " bytes=%" PRIu64 " hard time=%" PRIu64 " bytes=%" PRIu64 "\n",
318 op, param->ul_proto, rcs_sa2str(param->sa_src),
319 rcs_sa2str(param->sa_dst), rct2str(param->satype),
320 rct2str(param->samode), ntohl(param->spi),
321 rct2str(param->authtype), param->lft_soft_time,
322 param->lft_soft_bytes, param->lft_hard_time,
323 param->lft_hard_bytes));
324 }
325 }
326
327 /* send SADB_UPDATE */
328 static int
329 sadb_update(struct rcpfk_msg *param)
330 {
331 int err;
332
333 sadb_log_add("SADB_UPDATE", param);
334 IF_TRACE(dump_param("sadb_update", param));
335
336 /* param:
337 * so, satype, seq, spi, wsize, authtype, [enctype,] saflags, samode, reqid,
338 * lft_hard_time, lft_hard_bytes, lft_soft_time, lft_soft_bytes,
339 * sa_src, pref_src, sa_dst, pref_dst, ul_proto,
595 if (req->callback->expired(req, param))
596 goto done;
597 }
598
599 /* couldn't find corresponding SA */
600 isakmp_log(0, 0, 0, 0, PLOG_INTWARN, PLOGLOC,
601 "PF_KEY SADB_EXPIRE message does not have corresponding request. (ignored)\n");
602
603 done:
604 TRACE((PLOGLOC, "done.\n"));
605 return 0;
606 }
607
608
609 /*
610 * called when the kernel generates SADB_ACQUIRE message
611 */
612 static int
613 sadb_acquire_callback(struct rcpfk_msg *param)
614 {
615 /* param: seq, satype, sa_src, sa_dst, samode, selid */
616 /* address(P)??? pid?? identity??? proposal??? */
617
618 TRACE((PLOGLOC,
619 "sadb_acquire_callback: seq=%d satype=%d sa_src=%s sa_dst=%s samode=%d selid=%d\n",
620 param->seq, param->satype, rcs_sa2str(param->sa_src),
621 rcs_sa2str(param->sa_dst), param->samode, param->slid));
622
623 if (sadb_find_by_seq(param->seq)) {
624 TRACE((PLOGLOC, "duplicate seq %u\n", param->seq));
625 return 0;
626 }
627
628 isakmp_initiate(&sadb_initiator_request_method,
629 param->slid,
630 param->seq, param->satype,
631 param->sa_src, param->sa_dst,
632 param->sa2_src);
633 return 0;
634 }
635
636 /*
637 * called when the kernel generates SADB_DELETE message
638 */
639 static int
640 sadb_delete_callback(struct rcpfk_msg *param)
641 {
642 /* param: seq, satype, spi, sa_src, sa_dst, samode */
643
644 /* similar to expire ? */
645
646 plog(PLOG_INFO, PLOGLOC, 0,
647 "received PFKEY_DELETE seq=%d satype=%s spi=0x%08x\n",
648 param->seq, rct2str(param->satype), ntohl(param->spi));
649 return 0;
650 }
651
652 #if 0
|
52 # endif
53 #endif
54 #include <arpa/inet.h>
55
56 #include "racoon.h"
57 #include "ike_pfkey.h"
58 #include "isakmp_impl.h"
59 #include "ikev2_impl.h"
60 #include "debug.h"
61 #ifdef IKEV1
62 # include "oakley.h"
63 # include "ikev1_impl.h"
64 # include "ikev1/handler.h"
65 #endif
66
67 extern int debug_pfkey;
68 static void dump_param(char *, struct rcpfk_msg *);
69
70 static int sadb_getspi(struct rcpfk_msg *);
71 static int sadb_acquire_error(struct rcpfk_msg *);
72 static int sadb_inverse_acquire(struct rcpfk_msg *);
73 static int sadb_update(struct rcpfk_msg *);
74 static int sadb_get(struct rcpfk_msg *);
75 static int sadb_add(struct rcpfk_msg *);
76 static int sadb_responder_error(struct rcpfk_msg *);
77 static int sadb_delete(struct rcpfk_msg *);
78
79 static int
80 null_proc()
81 {
82 return 0;
83 }
84
85 /* sadb_initiator_request_method used in response to SADB_ACQUIRE */
86 struct sadb_request_method sadb_initiator_request_method = {
87 sadb_getspi,
88 sadb_acquire_error,
89 sadb_update,
90 sadb_add,
91 sadb_delete,
92 sadb_get,
93 #ifdef sun
94 null_proc,
95 #endif /* sun/OpenSolaris */
96 };
97
98 /* sadb_responder_request_method for use when receiving IKE_SA_INIT packet */
99 struct sadb_request_method sadb_responder_request_method = {
100 sadb_getspi,
101 sadb_responder_error,
102 sadb_update,
103 sadb_add,
104 sadb_delete,
105 sadb_get,
106 #ifdef sun
107 sadb_inverse_acquire,
108 #endif /* sun/OpenSolaris */
109 };
110
111 /* sadb_rekey_request_method for use when rekeying soft-expired IPsec SA */
112 struct sadb_request_method sadb_rekey_request_method = {
113 sadb_getspi,
114 sadb_responder_error,
115 sadb_update,
116 sadb_add,
117 sadb_delete,
118 sadb_get,
119 };
120
121 /* sadb_null_method for informational exchange SA */
122 struct sadb_request_method sadb_null_method = {
123 null_proc, null_proc, null_proc, null_proc, null_proc, null_proc
124 #ifdef sun
125 , null_proc
126 #endif /* sun/OpenSolaris */
127 };
128
129 /* sadb_force_initiate_method for use with isakmp_force_initiate() */
130 struct sadb_request_method sadb_force_initiate_method = {
131 sadb_getspi,
132 sadb_responder_error, /* to ignore error */
133 sadb_update,
134 sadb_add,
135 sadb_delete,
136 sadb_get,
137 #ifdef sun
138 null_proc,
139 #endif /* sun/OpenSolaris */
140 };
141
142 static SADB_LIST_HEAD(sadb_request_list_head, sadb_request) sadb_request_list_head;
143
144 static int pfkey_socket;
145 static uint32_t my_sadb_seqnum;
146
147 static int sadb_getspi_callback(struct rcpfk_msg *param);
148 static int sadb_update_callback(struct rcpfk_msg *param);
149 static int sadb_get_callback(struct rcpfk_msg *param);
150 static int sadb_expire_callback(struct rcpfk_msg *param);
151 static int sadb_acquire_callback(struct rcpfk_msg *param);
152 static int sadb_delete_callback(struct rcpfk_msg *param);
153 #ifdef SADB_X_MIGRATE
154 static int sadb_x_migrate_callback(struct rcpfk_msg *param);
155 #endif
156
157 static struct rcpfk_cb ike_rcpfk_callback = {
158 sadb_getspi_callback,
159 sadb_update_callback,
160 0, /* sadb_add_callback, */
161 sadb_expire_callback,
162 sadb_acquire_callback,
163 sadb_delete_callback,
164 sadb_get_callback,
165 0, /* sadb_spdupdate_callback, */
166 0, /* sadb_spdadd_callback, */
167 0, /* sadb_spddelete_callback, */
168 0, /* sadb_spddelete2_callback, */
169 0, /* sadb_spdexpire_callbcak, */
170 0, /* sadb_spdget_callback */
171 0, /* sadb_spddump_callback */
172 #ifdef SADB_X_MIGRATE
173 sadb_x_migrate_callback,
174 #endif
175 };
176
177 int
178 sadb_init(void)
179 {
180 struct rcpfk_msg param;
181
182 (void) memset(¶m, 0, sizeof (param));
183
184 SADB_LIST_INIT(&sadb_request_list_head);
185 if (debug_pfkey)
186 return 0;
187
188 param.flags = 0;
189
190 if (rcpfk_init(¶m, &ike_rcpfk_callback) != 0)
191 return -1;
192 pfkey_socket = param.so;
193 TRACE((PLOGLOC, "pfkey_socket: %d\n", pfkey_socket));
194 return 0;
195 }
196
197 #ifdef DEBUG
198 void
199 sadb_list_dump(void)
200 {
201 struct sadb_request *req;
202
203 plog(PLOG_DEBUG, PLOGLOC, 0, "sadb request list:\n");
205 !SADB_LIST_END(req);
206 req = SADB_LIST_NEXT(req)) {
207 plog(PLOG_DEBUG, PLOGLOC, 0,
208 "req %p method:%p seqno:%lx sa:%p\n",
209 req, req->method, (unsigned long)req->seqno,
210 req->sa);
211 }
212 plog(PLOG_DEBUG, PLOGLOC, 0, "end\n");
213 }
214 #endif
215
216 int
217 sadb_socket(void)
218 {
219 return pfkey_socket;
220 }
221
222 uint32_t
223 sadb_new_seq(void)
224 {
225 return ++my_sadb_seqnum;
226 }
227
228 static void
229 log_rcpfk_error(const char *msg, struct rcpfk_msg *param)
230 {
231 if (param->eno) {
232 isakmp_log(0, 0, 0, 0,
233 PLOG_INTERR, PLOGLOC,
234 "%s: %s\n", msg, param->estr);
235 } else {
236 isakmp_log(0, 0, 0, 0,
237 PLOG_INTERR, PLOGLOC,
238 "%s: unknown error\n", msg);
239 }
240 }
241
242 void
243 sadb_poll(void)
244 {
245 struct rcpfk_msg rcpfk_param;
246
247 (void) memset(&rcpfk_param, 0, sizeof (rcpfk_param));
248 rcpfk_param.so = pfkey_socket;
249 rcpfk_param.flags = 0;
250 if (rcpfk_handler(&rcpfk_param) != 0) {
251 log_rcpfk_error("sadb_poll", &rcpfk_param);
252 }
253 }
254
255 void
256 sadb_request_initialize(struct sadb_request *req,
257 struct sadb_request_method *m,
258 struct sadb_response_method *r,
259 uint32_t seqno, void *sa)
260 {
261 req->method = m;
262 req->callback = r;
263 req->seqno = seqno;
264 req->sa = sa;
265 SADB_LIST_LINK(&sadb_request_list_head, req);
266 }
267
297 * send SADB_ACQUIRE with error to inform kernel of SA creation failure
298 */
299 static int
300 sadb_acquire_error(struct rcpfk_msg *param)
301 {
302 int err;
303
304 TRACE((PLOGLOC,
305 "sadb_acquire_error: seq=%d, satype=%d, errno=%d\n",
306 param->seq, param->satype, param->eno));
307
308 /* param: so, satype, seq, eno */
309 param->so = pfkey_socket;
310 param->flags = 0;
311 err = rcpfk_send_acquire(param);
312 if (err)
313 log_rcpfk_error("sadb_acquire_error", param);
314 return err;
315 }
316
317 #ifdef sun
318 static int
319 sadb_inverse_acquire(struct rcpfk_msg *param)
320 {
321 int err;
322
323 TRACE((PLOGLOC, "sadb_inverse_acquire: seq=%d\n", param->seq));
324
325 /* param: so, satype, seq, eno */
326 param->so = pfkey_socket;
327 param->flags = 0;
328 err = rcpfk_send_inverse_acquire(param);
329 if (err)
330 log_rcpfk_error("sadb_inverse_acquire", param);
331 return (err);
332 }
333 #endif /* sun/OpenSolaris */
334
335 #define sa2str_chk(sa) (((sa) == NULL) ? "<none>" : rcs_sa2str(sa))
336
337 static void
338 sadb_log_add(char *op, struct rcpfk_msg *param)
339 {
340 if (param->satype == RCT_SATYPE_ESP) {
341 INFO((PLOGLOC,
342 "%s ul_proto=%d src=%s dst=%s "
343 #ifdef sun
344 "isrc=%s idst=%s nlc=%s nrm=%s"
345 #endif
346 "satype=%s samode=%s spi=0x%08x authtype=%s enctype=%s lifetime soft time=%"
347 PRIu64 " bytes=%" PRIu64 " hard time=%" PRIu64 " bytes=%" PRIu64 "\n",
348 op, param->ul_proto, rcs_sa2str(param->sa_src),
349 rcs_sa2str(param->sa_dst),
350 #ifdef sun
351 sa2str_chk(param->sa_isrc), sa2str_chk(param->sa_idst),
352 sa2str_chk(param->sa_natlocal),
353 sa2str_chk(param->sa_natremote),
354 #endif
355 rct2str(param->satype),
356 rct2str(param->samode), ntohl(param->spi),
357 rct2str(param->authtype), rct2str(param->enctype),
358 param->lft_soft_time, param->lft_soft_bytes,
359 param->lft_hard_time, param->lft_hard_bytes));
360 } else {
361 INFO((PLOGLOC,
362 "%s ul_proto=%d src=%s dst=%s "
363 #ifdef sun
364 "isrc=%s idst=%s nlc=%s nrm=%s"
365 #endif
366 "satype=%s samode=%s spi=0x%08x authtype=%s lifetime soft time=%"
367 PRIu64 " bytes=%" PRIu64 " hard time=%" PRIu64 " bytes=%" PRIu64 "\n",
368 op, param->ul_proto, rcs_sa2str(param->sa_src),
369 rcs_sa2str(param->sa_dst),
370 #ifdef sun
371 sa2str_chk(param->sa_isrc), sa2str_chk(param->sa_idst),
372 sa2str_chk(param->sa_natlocal),
373 sa2str_chk(param->sa_natremote),
374 #endif
375 rct2str(param->satype),
376 rct2str(param->samode), ntohl(param->spi),
377 rct2str(param->authtype), param->lft_soft_time,
378 param->lft_soft_bytes, param->lft_hard_time,
379 param->lft_hard_bytes));
380 }
381 }
382
383 /* send SADB_UPDATE */
384 static int
385 sadb_update(struct rcpfk_msg *param)
386 {
387 int err;
388
389 sadb_log_add("SADB_UPDATE", param);
390 IF_TRACE(dump_param("sadb_update", param));
391
392 /* param:
393 * so, satype, seq, spi, wsize, authtype, [enctype,] saflags, samode, reqid,
394 * lft_hard_time, lft_hard_bytes, lft_soft_time, lft_soft_bytes,
395 * sa_src, pref_src, sa_dst, pref_dst, ul_proto,
651 if (req->callback->expired(req, param))
652 goto done;
653 }
654
655 /* couldn't find corresponding SA */
656 isakmp_log(0, 0, 0, 0, PLOG_INTWARN, PLOGLOC,
657 "PF_KEY SADB_EXPIRE message does not have corresponding request. (ignored)\n");
658
659 done:
660 TRACE((PLOGLOC, "done.\n"));
661 return 0;
662 }
663
664
665 /*
666 * called when the kernel generates SADB_ACQUIRE message
667 */
668 static int
669 sadb_acquire_callback(struct rcpfk_msg *param)
670 {
671 struct sadb_request *req;
672 invacq_t *invacq;
673 /* param: seq, satype, sa_src, sa_dst, samode, selid */
674 /* address(P)??? pid?? identity??? proposal??? */
675
676 TRACE((PLOGLOC,
677 "sadb_acquire_callback: seq=%d satype=%d sa_src=%s sa_dst=%s samode=%d selid=%d\n",
678 param->seq, param->satype, rcs_sa2str(param->sa_src),
679 rcs_sa2str(param->sa_dst), param->samode, param->slid));
680
681 req = sadb_find_by_seq(param->seq);
682 if (req != NULL) {
683 /* Inverse-ACQUIRE. */
684 invacq = (invacq_t *)req->sa;
685 invacq->answer = param;
686 return (invacq->receiver(invacq));
687 }
688
689 if (param->eno != 0) {
690 /* inverse-ACQUIRE error with no outstanding request. Drop. */
691 return (-1);
692 }
693
694 isakmp_initiate(&sadb_initiator_request_method, param);
695 return 0;
696 }
697
698 /*
699 * called when the kernel generates SADB_DELETE message
700 */
701 static int
702 sadb_delete_callback(struct rcpfk_msg *param)
703 {
704 /* param: seq, satype, spi, sa_src, sa_dst, samode */
705
706 /* similar to expire ? */
707
708 plog(PLOG_INFO, PLOGLOC, 0,
709 "received PFKEY_DELETE seq=%d satype=%s spi=0x%08x\n",
710 param->seq, rct2str(param->satype), ntohl(param->spi));
711 return 0;
712 }
713
714 #if 0
|