|
|
1.1 misho 1: /*
2: * Copyright (C) 2012 Martin Willi
3: * Copyright (C) 2012 revosec AG
4: *
5: * This program is free software; you can redistribute it and/or modify it
6: * under the terms of the GNU General Public License as published by the
7: * Free Software Foundation; either version 2 of the License, or (at your
8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9: *
10: * This program is distributed in the hope that it will be useful, but
11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13: * for more details.
14: */
15:
16: #include "error_notify_listener.h"
17:
18: #include <daemon.h>
19:
20: typedef struct private_error_notify_listener_t private_error_notify_listener_t;
21:
22: /**
23: * Private data of an error_notify_listener_t object.
24: */
25: struct private_error_notify_listener_t {
26:
27: /**
28: * Public error_notify_listener_t interface.
29: */
30: error_notify_listener_t public;
31:
32: /**
33: * Socket to send notifications over
34: */
35: error_notify_socket_t *socket;
36: };
37:
38: METHOD(listener_t, alert, bool,
39: private_error_notify_listener_t *this, ike_sa_t *ike_sa,
40: alert_t alert, va_list args)
41: {
42: error_notify_msg_t msg;
43: message_t *message;
44: host_t *host;
45: identification_t *id;
46: linked_list_t *list, *list2;
47: peer_cfg_t *peer_cfg;
48: certificate_t *cert;
49: time_t not_before, not_after;
50:
51: if (!this->socket->has_listeners(this->socket))
52: {
53: return TRUE;
54: }
55:
56: memset(&msg, 0, sizeof(msg));
57:
58: switch (alert)
59: {
60: case ALERT_RADIUS_NOT_RESPONDING:
61: msg.type = htonl(ERROR_NOTIFY_RADIUS_NOT_RESPONDING);
62: snprintf(msg.str, sizeof(msg.str),
63: "a RADIUS request message timed out");
64: break;
65: case ALERT_LOCAL_AUTH_FAILED:
66: msg.type = htonl(ERROR_NOTIFY_LOCAL_AUTH_FAILED);
67: snprintf(msg.str, sizeof(msg.str),
68: "creating local authentication data failed");
69: break;
70: case ALERT_PEER_AUTH_FAILED:
71: msg.type = htonl(ERROR_NOTIFY_PEER_AUTH_FAILED);
72: snprintf(msg.str, sizeof(msg.str), "peer authentication failed");
73: break;
74: case ALERT_PARSE_ERROR_HEADER:
75: msg.type = htonl(ERROR_NOTIFY_PARSE_ERROR_HEADER);
76: message = va_arg(args, message_t*);
77: snprintf(msg.str, sizeof(msg.str), "parsing IKE header from "
78: "%#H failed", message->get_source(message));
79: break;
80: case ALERT_PARSE_ERROR_BODY:
81: msg.type = htonl(ERROR_NOTIFY_PARSE_ERROR_BODY);
82: message = va_arg(args, message_t*);
83: snprintf(msg.str, sizeof(msg.str), "parsing IKE message from "
84: "%#H failed", message->get_source(message));
85: break;
86: case ALERT_RETRANSMIT_SEND:
87: msg.type = htonl(ERROR_NOTIFY_RETRANSMIT_SEND);
88: snprintf(msg.str, sizeof(msg.str), "IKE message retransmission "
89: "number %u", va_arg(args, u_int));
90: break;
91: case ALERT_RETRANSMIT_SEND_TIMEOUT:
92: msg.type = htonl(ERROR_NOTIFY_RETRANSMIT_SEND_TIMEOUT);
93: snprintf(msg.str, sizeof(msg.str),
94: "IKE message retransmission timed out");
95: break;
96: case ALERT_HALF_OPEN_TIMEOUT:
97: msg.type = htonl(ERROR_NOTIFY_HALF_OPEN_TIMEOUT);
98: snprintf(msg.str, sizeof(msg.str), "IKE_SA timed out before it "
99: "could be established");
100: break;
101: case ALERT_PROPOSAL_MISMATCH_IKE:
102: msg.type = htonl(ERROR_NOTIFY_PROPOSAL_MISMATCH_IKE);
103: list = va_arg(args, linked_list_t*);
104: snprintf(msg.str, sizeof(msg.str), "the received IKE_SA proposals "
105: "did not match: %#P", list);
106: break;
107: case ALERT_PROPOSAL_MISMATCH_CHILD:
108: msg.type = htonl(ERROR_NOTIFY_PROPOSAL_MISMATCH_CHILD);
109: list = va_arg(args, linked_list_t*);
110: snprintf(msg.str, sizeof(msg.str), "the received CHILD_SA proposals "
111: "did not match: %#P", list);
112: break;
113: case ALERT_TS_MISMATCH:
114: msg.type = htonl(ERROR_NOTIFY_TS_MISMATCH);
115: list = va_arg(args, linked_list_t*);
116: list2 = va_arg(args, linked_list_t*);
117: snprintf(msg.str, sizeof(msg.str), "the received traffic selectors "
118: "did not match: %#R === %#R", list, list2);
119: break;
120: case ALERT_INSTALL_CHILD_SA_FAILED:
121: msg.type = htonl(ERROR_NOTIFY_INSTALL_CHILD_SA_FAILED);
122: snprintf(msg.str, sizeof(msg.str), "installing IPsec SA failed");
123: break;
124: case ALERT_INSTALL_CHILD_POLICY_FAILED:
125: msg.type = htonl(ERROR_NOTIFY_INSTALL_CHILD_POLICY_FAILED);
126: snprintf(msg.str, sizeof(msg.str), "installing IPsec policy failed");
127: break;
128: case ALERT_UNIQUE_REPLACE:
129: msg.type = htonl(ERROR_NOTIFY_UNIQUE_REPLACE);
130: snprintf(msg.str, sizeof(msg.str),
131: "replaced old IKE_SA due to uniqueness policy");
132: break;
133: case ALERT_UNIQUE_KEEP:
134: msg.type = htonl(ERROR_NOTIFY_UNIQUE_KEEP);
135: snprintf(msg.str, sizeof(msg.str), "keep existing in favor of "
136: "rejected new IKE_SA due to uniqueness policy");
137: break;
138: case ALERT_VIP_FAILURE:
139: msg.type = htonl(ERROR_NOTIFY_VIP_FAILURE);
140: list = va_arg(args, linked_list_t*);
141: if (list->get_first(list, (void**)&host) == SUCCESS)
142: {
143: snprintf(msg.str, sizeof(msg.str),
144: "allocating a virtual IP failed, requested was %H", host);
145: }
146: else
147: {
148: snprintf(msg.str, sizeof(msg.str),
149: "expected a virtual IP request, but none found");
150: }
151: break;
152: case ALERT_AUTHORIZATION_FAILED:
153: msg.type = htonl(ERROR_NOTIFY_AUTHORIZATION_FAILED);
154: snprintf(msg.str, sizeof(msg.str), "an authorization plugin "
155: "prevented establishment of an IKE_SA");
156: break;
157: case ALERT_CERT_EXPIRED:
158: msg.type = htonl(ERROR_NOTIFY_CERT_EXPIRED);
159: cert = va_arg(args, certificate_t*);
160: cert->get_validity(cert, NULL, ¬_before, ¬_after);
161: snprintf(msg.str, sizeof(msg.str), "certificate expired: '%Y' "
162: "(valid from %T to %T)", cert->get_subject(cert),
163: ¬_before, TRUE, ¬_after, TRUE);
164: break;
165: case ALERT_CERT_REVOKED:
166: msg.type = htonl(ERROR_NOTIFY_CERT_REVOKED);
167: cert = va_arg(args, certificate_t*);
168: snprintf(msg.str, sizeof(msg.str), "certificate revoked: '%Y'",
169: cert->get_subject(cert));
170: break;
171: case ALERT_CERT_NO_ISSUER:
172: msg.type = htonl(ERROR_NOTIFY_NO_ISSUER_CERT);
173: cert = va_arg(args, certificate_t*);
174: snprintf(msg.str, sizeof(msg.str), "no trusted issuer certificate "
175: "found: '%Y'", cert->get_issuer(cert));
176: break;
177: default:
178: return TRUE;
179: }
180:
181: if (ike_sa)
182: {
183: id = ike_sa->get_other_eap_id(ike_sa);
184: if (id->get_type(id) != ID_ANY)
185: {
186: snprintf(msg.id, sizeof(msg.id), "%Y", id);
187: }
188: host = ike_sa->get_other_host(ike_sa);
189: if (!host->is_anyaddr(host))
190: {
191: snprintf(msg.ip, sizeof(msg.ip), "%#H", host);
192: }
193: peer_cfg = ike_sa->get_peer_cfg(ike_sa);
194: if (peer_cfg)
195: {
196: snprintf(msg.name, sizeof(msg.name), "%s",
197: peer_cfg->get_name(peer_cfg));
198: }
199: }
200:
201: this->socket->notify(this->socket, &msg);
202:
203: return TRUE;
204: }
205:
206: METHOD(error_notify_listener_t, destroy, void,
207: private_error_notify_listener_t *this)
208: {
209: free(this);
210: }
211:
212: /**
213: * See header
214: */
215: error_notify_listener_t *error_notify_listener_create(error_notify_socket_t *s)
216: {
217: private_error_notify_listener_t *this;
218:
219: INIT(this,
220: .public = {
221: .listener = {
222: .alert = _alert,
223: },
224: .destroy = _destroy,
225: },
226: .socket = s,
227: );
228:
229: return &this->public;
230: }