summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2015-11-18 14:49:27 +0100
committerYves-Alexis Perez <corsac@debian.org>2015-11-18 14:49:27 +0100
commit1e980d6be0ef0e243c6fe82b5e855454b97e24a4 (patch)
tree0d59eec2ce2ed332434ae80fc78a44db9ad293c5 /src/libcharon/plugins
parent5dca9ea0e2931f0e2a056c7964d311bcc30a01b8 (diff)
downloadvyos-strongswan-1e980d6be0ef0e243c6fe82b5e855454b97e24a4.tar.gz
vyos-strongswan-1e980d6be0ef0e243c6fe82b5e855454b97e24a4.zip
Imported Upstream version 5.3.4
Diffstat (limited to 'src/libcharon/plugins')
-rw-r--r--src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c115
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_provider.c32
-rw-r--r--src/libcharon/plugins/error_notify/error_notify_listener.c2
-rw-r--r--src/libcharon/plugins/ha/ha_child.c2
-rw-r--r--src/libcharon/plugins/ha/ha_dispatcher.c2
-rw-r--r--src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c7
-rw-r--r--src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c9
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_ipsec.c5
-rw-r--r--src/libcharon/plugins/socket_default/socket_default_socket.c281
-rw-r--r--src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c94
-rw-r--r--src/libcharon/plugins/stroke/stroke_config.c6
-rw-r--r--src/libcharon/plugins/stroke/stroke_control.c71
-rw-r--r--src/libcharon/plugins/stroke/stroke_list.c6
-rw-r--r--src/libcharon/plugins/vici/README.md21
-rw-r--r--src/libcharon/plugins/vici/vici_attribute.c28
-rw-r--r--src/libcharon/plugins/vici/vici_cred.c12
-rw-r--r--src/libcharon/plugins/vici/vici_query.c47
17 files changed, 536 insertions, 204 deletions
diff --git a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c
index f7f39f984..16978f486 100644
--- a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c
+++ b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Tobias Brunner
+ * Copyright (C) 2009-2015 Tobias Brunner
* Copyright (C) 2010 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -81,6 +81,21 @@ struct private_eap_mschapv2_t
* Number of retries
*/
int retries;
+
+ /**
+ * Provide EAP-Identity
+ */
+ auth_cfg_t *auth;
+
+ /**
+ * Current state
+ */
+ enum {
+ S_EXPECT_CHALLENGE,
+ S_EXPECT_RESPONSE,
+ S_EXPECT_SUCCESS,
+ S_DONE,
+ } state;
};
/**
@@ -628,6 +643,7 @@ METHOD(eap_method_t, initiate_server, status_t,
memcpy(cha->name, name, sizeof(MSCHAPV2_HOST_NAME) - 1);
*out = eap_payload_create_data(chunk_create((void*) eap, len));
+ this->state = S_EXPECT_RESPONSE;
return NEED_MORE;
}
@@ -747,6 +763,7 @@ static status_t process_peer_challenge(private_eap_mschapv2_t *this,
memcpy(res->name, userid.ptr, userid.len);
*out = eap_payload_create_data(chunk_create((void*) eap, len));
+ this->state = S_EXPECT_SUCCESS;
return NEED_MORE;
}
@@ -829,6 +846,7 @@ static status_t process_peer_success(private_eap_mschapv2_t *this,
*out = eap_payload_create_data(chunk_create((void*) eap, len));
status = NEED_MORE;
+ this->state = S_DONE;
error:
chunk_free(&auth_string);
@@ -922,6 +940,7 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
*/
status = FAILED;
+ this->state = S_DONE;
error:
chunk_free(&challenge);
@@ -946,26 +965,38 @@ METHOD(eap_method_t, process_peer, status_t,
eap = (eap_mschapv2_header_t*)data.ptr;
+ switch (this->state)
+ {
+ case S_EXPECT_CHALLENGE:
+ if (eap->opcode == MSCHAPV2_CHALLENGE)
+ {
+ return process_peer_challenge(this, in, out);
+ }
+ break;
+ case S_EXPECT_SUCCESS:
+ switch (eap->opcode)
+ {
+ case MSCHAPV2_SUCCESS:
+ return process_peer_success(this, in, out);
+ case MSCHAPV2_FAILURE:
+ return process_peer_failure(this, in, out);
+ }
+ break;
+ default:
+ break;
+ }
switch (eap->opcode)
{
case MSCHAPV2_CHALLENGE:
- {
- return process_peer_challenge(this, in, out);
- }
case MSCHAPV2_SUCCESS:
- {
- return process_peer_success(this, in, out);
- }
case MSCHAPV2_FAILURE:
- {
- return process_peer_failure(this, in, out);
- }
+ DBG1(DBG_IKE, "received unexpected EAP-MS-CHAPv2 message with "
+ "OpCode (%N)!", mschapv2_opcode_names, eap->opcode);
+ break;
default:
- {
DBG1(DBG_IKE, "EAP-MS-CHAPv2 received packet with unsupported "
"OpCode (%N)!", mschapv2_opcode_names, eap->opcode);
break;
- }
}
return FAILED;
}
@@ -1027,6 +1058,8 @@ static status_t process_server_retry(private_eap_mschapv2_t *this,
/* delay the response for some time to make brute-force attacks harder */
sleep(RETRY_DELAY);
+ /* since the error is retryable the state does not change, we still
+ * expect an MSCHAPV2_RESPONSE from the peer */
return NEED_MORE;
}
@@ -1058,7 +1091,10 @@ static status_t process_server_response(private_eap_mschapv2_t *this,
name_len = min(data.len - RESPONSE_PAYLOAD_LEN, 255);
snprintf(buf, sizeof(buf), "%.*s", name_len, res->name);
userid = identification_create_from_string(buf);
- DBG2(DBG_IKE, "EAP-MS-CHAPv2 username: '%Y'", userid);
+ if (!userid->equals(userid, this->peer))
+ {
+ DBG1(DBG_IKE, "EAP-MS-CHAPv2 username: '%Y'", userid);
+ }
/* userid can only be destroyed after the last use of username */
username = extract_username(userid->get_encoding(userid));
@@ -1084,7 +1120,6 @@ static status_t process_server_response(private_eap_mschapv2_t *this,
chunk_clear(&nt_hash);
return FAILED;
}
- userid->destroy(userid);
chunk_clear(&nt_hash);
if (memeq_const(res->response.nt_response, this->nt_response.ptr,
@@ -1109,9 +1144,12 @@ static status_t process_server_response(private_eap_mschapv2_t *this,
chunk_free(&hex);
memcpy(eap->data, msg, AUTH_RESPONSE_LEN + sizeof(SUCCESS_MESSAGE));
*out = eap_payload_create_data(chunk_create((void*) eap, len));
+
+ this->auth->add(this->auth, AUTH_RULE_EAP_IDENTITY, userid);
+ this->state = S_EXPECT_SUCCESS;
return NEED_MORE;
}
-
+ userid->destroy(userid);
return process_server_retry(this, out);
}
@@ -1137,26 +1175,39 @@ METHOD(eap_method_t, process_server, status_t,
eap = (eap_mschapv2_header_t*)data.ptr;
+ switch (this->state)
+ {
+ case S_EXPECT_RESPONSE:
+ if (eap->opcode == MSCHAPV2_RESPONSE)
+ {
+ return process_server_response(this, in, out);
+ }
+ break;
+ case S_EXPECT_SUCCESS:
+ if (eap->opcode == MSCHAPV2_SUCCESS &&
+ this->msk.ptr)
+ {
+ return SUCCESS;
+ }
+ break;
+ default:
+ break;
+ }
switch (eap->opcode)
{
- case MSCHAPV2_RESPONSE:
- {
- return process_server_response(this, in, out);
- }
- case MSCHAPV2_SUCCESS:
- {
- return SUCCESS;
- }
case MSCHAPV2_FAILURE:
- {
+ /* the client may abort the authentication by sending us a failure
+ * in any state */
return FAILED;
- }
+ case MSCHAPV2_RESPONSE:
+ case MSCHAPV2_SUCCESS:
+ DBG1(DBG_IKE, "received unexpected EAP-MS-CHAPv2 message with "
+ "OpCode (%N)!", mschapv2_opcode_names, eap->opcode);
+ break;
default:
- {
DBG1(DBG_IKE, "EAP-MS-CHAPv2 received packet with unsupported "
"OpCode (%N)!", mschapv2_opcode_names, eap->opcode);
break;
- }
}
return FAILED;
}
@@ -1197,11 +1248,18 @@ METHOD(eap_method_t, is_mutual, bool,
return FALSE;
}
+METHOD(eap_method_t, get_auth, auth_cfg_t*,
+ private_eap_mschapv2_t *this)
+{
+ return this->auth;
+}
+
METHOD(eap_method_t, destroy, void,
private_eap_mschapv2_t *this)
{
this->peer->destroy(this->peer);
this->server->destroy(this->server);
+ this->auth->destroy(this->auth);
chunk_free(&this->challenge);
chunk_free(&this->nt_response);
chunk_free(&this->auth_response);
@@ -1224,11 +1282,14 @@ static private_eap_mschapv2_t *eap_mschapv2_create_generic(identification_t *ser
.get_msk = _get_msk,
.get_identifier = _get_identifier,
.set_identifier = _set_identifier,
+ .get_auth = _get_auth,
.destroy = _destroy,
},
},
.peer = peer->clone(peer),
.server = server->clone(server),
+ .auth = auth_cfg_create(),
+ .state = S_EXPECT_CHALLENGE,
);
return this;
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_provider.c b/src/libcharon/plugins/eap_radius/eap_radius_provider.c
index 0cf723711..0f207fbe6 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_provider.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_provider.c
@@ -178,18 +178,38 @@ static void add_addr(private_eap_radius_provider_t *this,
* Remove the next address from the locked hashtable stored for given id
*/
static host_t* remove_addr(private_eap_radius_provider_t *this,
- hashtable_t *hashtable, uintptr_t id)
+ hashtable_t *hashtable, uintptr_t id, host_t *addr)
{
+ enumerator_t *enumerator;
entry_t *entry;
- host_t *addr = NULL;
+ host_t *found = NULL, *current;
entry = hashtable->remove(hashtable, (void*)id);
if (entry)
{
- entry->addrs->remove_first(entry->addrs, (void**)&addr);
+ enumerator = entry->addrs->create_enumerator(entry->addrs);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (addr->ip_equals(addr, current))
+ { /* prefer an exact match */
+ entry->addrs->remove_at(entry->addrs, enumerator);
+ enumerator->destroy(enumerator);
+ put_or_destroy_entry(hashtable, entry);
+ return current;
+ }
+ if (!found && addr->get_family(addr) == current->get_family(current))
+ { /* fallback to the first IP with a matching address family */
+ found = current;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (found)
+ {
+ entry->addrs->remove(entry->addrs, found, NULL);
+ }
put_or_destroy_entry(hashtable, entry);
}
- return addr;
+ return found;
}
/**
@@ -326,7 +346,7 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
if (streq(name, "radius"))
{
this->listener.mutex->lock(this->listener.mutex);
- addr = remove_addr(this, this->listener.unclaimed, sa);
+ addr = remove_addr(this, this->listener.unclaimed, sa, requested);
if (addr)
{
add_addr(this, this->listener.claimed, sa, addr->clone(addr));
@@ -357,7 +377,7 @@ METHOD(attribute_provider_t, release_address, bool,
if (streq(name, "radius"))
{
this->listener.mutex->lock(this->listener.mutex);
- found = remove_addr(this, this->listener.claimed, sa);
+ found = remove_addr(this, this->listener.claimed, sa, address);
this->listener.mutex->unlock(this->listener.mutex);
break;
}
diff --git a/src/libcharon/plugins/error_notify/error_notify_listener.c b/src/libcharon/plugins/error_notify/error_notify_listener.c
index f7a1f49ec..ce577c62c 100644
--- a/src/libcharon/plugins/error_notify/error_notify_listener.c
+++ b/src/libcharon/plugins/error_notify/error_notify_listener.c
@@ -110,7 +110,7 @@ METHOD(listener_t, alert, bool,
list = va_arg(args, linked_list_t*);
list2 = va_arg(args, linked_list_t*);
snprintf(msg.str, sizeof(msg.str), "the received traffic selectors "
- "did not match: %#R=== %#R", list, list2);
+ "did not match: %#R === %#R", list, list2);
break;
case ALERT_INSTALL_CHILD_SA_FAILED:
msg.type = htonl(ERROR_NOTIFY_INSTALL_CHILD_SA_FAILED);
diff --git a/src/libcharon/plugins/ha/ha_child.c b/src/libcharon/plugins/ha/ha_child.c
index 17f2d50d1..dbb6adc8f 100644
--- a/src/libcharon/plugins/ha/ha_child.c
+++ b/src/libcharon/plugins/ha/ha_child.c
@@ -126,7 +126,7 @@ METHOD(listener_t, child_keys, bool,
ike_sa->get_my_host(ike_sa), child_sa->get_spi(child_sa, TRUE));
seg_o = this->kernel->get_segment_spi(this->kernel,
ike_sa->get_other_host(ike_sa), child_sa->get_spi(child_sa, FALSE));
- DBG1(DBG_CFG, "handling HA CHILD_SA %s{%d} %#R=== %#R "
+ DBG1(DBG_CFG, "handling HA CHILD_SA %s{%d} %#R === %#R "
"(segment in: %d%s, out: %d%s)", child_sa->get_name(child_sa),
child_sa->get_unique_id(child_sa), local_ts, remote_ts,
seg_i, this->segments->is_active(this->segments, seg_i) ? "*" : "",
diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c
index afa099309..07ef607c6 100644
--- a/src/libcharon/plugins/ha/ha_dispatcher.c
+++ b/src/libcharon/plugins/ha/ha_dispatcher.c
@@ -848,7 +848,7 @@ static void process_child_add(private_ha_dispatcher_t *this,
seg_o = this->kernel->get_segment_spi(this->kernel,
ike_sa->get_other_host(ike_sa), outbound_spi);
- DBG1(DBG_CFG, "installed HA CHILD_SA %s{%d} %#R=== %#R "
+ DBG1(DBG_CFG, "installed HA CHILD_SA %s{%d} %#R === %#R "
"(segment in: %d%s, out: %d%s)", child_sa->get_name(child_sa),
child_sa->get_unique_id(child_sa), local_ts, remote_ts,
seg_i, this->segments->is_active(this->segments, seg_i) ? "*" : "",
diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
index 6246dc505..d738e6d13 100644
--- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
+++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
@@ -563,15 +563,16 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
}
METHOD(kernel_ipsec_t, del_policy, status_t,
- private_kernel_libipsec_ipsec_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
+ private_kernel_libipsec_ipsec_t *this, host_t *src, host_t *dst,
+ traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+ policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
mark_t mark, policy_priority_t priority)
{
policy_entry_t *policy, *found = NULL;
status_t status;
status = ipsec->policies->del_policy(ipsec->policies, src_ts, dst_ts,
- direction, reqid, mark, priority);
+ direction, sa->reqid, mark, priority);
policy = create_policy_entry(src_ts, dst_ts, direction);
diff --git a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c
index b38ded846..95f79f168 100644
--- a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c
+++ b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c
@@ -2456,15 +2456,16 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
}
METHOD(kernel_ipsec_t, del_policy, status_t,
- private_kernel_wfp_ipsec_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
+ private_kernel_wfp_ipsec_t *this, host_t *src, host_t *dst,
+ traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+ policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
mark_t mark, policy_priority_t priority)
{
if (direction == POLICY_OUT && priority == POLICY_PRIORITY_ROUTED)
{
- if (remove_trap(this, reqid, FALSE, src_ts, dst_ts))
+ if (remove_trap(this, sa->reqid, FALSE, src_ts, dst_ts))
{
- remove_trap(this, reqid, TRUE, src_ts, dst_ts);
+ remove_trap(this, sa->reqid, TRUE, src_ts, dst_ts);
return SUCCESS;
}
return NOT_FOUND;
diff --git a/src/libcharon/plugins/load_tester/load_tester_ipsec.c b/src/libcharon/plugins/load_tester/load_tester_ipsec.c
index 62d43e302..6a86bb899 100644
--- a/src/libcharon/plugins/load_tester/load_tester_ipsec.c
+++ b/src/libcharon/plugins/load_tester/load_tester_ipsec.c
@@ -103,8 +103,9 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
}
METHOD(kernel_ipsec_t, del_policy, status_t,
- private_load_tester_ipsec_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
+ private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
+ traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+ policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
mark_t mark, policy_priority_t priority)
{
return SUCCESS;
diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.c b/src/libcharon/plugins/socket_default/socket_default_socket.c
index dbfddbb81..13bf3e775 100644
--- a/src/libcharon/plugins/socket_default/socket_default_socket.c
+++ b/src/libcharon/plugins/socket_default/socket_default_socket.c
@@ -148,6 +148,91 @@ struct private_socket_default_socket_t {
u_int rr_counter;
};
+/**
+ * Get the destination IPv4 address of a received packet, depending on the
+ * available mechanism.
+ */
+#ifdef IP_PKTINFO
+
+static host_t *get_dst_v4(struct cmsghdr *cmsgptr, u_int16_t port)
+{
+ struct sockaddr_in dst = {
+ .sin_family = AF_INET,
+ .sin_port = htons(port),
+ };
+ struct in_pktinfo *pktinfo;
+ struct in_addr *addr;
+
+ if (cmsgptr->cmsg_type == IP_PKTINFO)
+ {
+ pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgptr);
+ addr = &pktinfo->ipi_addr;
+ memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr));
+ return host_create_from_sockaddr((sockaddr_t*)&dst);
+ }
+ return NULL;
+}
+
+#elif defined(IP_RECVDSTADDR)
+
+static host_t *get_dst_v4(struct cmsghdr *cmsgptr, u_int16_t port)
+{
+ struct sockaddr_in dst = {
+ .sin_family = AF_INET,
+ .sin_port = htons(port),
+ };
+ struct in_addr *addr;
+
+ if (cmsgptr->cmsg_type == IP_RECVDSTADDR)
+ {
+ addr = (struct in_addr*)CMSG_DATA(cmsgptr);
+ memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr));
+ return host_create_from_sockaddr((sockaddr_t*)&dst);
+ }
+ return NULL;
+}
+
+#else /* IP_PKTINFO || IP_RECVDSTADDR */
+
+static host_t *get_dst_v4(struct cmsghdr *cmsgptr, u_int16_t port)
+{
+ return NULL;
+}
+
+#endif /* IP_PKTINFO || IP_RECVDSTADDR */
+
+/**
+ * Get the destination IPv6 address of a received packet, depending on the
+ * available mechanism.
+ */
+#ifdef HAVE_IN6_PKTINFO
+
+static host_t *get_dst_v6(struct cmsghdr *cmsgptr, u_int16_t port)
+{
+ struct in6_pktinfo *pktinfo;
+ struct sockaddr_in6 dst = {
+ .sin6_family = AF_INET6,
+ .sin6_port = htons(port),
+ };
+
+ if (cmsgptr->cmsg_type == IPV6_PKTINFO)
+ {
+ pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsgptr);
+ memcpy(&dst.sin6_addr, &pktinfo->ipi6_addr, sizeof(dst.sin6_addr));
+ return host_create_from_sockaddr((sockaddr_t*)&dst);
+ }
+ return NULL;
+}
+
+#else /* HAVE_IN6_PKTINFO */
+
+static host_t *get_dst_v6(struct cmsghdr *cmsgptr, u_int16_t port)
+{
+ return NULL;
+}
+
+#endif /* HAVE_IN6_PKTINFO */
+
METHOD(socket_t, receiver, status_t,
private_socket_default_socket_t *this, packet_t **packet)
{
@@ -233,48 +318,13 @@ METHOD(socket_t, receiver, status_t,
DBG1(DBG_NET, "error reading ancillary data");
return FAILED;
}
-
-#ifdef HAVE_IN6_PKTINFO
- if (cmsgptr->cmsg_level == SOL_IPV6 &&
- cmsgptr->cmsg_type == IPV6_PKTINFO)
+ if (cmsgptr->cmsg_level == SOL_IP)
{
- struct in6_pktinfo *pktinfo;
- pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsgptr);
- struct sockaddr_in6 dst;
-
- memset(&dst, 0, sizeof(dst));
- memcpy(&dst.sin6_addr, &pktinfo->ipi6_addr, sizeof(dst.sin6_addr));
- dst.sin6_family = AF_INET6;
- dst.sin6_port = htons(port);
- dest = host_create_from_sockaddr((sockaddr_t*)&dst);
+ dest = get_dst_v4(cmsgptr, port);
}
-#endif /* HAVE_IN6_PKTINFO */
- if (cmsgptr->cmsg_level == SOL_IP &&
-#ifdef IP_PKTINFO
- cmsgptr->cmsg_type == IP_PKTINFO
-#elif defined(IP_RECVDSTADDR)
- cmsgptr->cmsg_type == IP_RECVDSTADDR
-#else
- FALSE
-#endif
- )
+ else if (cmsgptr->cmsg_level == SOL_IPV6)
{
- struct in_addr *addr;
- struct sockaddr_in dst;
-
-#ifdef IP_PKTINFO
- struct in_pktinfo *pktinfo;
- pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgptr);
- addr = &pktinfo->ipi_addr;
-#elif defined(IP_RECVDSTADDR)
- addr = (struct in_addr*)CMSG_DATA(cmsgptr);
-#endif
- memset(&dst, 0, sizeof(dst));
- memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr));
-
- dst.sin_family = AF_INET;
- dst.sin_port = htons(port);
- dest = host_create_from_sockaddr((sockaddr_t*)&dst);
+ dest = get_dst_v6(cmsgptr, port);
}
if (dest)
{
@@ -305,6 +355,107 @@ METHOD(socket_t, receiver, status_t,
return SUCCESS;
}
+/**
+ * Generic function to send a message.
+ */
+static ssize_t send_msg_generic(int skt, struct msghdr *msg)
+{
+ return sendmsg(skt, msg, 0);
+}
+
+/**
+ * Send a message with the IPv4 source address set, if possible.
+ */
+#ifdef IP_PKTINFO
+
+static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src)
+{
+ char buf[CMSG_SPACE(sizeof(struct in_pktinfo))] = {};
+ struct cmsghdr *cmsg;
+ struct in_addr *addr;
+ struct in_pktinfo *pktinfo;
+ struct sockaddr_in *sin;
+
+ msg->msg_control = buf;
+ msg->msg_controllen = sizeof(buf);
+ cmsg = CMSG_FIRSTHDR(msg);
+ cmsg->cmsg_level = SOL_IP;
+ cmsg->cmsg_type = IP_PKTINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+
+ pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
+ addr = &pktinfo->ipi_spec_dst;
+
+ sin = (struct sockaddr_in*)src->get_sockaddr(src);
+ memcpy(addr, &sin->sin_addr, sizeof(struct in_addr));
+ return send_msg_generic(skt, msg);
+}
+
+#elif defined(IP_SENDSRCADDR)
+
+static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src)
+{
+ char buf[CMSG_SPACE(sizeof(struct in_addr))] = {};
+ struct cmsghdr *cmsg;
+ struct in_addr *addr;
+ struct sockaddr_in *sin;
+
+ msg->msg_control = buf;
+ msg->msg_controllen = sizeof(buf);
+ cmsg = CMSG_FIRSTHDR(msg);
+ cmsg->cmsg_level = SOL_IP;
+ cmsg->cmsg_type = IP_SENDSRCADDR;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
+
+ addr = (struct in_addr*)CMSG_DATA(cmsg);
+
+ sin = (struct sockaddr_in*)src->get_sockaddr(src);
+ memcpy(addr, &sin->sin_addr, sizeof(struct in_addr));
+ return send_msg_generic(skt, msg);
+}
+
+#else /* IP_PKTINFO || IP_RECVDSTADDR */
+
+static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src)
+{
+ return send_msg_generic(skt, msg);
+}
+
+#endif /* IP_PKTINFO || IP_RECVDSTADDR */
+
+/**
+ * Send a message with the IPv6 source address set, if possible.
+ */
+#ifdef HAVE_IN6_PKTINFO
+
+static ssize_t send_msg_v6(int skt, struct msghdr *msg, host_t *src)
+{
+ char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))] = {};
+ struct cmsghdr *cmsg;
+ struct in6_pktinfo *pktinfo;
+ struct sockaddr_in6 *sin;
+
+ msg->msg_control = buf;
+ msg->msg_controllen = sizeof(buf);
+ cmsg = CMSG_FIRSTHDR(msg);
+ cmsg->cmsg_level = SOL_IPV6;
+ cmsg->cmsg_type = IPV6_PKTINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
+ pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg);
+ sin = (struct sockaddr_in6*)src->get_sockaddr(src);
+ memcpy(&pktinfo->ipi6_addr, &sin->sin6_addr, sizeof(struct in6_addr));
+ return send_msg_generic(skt, msg);
+}
+
+#else /* HAVE_IN6_PKTINFO */
+
+static ssize_t send_msg_v6(int skt, struct msghdr *msg, host_t *src)
+{
+ return send_msg_generic(skt, msg);
+}
+
+#endif /* HAVE_IN6_PKTINFO */
+
METHOD(socket_t, sender, status_t,
private_socket_default_socket_t *this, packet_t *packet)
{
@@ -313,7 +464,6 @@ METHOD(socket_t, sender, status_t,
chunk_t data;
host_t *src, *dst;
struct msghdr msg;
- struct cmsghdr *cmsg;
struct iovec iov;
u_int8_t *dscp;
@@ -415,56 +565,17 @@ METHOD(socket_t, sender, status_t,
{
if (family == AF_INET)
{
-#if defined(IP_PKTINFO) || defined(IP_SENDSRCADDR)
- struct in_addr *addr;
- struct sockaddr_in *sin;
-#ifdef IP_PKTINFO
- char buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
- struct in_pktinfo *pktinfo;
-#elif defined(IP_SENDSRCADDR)
- char buf[CMSG_SPACE(sizeof(struct in_addr))];
-#endif
- memset(buf, 0, sizeof(buf));
- msg.msg_control = buf;
- msg.msg_controllen = sizeof(buf);
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_level = SOL_IP;
-#ifdef IP_PKTINFO
- cmsg->cmsg_type = IP_PKTINFO;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
- pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
- addr = &pktinfo->ipi_spec_dst;
-#elif defined(IP_SENDSRCADDR)
- cmsg->cmsg_type = IP_SENDSRCADDR;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
- addr = (struct in_addr*)CMSG_DATA(cmsg);
-#endif
- sin = (struct sockaddr_in*)src->get_sockaddr(src);
- memcpy(addr, &sin->sin_addr, sizeof(struct in_addr));
-#endif /* IP_PKTINFO || IP_SENDSRCADDR */
+ bytes_sent = send_msg_v4(skt, &msg, src);
}
-#ifdef HAVE_IN6_PKTINFO
else
{
- char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
- struct in6_pktinfo *pktinfo;
- struct sockaddr_in6 *sin;
-
- memset(buf, 0, sizeof(buf));
- msg.msg_control = buf;
- msg.msg_controllen = sizeof(buf);
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_level = SOL_IPV6;
- cmsg->cmsg_type = IPV6_PKTINFO;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
- pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg);
- sin = (struct sockaddr_in6*)src->get_sockaddr(src);
- memcpy(&pktinfo->ipi6_addr, &sin->sin6_addr, sizeof(struct in6_addr));
+ bytes_sent = send_msg_v6(skt, &msg, src);
}
-#endif /* HAVE_IN6_PKTINFO */
}
-
- bytes_sent = sendmsg(skt, &msg, 0);
+ else
+ {
+ bytes_sent = send_msg_generic(skt, &msg);
+ }
if (bytes_sent != data.len)
{
diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c
index b82a69e1b..a032134c3 100644
--- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c
+++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c
@@ -527,6 +527,62 @@ static dynsock_t *find_socket(private_socket_dynamic_socket_t *this,
return skt;
}
+/**
+ * Generic function to send a message.
+ */
+static ssize_t send_msg_generic(int skt, struct msghdr *msg)
+{
+ return sendmsg(skt, msg, 0);
+}
+
+/**
+ * Send a message with the IPv4 source address set.
+ */
+static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src)
+{
+ char buf[CMSG_SPACE(sizeof(struct in_pktinfo))] = {};
+ struct cmsghdr *cmsg;
+ struct in_addr *addr;
+ struct in_pktinfo *pktinfo;
+ struct sockaddr_in *sin;
+
+ msg->msg_control = buf;
+ msg->msg_controllen = sizeof(buf);
+ cmsg = CMSG_FIRSTHDR(msg);
+ cmsg->cmsg_level = SOL_IP;
+ cmsg->cmsg_type = IP_PKTINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+
+ pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
+ addr = &pktinfo->ipi_spec_dst;
+
+ sin = (struct sockaddr_in*)src->get_sockaddr(src);
+ memcpy(addr, &sin->sin_addr, sizeof(struct in_addr));
+ return send_msg_generic(skt, msg);
+}
+
+/**
+ * Send a message with the IPv6 source address set.
+ */
+static ssize_t send_msg_v6(int skt, struct msghdr *msg, host_t *src)
+{
+ char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))] = {};
+ struct cmsghdr *cmsg;
+ struct in6_pktinfo *pktinfo;
+ struct sockaddr_in6 *sin;
+
+ msg->msg_control = buf;
+ msg->msg_controllen = sizeof(buf);
+ cmsg = CMSG_FIRSTHDR(msg);
+ cmsg->cmsg_level = SOL_IPV6;
+ cmsg->cmsg_type = IPV6_PKTINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
+ pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg);
+ sin = (struct sockaddr_in6*)src->get_sockaddr(src);
+ memcpy(&pktinfo->ipi6_addr, &sin->sin6_addr, sizeof(struct in6_addr));
+ return send_msg_generic(skt, msg);
+}
+
METHOD(socket_t, sender, status_t,
private_socket_dynamic_socket_t *this, packet_t *packet)
{
@@ -536,7 +592,6 @@ METHOD(socket_t, sender, status_t,
ssize_t len;
chunk_t data;
struct msghdr msg;
- struct cmsghdr *cmsg;
struct iovec iov;
src = packet->get_source(packet);
@@ -564,43 +619,18 @@ METHOD(socket_t, sender, status_t,
{
if (family == AF_INET)
{
- struct in_addr *addr;
- struct sockaddr_in *sin;
- char buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
- struct in_pktinfo *pktinfo;
-
- memset(buf, 0, sizeof(buf));
- msg.msg_control = buf;
- msg.msg_controllen = sizeof(buf);
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_level = SOL_IP;
- cmsg->cmsg_type = IP_PKTINFO;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
- pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
- addr = &pktinfo->ipi_spec_dst;
- sin = (struct sockaddr_in*)src->get_sockaddr(src);
- memcpy(addr, &sin->sin_addr, sizeof(struct in_addr));
+ len = send_msg_v4(skt->fd, &msg, src);
}
else
{
- char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
- struct in6_pktinfo *pktinfo;
- struct sockaddr_in6 *sin;
-
- memset(buf, 0, sizeof(buf));
- msg.msg_control = buf;
- msg.msg_controllen = sizeof(buf);
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_level = SOL_IPV6;
- cmsg->cmsg_type = IPV6_PKTINFO;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
- pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg);
- sin = (struct sockaddr_in6*)src->get_sockaddr(src);
- memcpy(&pktinfo->ipi6_addr, &sin->sin6_addr, sizeof(struct in6_addr));
+ len = send_msg_v6(skt->fd, &msg, src);
}
}
+ else
+ {
+ len = send_msg_generic(skt->fd, &msg);
+ }
- len = sendmsg(skt->fd, &msg, 0);
if (len != data.len)
{
DBG1(DBG_NET, "error writing to socket: %s", strerror(errno));
diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c
index f71719458..68cf83089 100644
--- a/src/libcharon/plugins/stroke/stroke_config.c
+++ b/src/libcharon/plugins/stroke/stroke_config.c
@@ -346,9 +346,9 @@ static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg)
{ "sha256", SIGN_ECDSA_256, KEY_ECDSA, },
{ "sha384", SIGN_ECDSA_384, KEY_ECDSA, },
{ "sha512", SIGN_ECDSA_521, KEY_ECDSA, },
- { "sha256", SIGN_BLISS_WITH_SHA256, KEY_BLISS, },
- { "sha384", SIGN_BLISS_WITH_SHA384, KEY_BLISS, },
- { "sha512", SIGN_BLISS_WITH_SHA512, KEY_BLISS, },
+ { "sha256", SIGN_BLISS_WITH_SHA2_256, KEY_BLISS, },
+ { "sha384", SIGN_BLISS_WITH_SHA2_384, KEY_BLISS, },
+ { "sha512", SIGN_BLISS_WITH_SHA2_512, KEY_BLISS, },
};
if (rsa_len || ecdsa_len || bliss_strength)
diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c
index 0125d17c6..5a1a5074d 100644
--- a/src/libcharon/plugins/stroke/stroke_control.c
+++ b/src/libcharon/plugins/stroke/stroke_control.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Tobias Brunner
+ * Copyright (C) 2013-2015 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -298,6 +298,41 @@ static void report_terminate_status(private_stroke_control_t *this,
}
}
+/**
+ * Call the charon controller to terminate a CHILD_SA
+ */
+static void charon_terminate(private_stroke_control_t *this, u_int32_t id,
+ stroke_msg_t *msg, FILE *out, bool child)
+{
+ if (msg->output_verbosity >= 0)
+ {
+ stroke_log_info_t info = { msg->output_verbosity, out };
+ status_t status;
+
+ if (child)
+ {
+ status = charon->controller->terminate_child(charon->controller, id,
+ (controller_cb_t)stroke_log, &info, this->timeout);
+ }
+ else
+ {
+ status = charon->controller->terminate_ike(charon->controller, id,
+ (controller_cb_t)stroke_log, &info, this->timeout);
+ }
+ report_terminate_status(this, status, out, id, child);
+ }
+ else if (child)
+ {
+ charon->controller->terminate_child(charon->controller, id,
+ NULL, NULL, 0);
+ }
+ else
+ {
+ charon->controller->terminate_ike(charon->controller, id,
+ NULL, NULL, 0);
+ }
+}
+
METHOD(stroke_control_t, terminate, void,
private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
{
@@ -307,9 +342,7 @@ METHOD(stroke_control_t, terminate, void,
ike_sa_t *ike_sa;
enumerator_t *enumerator;
linked_list_t *ike_list, *child_list;
- stroke_log_info_t info;
uintptr_t del;
- status_t status;
if (!parse_specifier(msg->terminate.name, &id, &name, &child, &all))
{
@@ -317,22 +350,9 @@ METHOD(stroke_control_t, terminate, void,
return;
}
- info.out = out;
- info.level = msg->output_verbosity;
-
if (id)
{
- if (child)
- {
- status = charon->controller->terminate_child(charon->controller, id,
- (controller_cb_t)stroke_log, &info, this->timeout);
- }
- else
- {
- status = charon->controller->terminate_ike(charon->controller, id,
- (controller_cb_t)stroke_log, &info, this->timeout);
- }
- return report_terminate_status(this, status, out, id, child);
+ return charon_terminate(this, id, msg, out, child);
}
ike_list = linked_list_create();
@@ -380,18 +400,14 @@ METHOD(stroke_control_t, terminate, void,
enumerator = child_list->create_enumerator(child_list);
while (enumerator->enumerate(enumerator, &del))
{
- status = charon->controller->terminate_child(charon->controller, del,
- (controller_cb_t)stroke_log, &info, this->timeout);
- report_terminate_status(this, status, out, del, TRUE);
+ charon_terminate(this, del, msg, out, TRUE);
}
enumerator->destroy(enumerator);
enumerator = ike_list->create_enumerator(ike_list);
while (enumerator->enumerate(enumerator, &del))
{
- status = charon->controller->terminate_ike(charon->controller, del,
- (controller_cb_t)stroke_log, &info, this->timeout);
- report_terminate_status(this, status, out, del, FALSE);
+ charon_terminate(this, del, msg, out, FALSE);
}
enumerator->destroy(enumerator);
@@ -548,11 +564,6 @@ METHOD(stroke_control_t, purge_ike, void,
child_sa_t *child_sa;
linked_list_t *list;
uintptr_t del;
- stroke_log_info_t info;
- status_t status;
-
- info.out = out;
- info.level = msg->output_verbosity;
list = linked_list_create();
enumerator = charon->controller->create_ike_sa_enumerator(
@@ -572,9 +583,7 @@ METHOD(stroke_control_t, purge_ike, void,
enumerator = list->create_enumerator(list);
while (enumerator->enumerate(enumerator, &del))
{
- status = charon->controller->terminate_ike(charon->controller, del,
- (controller_cb_t)stroke_log, &info, this->timeout);
- report_terminate_status(this, status, out, del, TRUE);
+ charon_terminate(this, del, msg, out, FALSE);
}
enumerator->destroy(enumerator);
list->destroy(list);
diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c
index c7e4c9c65..c0192b5c0 100644
--- a/src/libcharon/plugins/stroke/stroke_list.c
+++ b/src/libcharon/plugins/stroke/stroke_list.c
@@ -334,7 +334,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
child_sa->create_ts_enumerator(child_sa, TRUE));
other_ts = linked_list_create_from_enumerator(
child_sa->create_ts_enumerator(child_sa, FALSE));
- fprintf(out, "\n%12s{%d}: %#R=== %#R\n",
+ fprintf(out, "\n%12s{%d}: %#R === %#R\n",
child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa),
my_ts, other_ts);
my_ts->destroy(my_ts);
@@ -586,7 +586,7 @@ METHOD(stroke_list_t, status, void,
{
my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL);
other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL);
- fprintf(out, "%12s: child: %#R=== %#R%N",
+ fprintf(out, "%12s: child: %#R === %#R %N",
child_cfg->get_name(child_cfg), my_ts, other_ts,
ipsec_mode_names, child_cfg->get_mode(child_cfg));
my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
@@ -620,7 +620,7 @@ METHOD(stroke_list_t, status, void,
}
my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL);
other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL);
- fprintf(out, "%12s: %#R=== %#R%N\n",
+ fprintf(out, "%12s: %#R === %#R %N\n",
child_cfg->get_name(child_cfg), my_ts, other_ts,
ipsec_mode_names, child_cfg->get_mode(child_cfg));
my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
diff --git a/src/libcharon/plugins/vici/README.md b/src/libcharon/plugins/vici/README.md
index e20e8ab26..b9531d8a5 100644
--- a/src/libcharon/plugins/vici/README.md
+++ b/src/libcharon/plugins/vici/README.md
@@ -526,12 +526,21 @@ Unloading fails for pools with leases currently online.
List the currently loaded pools.
- {} => {
+ {
+ leases = <set to yes to include leases>
+ } => {
<pool name>* = {
base = <virtual IP pool base address>
size = <total number of addresses in the pool>
online = <number of leases online>
offline = <number of leases offline>
+ leases = {
+ <zero-based index>* = {
+ address = <IP address>
+ identity = <assigned identity>
+ status = <online|offline>
+ }
+ }
}
}
@@ -587,6 +596,10 @@ command.
initiator = <yes, if initiator of IKE_SA>
initiator-spi = <hex encoded initiator SPI / cookie>
responder-spi = <hex encoded responder SPI / cookie>
+ nat-local = <yes, if local endpoint is behind a NAT>
+ nat-remote = <yes, if remote endpoint is behind a NAT>
+ nat-fake = <yes, if NAT situation has been faked as responder>
+ nat-any = <yes, if any endpoint is behind a NAT (also if faked)>
encr-alg = <IKE encryption algorithm string>
encr-keysize = <key size for encr-alg, if applicable>
integ-alg = <IKE integrity algorithm string>
@@ -596,6 +609,12 @@ command.
established = <seconds the IKE_SA has been established>
rekey-time = <seconds before IKE_SA gets rekeyed>
reauth-time = <seconds before IKE_SA gets re-authenticated>
+ local-vips = [
+ <list of virtual IPs assigned by the remote peer, installed locally>
+ ]
+ remote-vips = [
+ <list of virtual IPs assigned to the remote peer>
+ ]
tasks-queued = [
<list of currently queued tasks for execution>
]
diff --git a/src/libcharon/plugins/vici/vici_attribute.c b/src/libcharon/plugins/vici/vici_attribute.c
index f04bae774..9064d3d8c 100644
--- a/src/libcharon/plugins/vici/vici_attribute.c
+++ b/src/libcharon/plugins/vici/vici_attribute.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Tobias Brunner
+ * Copyright (C) 2014-2015 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2014 Martin Willi
@@ -662,9 +662,16 @@ CALLBACK(get_pools, vici_message_t*,
vici_message_t *message)
{
vici_builder_t *builder;
- enumerator_t *enumerator;
+ enumerator_t *enumerator, *leases;
mem_pool_t *vips;
pool_t *pool;
+ identification_t *uid;
+ host_t *lease;
+ bool list_leases, on;
+ char buf[32];
+ int i;
+
+ list_leases = message->get_bool(message, FALSE, "leases");
builder = vici_builder_create();
@@ -681,6 +688,23 @@ CALLBACK(get_pools, vici_message_t*,
builder->add_kv(builder, "online", "%u", vips->get_online(vips));
builder->add_kv(builder, "offline", "%u", vips->get_offline(vips));
+ if (list_leases)
+ {
+ i = 0;
+ builder->begin_section(builder, "leases");
+ leases = vips->create_lease_enumerator(vips);
+ while (leases && leases->enumerate(leases, &uid, &lease, &on))
+ {
+ snprintf(buf, sizeof(buf), "%d", i++);
+ builder->begin_section(builder, buf);
+ builder->add_kv(builder, "address", "%H", lease);
+ builder->add_kv(builder, "identity", "%Y", uid);
+ builder->add_kv(builder, "status", on ? "online" : "offline");
+ builder->end_section(builder);
+ }
+ leases->destroy(leases);
+ builder->end_section(builder);
+ }
builder->end_section(builder);
}
enumerator->destroy(enumerator);
diff --git a/src/libcharon/plugins/vici/vici_cred.c b/src/libcharon/plugins/vici/vici_cred.c
index ffdc034ea..6631184b5 100644
--- a/src/libcharon/plugins/vici/vici_cred.c
+++ b/src/libcharon/plugins/vici/vici_cred.c
@@ -71,6 +71,7 @@ CALLBACK(load_cert, vici_message_t*,
certificate_t *cert;
x509_t *x509;
chunk_t data;
+ bool trusted = TRUE;
char *str;
str = message->get_str(message, NULL, "type");
@@ -99,6 +100,7 @@ CALLBACK(load_cert, vici_message_t*,
else if (strcaseeq(str, "x509ac"))
{
type = CERT_X509_AC;
+ trusted = FALSE;
}
else
{
@@ -131,8 +133,14 @@ CALLBACK(load_cert, vici_message_t*,
DBG1(DBG_CFG, "loaded certificate '%Y'", cert->get_subject(cert));
- this->creds->add_cert(this->creds, TRUE, cert);
-
+ if (type == CERT_X509_CRL)
+ {
+ this->creds->add_crl(this->creds, (crl_t*)cert);
+ }
+ else
+ {
+ this->creds->add_cert(this->creds, trusted, cert);
+ }
return create_reply(NULL);
}
diff --git a/src/libcharon/plugins/vici/vici_query.c b/src/libcharon/plugins/vici/vici_query.c
index 98d264fca..9a3d832da 100644
--- a/src/libcharon/plugins/vici/vici_query.c
+++ b/src/libcharon/plugins/vici/vici_query.c
@@ -222,6 +222,45 @@ static void list_task_queue(private_vici_query_t *this, vici_builder_t *b,
}
/**
+ * Add an IKE_SA condition to the given builder
+ */
+static void add_condition(vici_builder_t *b, ike_sa_t *ike_sa,
+ char *key, ike_condition_t cond)
+{
+ if (ike_sa->has_condition(ike_sa, cond))
+ {
+ b->add_kv(b, key, "yes");
+ }
+}
+
+/**
+ * List virtual IPs
+ */
+static void list_vips(private_vici_query_t *this, vici_builder_t *b,
+ ike_sa_t *ike_sa, bool local, char *name)
+{
+ enumerator_t *enumerator;
+ bool has = FALSE;
+ host_t *vip;
+
+ enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, local);
+ while (enumerator->enumerate(enumerator, &vip))
+ {
+ if (!has)
+ {
+ b->begin_list(b, name);
+ has = TRUE;
+ }
+ b->add_li(b, "%H", vip);
+ }
+ enumerator->destroy(enumerator);
+ if (has)
+ {
+ b->end_list(b);
+ }
+}
+
+/**
* List details of an IKE_SA
*/
static void list_ike(private_vici_query_t *this, vici_builder_t *b,
@@ -265,6 +304,11 @@ static void list_ike(private_vici_query_t *this, vici_builder_t *b,
b->add_kv(b, "initiator-spi", "%.16"PRIx64, id->get_initiator_spi(id));
b->add_kv(b, "responder-spi", "%.16"PRIx64, id->get_responder_spi(id));
+ add_condition(b, ike_sa, "nat-local", COND_NAT_HERE);
+ add_condition(b, ike_sa, "nat-remote", COND_NAT_THERE);
+ add_condition(b, ike_sa, "nat-fake", COND_NAT_FAKE);
+ add_condition(b, ike_sa, "nat-any", COND_NAT_ANY);
+
proposal = ike_sa->get_proposal(ike_sa);
if (proposal)
{
@@ -310,6 +354,9 @@ static void list_ike(private_vici_query_t *this, vici_builder_t *b,
}
}
+ list_vips(this, b, ike_sa, TRUE, "local-vips");
+ list_vips(this, b, ike_sa, FALSE, "remote-vips");
+
list_task_queue(this, b, ike_sa, TASK_QUEUE_QUEUED, "tasks-queued");
list_task_queue(this, b, ike_sa, TASK_QUEUE_ACTIVE, "tasks-active");
list_task_queue(this, b, ike_sa, TASK_QUEUE_PASSIVE, "tasks-passive");