fixed cert_validator_t:validate interface
[strongswan.git] / src / libcharon / plugins / addrblock / addrblock_narrow.c
1 /*
2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
4 * Copyright (C) 2009 Andreas Steffen
5 * Hochschule fuer Technik Rapperswil
6 *
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>.
11 *
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
15 * for more details.
16 */
17
18 #include "addrblock_narrow.h"
19
20 #include <daemon.h>
21 #include <credentials/certificates/x509.h>
22
23 typedef struct private_addrblock_narrow_t private_addrblock_narrow_t;
24
25 /**
26 * Private data of an addrblock_narrow_t object.
27 */
28 struct private_addrblock_narrow_t {
29
30 /**
31 * Public addrblock_narrow_t interface.
32 */
33 addrblock_narrow_t public;
34 };
35
36 /**
37 * Check if the negotiated TS list is acceptable by X509 ipAddrBlock constraints
38 */
39 static bool check_constraints(ike_sa_t *ike_sa, linked_list_t *list)
40 {
41 auth_cfg_t *auth;
42 enumerator_t *auth_enum;
43 certificate_t *cert = NULL;
44
45 auth_enum = ike_sa->create_auth_cfg_enumerator(ike_sa, FALSE);
46 while (auth_enum->enumerate(auth_enum, &auth))
47 {
48 cert = auth->get(auth, AUTH_HELPER_SUBJECT_CERT);
49 if (cert)
50 {
51 break;
52 }
53 }
54 auth_enum->destroy(auth_enum);
55
56 if (cert && cert->get_type(cert) == CERT_X509)
57 {
58 x509_t *x509 = (x509_t*)cert;
59
60 if (x509->get_flags(x509) & X509_IP_ADDR_BLOCKS)
61 {
62 enumerator_t *enumerator, *block_enum;
63 traffic_selector_t *ts, *block_ts;
64
65 DBG1(DBG_IKE, "checking certificate-based traffic selector "
66 "constraints [RFC 3779]");
67 enumerator = list->create_enumerator(list);
68 while (enumerator->enumerate(enumerator, &ts))
69 {
70 bool contained = FALSE;
71
72 block_enum = x509->create_ipAddrBlock_enumerator(x509);
73 while (block_enum->enumerate(block_enum, &block_ts))
74 {
75 if (ts->is_contained_in(ts, block_ts))
76 {
77 DBG1(DBG_IKE, " TS %R is contained in address block"
78 " constraint %R", ts, block_ts);
79 contained = TRUE;
80 break;
81 }
82 }
83 block_enum->destroy(block_enum);
84
85 if (!contained)
86 {
87 DBG1(DBG_IKE, " TS %R is not contained in any"
88 " address block constraint", ts);
89 enumerator->destroy(enumerator);
90 return FALSE;
91 }
92 }
93 enumerator->destroy(enumerator);
94 }
95 }
96 return TRUE;
97 }
98
99 /**
100 * Delete all traffic selectors in a list
101 */
102 static void flush_ts_list(linked_list_t *list)
103 {
104 traffic_selector_t *ts;
105
106 while (list->remove_last(list, (void**)&ts) == SUCCESS)
107 {
108 ts->destroy(ts);
109 }
110 }
111
112 METHOD(listener_t, narrow, bool,
113 private_addrblock_narrow_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
114 narrow_hook_t type, linked_list_t *local, linked_list_t *remote)
115 {
116 switch (type)
117 {
118 case NARROW_RESPONDER:
119 case NARROW_INITIATOR_POST_AUTH:
120 case NARROW_INITIATOR_POST_NOAUTH:
121 if (!check_constraints(ike_sa, remote))
122 {
123 flush_ts_list(local);
124 flush_ts_list(remote);
125 }
126 break;
127 default:
128 break;
129 }
130 return TRUE;
131 }
132
133 METHOD(addrblock_narrow_t, destroy, void,
134 private_addrblock_narrow_t *this)
135 {
136 free(this);
137 }
138
139 /**
140 * See header
141 */
142 addrblock_narrow_t *addrblock_narrow_create()
143 {
144 private_addrblock_narrow_t *this;
145
146 INIT(this,
147 .public = {
148 .listener.narrow = _narrow,
149 .destroy = _destroy,
150 },
151 );
152
153 return &this->public;
154 }