Lines Matching refs:sa

1 /* $OpenBSD: sa.c,v 1.125 2022/01/28 05:24:15 guenther Exp $	 */
2 /* $EOM: sa.c,v 1.112 2000/12/12 00:22:52 niklas Exp $ */
55 #include "sa.h"
83 static LIST_HEAD(sa_list, sa) *sa_tab;
124 struct sa *
125 sa_find(int (*check) (struct sa*, void *), void *arg)
128 struct sa *sa;
131 for (sa = LIST_FIRST(&sa_tab[i]); sa; sa = LIST_NEXT(sa, link))
132 if (check(sa, arg)) {
134 sa));
135 return sa;
143 sa_check_icookie(struct sa *sa, void *icookie)
145 return sa->phase == 1 &&
146 memcmp(sa->cookies, icookie, ISAKMP_HDR_ICOOKIE_LEN) == 0;
150 struct sa *
163 sa_check_name_phase(struct sa *sa, void *v_arg)
167 return sa->name && strcasecmp(sa->name, arg->name) == 0 &&
168 sa->phase == arg->phase && !(sa->flags & SA_FLAG_REPLACED);
172 struct sa *
230 sa_check_peer(struct sa *sa, void *v_addr)
235 if (!sa->transport || (sa->flags & SA_FLAG_READY) == 0 ||
236 (addr->phase && addr->phase != sa->phase))
239 sa->transport->vtbl->get_dst(sa->transport, &dst);
264 isakmp_sa_check(struct sa *sa, void *v_arg)
269 if (sa->phase != 1 || !(sa->flags & SA_FLAG_READY))
272 /* verify address is either src or dst for this sa */
273 sa->transport->vtbl->get_dst(sa->transport, &dst);
274 sa->transport->vtbl->get_src(sa->transport, &src);
280 if (memcmp(sa->cookies, arg->spi, ISAKMP_HDR_COOKIES_LEN) == 0)
289 struct sa *
301 struct sa *
314 struct sa *
327 sa_enter(struct sa *sa)
336 cp = sa->cookies + i;
341 cp = sa->message_id + i;
346 LIST_INSERT_HEAD(&sa_tab[bucket], sa, link);
347 sa_reference(sa);
348 LOG_DBG((LOG_SA, 70, "sa_enter: SA %p added to SA list", sa));
356 struct sa *
367 struct sa *
372 struct sa *sa;
394 for (sa = LIST_FIRST(&sa_tab[bucket]);
395 sa && (memcmp(cookies, sa->cookies, ISAKMP_HDR_COOKIES_LEN) != 0 ||
396 (message_id && memcmp(message_id, sa->message_id,
398 (!message_id && !zero_test(sa->message_id, ISAKMP_HDR_MESSAGE_ID_LEN)));
399 sa = LIST_NEXT(sa, link))
402 return sa;
409 struct sa *sa;
415 sa = calloc(1, sizeof *sa);
416 if (!sa) {
418 (unsigned long)sizeof *sa);
421 sa->transport = t;
424 sa->phase = exchange->phase;
425 memcpy(sa->cookies, exchange->cookies, ISAKMP_HDR_COOKIES_LEN);
426 memcpy(sa->message_id, exchange->message_id,
428 sa->doi = exchange->doi;
429 sa->policy_id = -1;
431 if (sa->doi->sa_size) {
436 sa->data = calloc(1, sa->doi->sa_size);
437 if (!sa->data) {
439 (unsigned long)sa->doi->sa_size);
440 free(sa);
444 TAILQ_INIT(&sa->protos);
446 sa_enter(sa);
447 TAILQ_INSERT_TAIL(&exchange->sa_list, sa, next);
448 sa_reference(sa);
451 "sa_create: sa %p phase %d added to exchange %p (%s)", sa,
452 sa->phase, exchange,
462 sa_dump(int cls, int level, char *header, struct sa *sa)
469 sa, sa->name ? sa->name : "<unnamed>", sa->phase, sa->doi->id,
470 sa->flags));
472 decode_32(sa->cookies), decode_32(sa->cookies + 4),
473 decode_32(sa->cookies + 8), decode_32(sa->cookies + 12)));
475 decode_32(sa->message_id), sa->refcnt));
476 LOG_DBG((cls, level, "%s: life secs %llu kb %llu", header, sa->seconds,
477 sa->kilobytes));
478 for (proto = TAILQ_FIRST(&sa->protos); proto;
487 !sa->doi ? "<nodoi>" :
488 sa->doi->decode_ids("initiator id: %s, responder id: %s",
489 sa->id_i, sa->id_i_len,
490 sa->id_r, sa->id_r_len, 0),
491 !sa->transport ? "<no transport>" :
492 sa->transport->vtbl->decode_ids(sa->transport)));
675 report_lifetimes(FILE *fd, struct sa *sa)
679 if (sa->seconds)
680 fprintf(fd, "Lifetime: %llu seconds\n", sa->seconds);
682 if (sa->soft_death) {
683 timeout = get_timeout(&sa->soft_death->expiration);
690 if (sa->death) {
691 timeout = get_timeout(&sa->death->expiration);
698 if (sa->kilobytes)
699 fprintf(fd, "Lifetime: %llu kilobytes\n", sa->kilobytes);
706 report_phase1(FILE *fd, struct sa *sa)
710 decode_32(sa->cookies), decode_32(sa->cookies + 4),
711 decode_32(sa->cookies + 8), decode_32(sa->cookies + 12));
718 report_phase2(FILE *fd, struct sa *sa)
724 for (proto = TAILQ_FIRST(&sa->protos); proto;
744 struct sa *sa;
748 for (sa = LIST_FIRST(&sa_tab[i]); sa; sa = LIST_NEXT(sa, link))
749 sa_dump(LOG_REPORT, 0, "sa_report", sa);
756 sa_dump_all(FILE *fd, struct sa *sa)
759 fprintf(fd, "SA name: %s", sa->name ? sa->name : "<unnamed>");
760 fprintf(fd, " (Phase %d%s)\n", sa->phase, sa->phase == 1 ?
761 (sa->initiator ? "/Initiator" : "/Responder") : "");
764 fprintf(fd, "%s", sa->transport == NULL ? "<no transport>" :
765 sa->transport->vtbl->decode_ids(sa->transport));
769 report_lifetimes(fd, sa);
771 fprintf(fd, "Flags 0x%08x\n", sa->flags);
773 if (sa->phase == 1)
774 report_phase1(fd, sa);
775 else if (sa->phase == 2)
776 report_phase2(fd, sa);
790 struct sa *sa;
794 for (sa = LIST_FIRST(&sa_tab[i]); sa; sa = LIST_NEXT(sa, link))
795 sa_dump_all(fd, sa);
803 struct sa *sa = proto->sa;
808 if (sa->doi->delete_spi)
809 sa->doi->delete_spi(sa, proto, i);
812 TAILQ_REMOVE(&sa->protos, proto, link);
814 if (sa->doi && sa->doi->free_proto_data)
815 sa->doi->free_proto_data(proto->data);
831 sa_free(struct sa *sa)
833 if (sa->death) {
834 timer_remove_event(sa->death);
835 sa->death = 0;
836 sa->refcnt--;
838 if (sa->soft_death) {
839 timer_remove_event(sa->soft_death);
840 sa->soft_death = 0;
841 sa->refcnt--;
843 if (sa->dpd_event) {
844 timer_remove_event(sa->dpd_event);
845 sa->dpd_event = 0;
847 sa_remove(sa);
852 sa_remove(struct sa *sa)
854 LIST_REMOVE(sa, link);
855 LOG_DBG((LOG_SA, 70, "sa_remove: SA %p removed from SA list", sa));
856 sa_release(sa);
861 sa_reference(struct sa *sa)
863 sa->refcnt++;
865 sa, sa->refcnt));
870 sa_release(struct sa *sa)
876 sa, sa->refcnt));
878 if (--sa->refcnt)
881 LOG_DBG((LOG_SA, 60, "sa_release: freeing SA %p", sa));
883 while ((proto = TAILQ_FIRST(&sa->protos)) != 0)
885 if (sa->data) {
886 if (sa->doi && sa->doi->free_sa_data)
887 sa->doi->free_sa_data(sa->data);
888 free(sa->data);
890 free(sa->id_i);
891 free(sa->id_r);
892 if (sa->recv_cert) {
893 handler = cert_get(sa->recv_certtype);
895 handler->cert_free(sa->recv_cert);
897 if (sa->sent_cert) {
898 handler = cert_get(sa->sent_certtype);
900 handler->cert_free(sa->sent_cert);
902 if (sa->recv_key)
903 key_free(sa->recv_keytype, ISAKMP_KEYTYPE_PUBLIC,
904 sa->recv_key);
905 free(sa->keynote_key); /* This is just a string */
906 if (sa->policy_id != -1)
907 kn_close(sa->policy_id);
908 free(sa->name);
909 free(sa->keystate);
910 if (sa->nat_t_keepalive)
911 timer_remove_event(sa->nat_t_keepalive);
912 if (sa->dpd_event)
913 timer_remove_event(sa->dpd_event);
914 if (sa->transport)
915 transport_release(sa->transport);
916 free(sa->tag);
917 free(sa);
927 struct sa *sa = TAILQ_FIRST(&msg->exchange->sa_list);
929 sa_remove(sa);
931 sa->cookies + ISAKMP_HDR_ICOOKIE_LEN);
937 sa->transport = msg->transport;
938 transport_reference(sa->transport);
939 sa_enter(sa);
1089 sa_add_transform(struct sa *sa, struct payload *xf, int initiator,
1111 for (proto = TAILQ_FIRST(&sa->protos);
1119 if (!proto || sa_validate_proto_xf(proto, xf, sa->phase) != 0)
1120 for (proto = TAILQ_FIRST(&sa->protos);
1121 proto && sa_validate_proto_xf(proto, xf, sa->phase) != 0;
1131 proto->data = calloc(1, sa->doi->proto_size);
1134 (unsigned long)sa->doi->proto_size);
1149 proto->sa = sa;
1152 TAILQ_INSERT_TAIL(&sa->protos, proto, link);
1155 if (sa->doi->proto_init)
1156 sa->doi->proto_init(proto, 0);
1160 "proto %p no %d proto %d chosen %p sa %p id %d",
1161 proto, proto->no, proto->proto, proto->chosen, proto->sa,
1177 sa_delete(struct sa *sa, int notify)
1180 message_send_delete(sa);
1181 sa_free(sa);
1190 struct sa *sa, *next = 0;
1195 for (sa = LIST_FIRST(&sa_tab[i]); sa; sa = next) {
1196 next = LIST_NEXT(sa, link);
1197 if (sa->phase == 2) {
1204 sa->name ? sa->name : "<unnamed>"));
1205 if (sa->name)
1206 connection_teardown(sa->name);
1207 sa_delete(sa, 1);
1218 struct sa *sa = v_sa;
1220 sa->soft_death = 0;
1221 sa_release(sa);
1223 if ((sa->flags & (SA_FLAG_STAYALIVE | SA_FLAG_REPLACED)) ==
1225 exchange_establish(sa->name, 0, 0, 1);
1231 sa->flags |= SA_FLAG_FADING;
1238 struct sa *sa = v_sa;
1240 sa->death = 0;
1241 sa_release(sa);
1243 if ((sa->flags & (SA_FLAG_STAYALIVE | SA_FLAG_REPLACED)) ==
1245 exchange_establish(sa->name, 0, 0, 1);
1247 sa_delete(sa, 1);
1253 struct sa *sa;
1270 for (sa = LIST_FIRST(&sa_tab[i]); sa; sa = LIST_NEXT(sa, link))
1271 if (sa->phase == 2)
1272 if (exchange_lookup_by_name(sa->name,
1273 sa->phase) == 0 && sa->soft_death) {
1274 timer_remove_event(sa->soft_death);
1275 sa_soft_expire(sa);
1315 sa_mark_replaced(struct sa *sa)
1318 sa, sa->name ? sa->name : "unnamed"));
1319 if (sa->dpd_event) {
1320 timer_remove_event(sa->dpd_event);
1321 sa->dpd_event = 0;
1323 sa->flags |= SA_FLAG_REPLACED;
1328 sa_replace(struct sa *sa, struct sa *new_sa)
1331 sa, sa->name ? sa->name : "unnamed",
1333 sa_mark_replaced(sa);
1349 sa_setup_expirations(struct sa *sa)
1352 u_int64_t seconds = sa->seconds;
1364 if (!sa->soft_death) {
1370 seconds = sa->seconds * (850 + arc4random_uniform(100)) / 1000;
1373 sa, seconds));
1375 sa->soft_death = timer_add_event("sa_soft_expire",
1376 sa_soft_expire, sa, &expiration);
1377 if (!sa->soft_death) {
1379 sa_delete(sa, 1);
1382 sa_reference(sa);
1384 if (!sa->death) {
1388 sa, sa->seconds));
1389 expiration.tv_sec += sa->seconds;
1390 sa->death = timer_add_event("sa_hard_expire", sa_hard_expire,
1391 sa, &expiration);
1392 if (!sa->death) {
1394 sa_delete(sa, 1);
1397 sa_reference(sa);