diff options
Diffstat (limited to 'src/libhydra/plugins')
12 files changed, 262 insertions, 108 deletions
diff --git a/src/libhydra/plugins/attr/Makefile.in b/src/libhydra/plugins/attr/Makefile.in index ddf2a4486..50ea066c5 100644 --- a/src/libhydra/plugins/attr/Makefile.in +++ b/src/libhydra/plugins/attr/Makefile.in @@ -232,6 +232,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -292,6 +293,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -357,6 +359,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -404,6 +408,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libhydra/plugins/attr_sql/Makefile.in b/src/libhydra/plugins/attr_sql/Makefile.in index 6f27bf37e..076e1f8f2 100644 --- a/src/libhydra/plugins/attr_sql/Makefile.in +++ b/src/libhydra/plugins/attr_sql/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libhydra/plugins/kernel_netlink/Makefile.in b/src/libhydra/plugins/kernel_netlink/Makefile.in index 2a67bd595..a9b523eb8 100644 --- a/src/libhydra/plugins/kernel_netlink/Makefile.in +++ b/src/libhydra/plugins/kernel_netlink/Makefile.in @@ -236,6 +236,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -296,6 +297,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -361,6 +363,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -408,6 +412,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c index d9b55cfa7..dfd71f3bd 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -310,6 +310,12 @@ struct private_kernel_netlink_ipsec_t { bool install_routes; /** + * Whether to set protocol and ports on selector installed with transport + * mode IPsec SAs + */ + bool proto_port_transport; + + /** * Whether to track the history of a policy */ bool policy_history; @@ -810,7 +816,7 @@ static void process_acquire(private_kernel_netlink_ipsec_t *this, u_int32_t reqid = 0; int proto = 0; - acquire = (struct xfrm_user_acquire*)NLMSG_DATA(hdr); + acquire = NLMSG_DATA(hdr); rta = XFRM_RTA(hdr, struct xfrm_user_acquire); rtasize = XFRM_PAYLOAD(hdr, struct xfrm_user_acquire); @@ -856,7 +862,7 @@ static void process_expire(private_kernel_netlink_ipsec_t *this, u_int32_t spi, reqid; u_int8_t protocol; - expire = (struct xfrm_user_expire*)NLMSG_DATA(hdr); + expire = NLMSG_DATA(hdr); protocol = expire->state.id.proto; spi = expire->state.id.spi; reqid = expire->state.reqid; @@ -890,7 +896,7 @@ static void process_migrate(private_kernel_netlink_ipsec_t *this, u_int32_t reqid = 0; policy_dir_t dir; - policy_id = (struct xfrm_userpolicy_id*)NLMSG_DATA(hdr); + policy_id = NLMSG_DATA(hdr); rta = XFRM_RTA(hdr, struct xfrm_userpolicy_id); rtasize = XFRM_PAYLOAD(hdr, struct xfrm_userpolicy_id); @@ -957,7 +963,7 @@ static void process_mapping(private_kernel_netlink_ipsec_t *this, struct xfrm_user_mapping *mapping; u_int32_t spi, reqid; - mapping = (struct xfrm_user_mapping*)NLMSG_DATA(hdr); + mapping = NLMSG_DATA(hdr); spi = mapping->id.spi; reqid = mapping->reqid; @@ -1059,12 +1065,12 @@ static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this, memset(&request, 0, sizeof(request)); - hdr = (struct nlmsghdr*)request; + hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST; hdr->nlmsg_type = XFRM_MSG_ALLOCSPI; hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userspi_info)); - userspi = (struct xfrm_userspi_info*)NLMSG_DATA(hdr); + userspi = NLMSG_DATA(hdr); host2xfrm(src, &userspi->info.saddr); host2xfrm(dst, &userspi->info.id.daddr); userspi->info.id.proto = proto; @@ -1208,12 +1214,12 @@ METHOD(kernel_ipsec_t, add_sa, status_t, DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u} (mark " "%u/0x%08x)", ntohl(spi), reqid, mark.value, mark.mask); - hdr = (struct nlmsghdr*)request; + hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; hdr->nlmsg_type = inbound ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA; hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)); - sa = (struct xfrm_usersa_info*)NLMSG_DATA(hdr); + sa = NLMSG_DATA(hdr); host2xfrm(src, &sa->saddr); host2xfrm(dst, &sa->id.daddr); sa->id.spi = spi; @@ -1235,12 +1241,15 @@ METHOD(kernel_ipsec_t, add_sa, status_t, if (src_ts && dst_ts) { sa->sel = ts2selector(src_ts, dst_ts); - /* don't install proto/port on SA. This would break - * potential secondary SAs for the same address using a - * different prot/port. */ - sa->sel.proto = 0; - sa->sel.dport = sa->sel.dport_mask = 0; - sa->sel.sport = sa->sel.sport_mask = 0; + if (!this->proto_port_transport) + { + /* don't install proto/port on SA. This would break + * potential secondary SAs for the same address using a + * different prot/port. */ + sa->sel.proto = 0; + sa->sel.dport = sa->sel.dport_mask = 0; + sa->sel.sport = sa->sel.sport_mask = 0; + } } break; default: @@ -1512,7 +1521,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t, status = SUCCESS; failed: - memwipe(request, sizeof(request)); + memwipe(&request, sizeof(request)); return status; } @@ -1540,12 +1549,12 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this, DBG2(DBG_KNL, "querying replay state from SAD entry with SPI %.8x", ntohl(spi)); - hdr = (struct nlmsghdr*)request; + hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST; hdr->nlmsg_type = XFRM_MSG_GETAE; hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id)); - aevent_id = (struct xfrm_aevent_id*)NLMSG_DATA(hdr); + aevent_id = NLMSG_DATA(hdr); aevent_id->flags = XFRM_AE_RVAL; host2xfrm(dst, &aevent_id->sa_id.daddr); @@ -1632,12 +1641,12 @@ METHOD(kernel_ipsec_t, query_sa, status_t, DBG2(DBG_KNL, "querying SAD entry with SPI %.8x (mark %u/0x%08x)", ntohl(spi), mark.value, mark.mask); - hdr = (struct nlmsghdr*)request; + hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST; hdr->nlmsg_type = XFRM_MSG_GETSA; hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)); - sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr); + sa_id = NLMSG_DATA(hdr); host2xfrm(dst, &sa_id->daddr); sa_id->spi = spi; sa_id->proto = protocol; @@ -1657,7 +1666,7 @@ METHOD(kernel_ipsec_t, query_sa, status_t, { case XFRM_MSG_NEWSA: { - sa = (struct xfrm_usersa_info*)NLMSG_DATA(hdr); + sa = NLMSG_DATA(hdr); break; } case NLMSG_ERROR: @@ -1735,12 +1744,12 @@ METHOD(kernel_ipsec_t, del_sa, status_t, DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x (mark %u/0x%08x)", ntohl(spi), mark.value, mark.mask); - hdr = (struct nlmsghdr*)request; + hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; hdr->nlmsg_type = XFRM_MSG_DELSA; hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)); - sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr); + sa_id = NLMSG_DATA(hdr); host2xfrm(dst, &sa_id->daddr); sa_id->spi = spi; sa_id->proto = protocol; @@ -1804,12 +1813,12 @@ METHOD(kernel_ipsec_t, update_sa, status_t, DBG2(DBG_KNL, "querying SAD entry with SPI %.8x for update", ntohl(spi)); /* query the existing SA first */ - hdr = (struct nlmsghdr*)request; + hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST; hdr->nlmsg_type = XFRM_MSG_GETSA; hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)); - sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr); + sa_id = NLMSG_DATA(hdr); host2xfrm(dst, &sa_id->daddr); sa_id->spi = spi; sa_id->proto = protocol; @@ -1867,7 +1876,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t, DBG2(DBG_KNL, "updating SAD entry with SPI %.8x from %#H..%#H to %#H..%#H", ntohl(spi), src, dst, new_src, new_dst); /* copy over the SA from out to request */ - hdr = (struct nlmsghdr*)request; + hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; hdr->nlmsg_type = XFRM_MSG_NEWSA; hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)); @@ -1958,7 +1967,7 @@ failed: free(replay); free(replay_esn); memwipe(out, len); - memwipe(request, sizeof(request)); + memwipe(&request, sizeof(request)); free(out); return status; @@ -1975,12 +1984,12 @@ METHOD(kernel_ipsec_t, flush_sas, status_t, DBG2(DBG_KNL, "flushing all SAD entries"); - hdr = (struct nlmsghdr*)request; + hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; hdr->nlmsg_type = XFRM_MSG_FLUSHSA; hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush)); - flush = (struct xfrm_usersa_flush*)NLMSG_DATA(hdr); + flush = NLMSG_DATA(hdr); flush->proto = IPSEC_PROTO_ANY; if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS) @@ -2011,12 +2020,12 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this, memcpy(&clone, policy, sizeof(policy_entry_t)); memset(&request, 0, sizeof(request)); - hdr = (struct nlmsghdr*)request; + hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; hdr->nlmsg_type = update ? XFRM_MSG_UPDPOLICY : XFRM_MSG_NEWPOLICY; hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)); - policy_info = (struct xfrm_userpolicy_info*)NLMSG_DATA(hdr); + policy_info = NLMSG_DATA(hdr); policy_info->sel = policy->sel; policy_info->dir = policy->direction; @@ -2335,12 +2344,12 @@ METHOD(kernel_ipsec_t, query_policy, status_t, src_ts, dst_ts, policy_dir_names, direction, mark.value, mark.mask); - hdr = (struct nlmsghdr*)request; + hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST; hdr->nlmsg_type = XFRM_MSG_GETPOLICY; hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)); - policy_id = (struct xfrm_userpolicy_id*)NLMSG_DATA(hdr); + policy_id = NLMSG_DATA(hdr); policy_id->sel = ts2selector(src_ts, dst_ts); policy_id->dir = direction; @@ -2358,7 +2367,7 @@ METHOD(kernel_ipsec_t, query_policy, status_t, { case XFRM_MSG_NEWPOLICY: { - policy = (struct xfrm_userpolicy_info*)NLMSG_DATA(hdr); + policy = NLMSG_DATA(hdr); break; } case NLMSG_ERROR: @@ -2492,12 +2501,12 @@ METHOD(kernel_ipsec_t, del_policy, status_t, memset(&request, 0, sizeof(request)); - hdr = (struct nlmsghdr*)request; + hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; hdr->nlmsg_type = XFRM_MSG_DELPOLICY; hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)); - policy_id = (struct xfrm_userpolicy_id*)NLMSG_DATA(hdr); + policy_id = NLMSG_DATA(hdr); policy_id->sel = current->sel; policy_id->dir = direction; @@ -2551,7 +2560,7 @@ METHOD(kernel_ipsec_t, flush_policies, status_t, DBG2(DBG_KNL, "flushing all policies from SPD"); - hdr = (struct nlmsghdr*)request; + hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; hdr->nlmsg_type = XFRM_MSG_FLUSHPOLICY; hdr->nlmsg_len = NLMSG_LENGTH(0); /* no data associated */ @@ -2683,6 +2692,9 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create() .policy_history = TRUE, .install_routes = lib->settings->get_bool(lib->settings, "%s.install_routes", TRUE, lib->ns), + .proto_port_transport = lib->settings->get_bool(lib->settings, + "%s.plugins.kernel-netlink.set_proto_port_transport_sa", + FALSE, lib->ns), ); if (streq(lib->ns, "starter")) @@ -2699,7 +2711,7 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create() fclose(f); } - this->socket_xfrm = netlink_socket_create(NETLINK_XFRM); + this->socket_xfrm = netlink_socket_create(NETLINK_XFRM, xfrm_msg_names); if (!this->socket_xfrm) { destroy(this); diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c index 82b637d1e..9d9f15974 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c @@ -78,6 +78,27 @@ #define ROUTING_TABLE_PRIO 0 #endif +ENUM(rt_msg_names, RTM_NEWLINK, RTM_GETRULE, + "RTM_NEWLINK", + "RTM_DELLINK", + "RTM_GETLINK", + "RTM_SETLINK", + "RTM_NEWADDR", + "RTM_DELADDR", + "RTM_GETADDR", + "31", + "RTM_NEWROUTE", + "RTM_DELROUTE", + "RTM_GETROUTE", + "35", + "RTM_NEWNEIGH", + "RTM_DELNEIGH", + "RTM_GETNEIGH", + "RTM_NEWRULE", + "RTM_DELRULE", + "RTM_GETRULE", +); + typedef struct addr_entry_t addr_entry_t; /** @@ -478,6 +499,16 @@ struct private_kernel_netlink_net_t { * list with routing tables to be excluded from route lookup */ linked_list_t *rt_exclude; + + /** + * MTU to set on installed routes + */ + u_int32_t mtu; + + /** + * MSS to set on installed routes + */ + u_int32_t mss; }; /** @@ -928,7 +959,7 @@ static void addr_entry_unregister(addr_entry_t *addr, iface_entry_t *iface, static void process_link(private_kernel_netlink_net_t *this, struct nlmsghdr *hdr, bool event) { - struct ifinfomsg* msg = (struct ifinfomsg*)(NLMSG_DATA(hdr)); + struct ifinfomsg* msg = NLMSG_DATA(hdr); struct rtattr *rta = IFLA_RTA(msg); size_t rtasize = IFLA_PAYLOAD (hdr); enumerator_t *enumerator; @@ -1030,7 +1061,7 @@ static void process_link(private_kernel_netlink_net_t *this, static void process_addr(private_kernel_netlink_net_t *this, struct nlmsghdr *hdr, bool event) { - struct ifaddrmsg* msg = (struct ifaddrmsg*)(NLMSG_DATA(hdr)); + struct ifaddrmsg* msg = NLMSG_DATA(hdr); struct rtattr *rta = IFA_RTA(msg); size_t rtasize = IFA_PAYLOAD (hdr); host_t *host = NULL; @@ -1173,7 +1204,7 @@ static void process_addr(private_kernel_netlink_net_t *this, */ static void process_route(private_kernel_netlink_net_t *this, struct nlmsghdr *hdr) { - struct rtmsg* msg = (struct rtmsg*)(NLMSG_DATA(hdr)); + struct rtmsg* msg = NLMSG_DATA(hdr); struct rtattr *rta = RTM_RTA(msg); size_t rtasize = RTM_PAYLOAD(hdr); u_int32_t rta_oif = 0; @@ -1530,7 +1561,7 @@ static rt_entry_t *parse_route(struct nlmsghdr *hdr, rt_entry_t *route) struct rtmsg *msg; size_t rtasize; - msg = (struct rtmsg*)(NLMSG_DATA(hdr)); + msg = NLMSG_DATA(hdr); rta = RTM_RTA(msg); rtasize = RTM_PAYLOAD(hdr); @@ -1615,7 +1646,7 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest, memset(&request, 0, sizeof(request)); family = dest->get_family(dest); - hdr = (struct nlmsghdr*)request; + hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST; if (family == AF_INET || this->rta_prefsrc_for_ipv6 || this->routing_table || match_net) @@ -1627,7 +1658,7 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest, hdr->nlmsg_type = RTM_GETROUTE; hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); - msg = (struct rtmsg*)NLMSG_DATA(hdr); + msg = NLMSG_DATA(hdr); msg->rtm_family = family; if (candidate) { @@ -1854,12 +1885,12 @@ static status_t manage_ipaddr(private_kernel_netlink_net_t *this, int nlmsg_type chunk = ip->get_address(ip); - hdr = (struct nlmsghdr*)request; + hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags; hdr->nlmsg_type = nlmsg_type; hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); - msg = (struct ifaddrmsg*)NLMSG_DATA(hdr); + msg = NLMSG_DATA(hdr); msg->ifa_family = ip->get_family(ip); msg->ifa_flags = 0; msg->ifa_prefixlen = prefix < 0 ? chunk.len * 8 : prefix; @@ -2055,6 +2086,7 @@ static status_t manage_srcroute(private_kernel_netlink_net_t *this, netlink_buf_t request; struct nlmsghdr *hdr; struct rtmsg *msg; + struct rtattr *rta; int ifindex; chunk_t chunk; @@ -2081,12 +2113,12 @@ static status_t manage_srcroute(private_kernel_netlink_net_t *this, memset(&request, 0, sizeof(request)); - hdr = (struct nlmsghdr*)request; + hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags; hdr->nlmsg_type = nlmsg_type; hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); - msg = (struct rtmsg*)NLMSG_DATA(hdr); + msg = NLMSG_DATA(hdr); msg->rtm_family = src_ip->get_family(src_ip); msg->rtm_dst_len = prefixlen; msg->rtm_table = this->routing_table; @@ -2107,6 +2139,30 @@ static status_t manage_srcroute(private_kernel_netlink_net_t *this, chunk.len = sizeof(ifindex); netlink_add_attribute(hdr, RTA_OIF, chunk, sizeof(request)); + if (this->mtu || this->mss) + { + chunk = chunk_alloca(RTA_LENGTH((sizeof(struct rtattr) + + sizeof(u_int32_t)) * 2)); + chunk.len = 0; + rta = (struct rtattr*)chunk.ptr; + if (this->mtu) + { + rta->rta_type = RTAX_MTU; + rta->rta_len = RTA_LENGTH(sizeof(u_int32_t)); + memcpy(RTA_DATA(rta), &this->mtu, sizeof(u_int32_t)); + chunk.len = rta->rta_len; + } + if (this->mss) + { + rta = (struct rtattr*)(chunk.ptr + RTA_ALIGN(chunk.len)); + rta->rta_type = RTAX_ADVMSS; + rta->rta_len = RTA_LENGTH(sizeof(u_int32_t)); + memcpy(RTA_DATA(rta), &this->mss, sizeof(u_int32_t)); + chunk.len = RTA_ALIGN(chunk.len) + rta->rta_len; + } + netlink_add_attribute(hdr, RTA_METRICS, chunk, sizeof(request)); + } + return this->socket->send_ack(this->socket, hdr); } @@ -2186,10 +2242,10 @@ static status_t init_address_list(private_kernel_netlink_net_t *this) memset(&request, 0, sizeof(request)); - in = (struct nlmsghdr*)&request; + in = &request.hdr; in->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)); in->nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT; - msg = (struct rtgenmsg*)NLMSG_DATA(in); + msg = NLMSG_DATA(in); msg->rtgen_family = AF_UNSPEC; /* get all links */ @@ -2273,7 +2329,7 @@ static status_t manage_rule(private_kernel_netlink_net_t *this, int nlmsg_type, char *fwmark; memset(&request, 0, sizeof(request)); - hdr = (struct nlmsghdr*)request; + hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; hdr->nlmsg_type = nlmsg_type; if (nlmsg_type == RTM_NEWRULE) @@ -2282,7 +2338,7 @@ static status_t manage_rule(private_kernel_netlink_net_t *this, int nlmsg_type, } hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); - msg = (struct rtmsg*)NLMSG_DATA(hdr); + msg = NLMSG_DATA(hdr); msg->rtm_table = table; msg->rtm_family = family; msg->rtm_protocol = RTPROT_BOOT; @@ -2434,7 +2490,7 @@ kernel_netlink_net_t *kernel_netlink_net_create() .destroy = _destroy, }, }, - .socket = netlink_socket_create(NETLINK_ROUTE), + .socket = netlink_socket_create(NETLINK_ROUTE, rt_msg_names), .rt_exclude = linked_list_create(), .routes = hashtable_create((hashtable_hash_t)route_entry_hash, (hashtable_equals_t)route_entry_equals, 16), @@ -2466,6 +2522,10 @@ kernel_netlink_net_t *kernel_netlink_net_create() "%s.prefer_temporary_addrs", FALSE, lib->ns), .roam_events = lib->settings->get_bool(lib->settings, "%s.plugins.kernel-netlink.roam_events", TRUE, lib->ns), + .mtu = lib->settings->get_int(lib->settings, + "%s.plugins.kernel-netlink.mtu", 0, lib->ns), + .mss = lib->settings->get_int(lib->settings, + "%s.plugins.kernel-netlink.mss", 0, lib->ns), ); timerclear(&this->last_route_reinstall); timerclear(&this->next_roam); diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c index fd00c23af..b4cece720 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c @@ -46,14 +46,14 @@ struct private_netlink_socket_t { int seq; /** - * netlink socket protocol + * netlink socket */ - int protocol; + int socket; /** - * netlink socket + * Enum names for Netlink messages */ - int socket; + enum_name_t *names; }; /** @@ -65,10 +65,13 @@ METHOD(netlink_socket_t, netlink_send, status_t, private_netlink_socket_t *this, struct nlmsghdr *in, struct nlmsghdr **out, size_t *out_len) { - int len, addr_len; + union { + struct nlmsghdr hdr; + u_char bytes[4096]; + } response; struct sockaddr_nl addr; - chunk_t result = chunk_empty, tmp; - struct nlmsghdr *msg, peek; + chunk_t result = chunk_empty; + int len; this->mutex->lock(this->mutex); @@ -80,13 +83,11 @@ METHOD(netlink_socket_t, netlink_send, status_t, addr.nl_pid = 0; addr.nl_groups = 0; - if (this->protocol == NETLINK_XFRM) + if (this->names) { - chunk_t in_chunk = { (u_char*)in, in->nlmsg_len }; - - DBG3(DBG_KNL, "sending %N: %B", xfrm_msg_names, in->nlmsg_type, &in_chunk); + DBG3(DBG_KNL, "sending %N: %b", + this->names, in->nlmsg_type, in, in->nlmsg_len); } - while (TRUE) { len = sendto(this->socket, in, in->nlmsg_len, 0, @@ -108,20 +109,7 @@ METHOD(netlink_socket_t, netlink_send, status_t, while (TRUE) { - char buf[4096]; - tmp.len = sizeof(buf); - tmp.ptr = buf; - msg = (struct nlmsghdr*)tmp.ptr; - - memset(&addr, 0, sizeof(addr)); - addr.nl_family = AF_NETLINK; - addr.nl_pid = getpid(); - addr.nl_groups = 0; - addr_len = sizeof(addr); - - len = recvfrom(this->socket, tmp.ptr, tmp.len, 0, - (struct sockaddr*)&addr, &addr_len); - + len = recv(this->socket, &response, sizeof(response), 0); if (len < 0) { if (errno == EINTR) @@ -135,17 +123,17 @@ METHOD(netlink_socket_t, netlink_send, status_t, free(result.ptr); return FAILED; } - if (!NLMSG_OK(msg, len)) + if (!NLMSG_OK(&response.hdr, len)) { DBG1(DBG_KNL, "received corrupted netlink message"); this->mutex->unlock(this->mutex); free(result.ptr); return FAILED; } - if (msg->nlmsg_seq != this->seq) + if (response.hdr.nlmsg_seq != this->seq) { DBG1(DBG_KNL, "received invalid netlink sequence number"); - if (msg->nlmsg_seq < this->seq) + if (response.hdr.nlmsg_seq < this->seq) { continue; } @@ -154,17 +142,13 @@ METHOD(netlink_socket_t, netlink_send, status_t, return FAILED; } - tmp.len = len; - result.ptr = realloc(result.ptr, result.len + tmp.len); - memcpy(result.ptr + result.len, tmp.ptr, tmp.len); - result.len += tmp.len; + result = chunk_cat("mc", result, chunk_create(response.bytes, len)); /* NLM_F_MULTI flag does not seem to be set correctly, we use sequence * numbers to detect multi header messages */ - len = recvfrom(this->socket, &peek, sizeof(peek), MSG_PEEK | MSG_DONTWAIT, - (struct sockaddr*)&addr, &addr_len); - - if (len == sizeof(peek) && peek.nlmsg_seq == this->seq) + len = recv(this->socket, &response.hdr, sizeof(response.hdr), + MSG_PEEK | MSG_DONTWAIT); + if (len == sizeof(response.hdr) && response.hdr.nlmsg_seq == this->seq) { /* seems to be multipart */ continue; @@ -197,7 +181,7 @@ METHOD(netlink_socket_t, netlink_send_ack, status_t, { case NLMSG_ERROR: { - struct nlmsgerr* err = (struct nlmsgerr*)NLMSG_DATA(hdr); + struct nlmsgerr* err = NLMSG_DATA(hdr); if (err->error) { @@ -235,7 +219,7 @@ METHOD(netlink_socket_t, netlink_send_ack, status_t, METHOD(netlink_socket_t, destroy, void, private_netlink_socket_t *this) { - if (this->socket > 0) + if (this->socket != -1) { close(this->socket); } @@ -246,10 +230,12 @@ METHOD(netlink_socket_t, destroy, void, /** * Described in header. */ -netlink_socket_t *netlink_socket_create(int protocol) +netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names) { private_netlink_socket_t *this; - struct sockaddr_nl addr; + struct sockaddr_nl addr = { + .nl_family = AF_NETLINK, + }; INIT(this, .public = { @@ -259,21 +245,16 @@ netlink_socket_t *netlink_socket_create(int protocol) }, .seq = 200, .mutex = mutex_create(MUTEX_TYPE_DEFAULT), - .protocol = protocol, + .socket = socket(AF_NETLINK, SOCK_RAW, protocol), + .names = names, ); - memset(&addr, 0, sizeof(addr)); - addr.nl_family = AF_NETLINK; - - this->socket = socket(AF_NETLINK, SOCK_RAW, protocol); - if (this->socket < 0) + if (this->socket == -1) { DBG1(DBG_KNL, "unable to create netlink socket"); destroy(this); return NULL; } - - addr.nl_groups = 0; if (bind(this->socket, (struct sockaddr*)&addr, sizeof(addr))) { DBG1(DBG_KNL, "unable to bind netlink socket"); diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h index 8be935bc3..069f746d1 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h @@ -26,7 +26,10 @@ * 1024 byte is currently sufficient for all operations. Some platform * require an enforced aligment to four bytes (e.g. ARM). */ -typedef u_char netlink_buf_t[1024] __attribute__((aligned(RTA_ALIGNTO))); +typedef union { + struct nlmsghdr hdr; + u_char bytes[1024]; +} netlink_buf_t __attribute__((aligned(RTA_ALIGNTO))); typedef struct netlink_socket_t netlink_socket_t; @@ -61,9 +64,10 @@ struct netlink_socket_t { /** * Create a netlink_socket_t object. * - * @param protocol protocol type (e.g. NETLINK_XFRM or NETLINK_ROUTE) + * @param protocol protocol type (e.g. NETLINK_XFRM or NETLINK_ROUTE) + * @param names optional enum names for Netlink messages */ -netlink_socket_t *netlink_socket_create(int protocol); +netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names); /** * Creates an rtattr and adds it to the given netlink message. diff --git a/src/libhydra/plugins/kernel_pfkey/Makefile.in b/src/libhydra/plugins/kernel_pfkey/Makefile.in index 767769698..821ad7710 100644 --- a/src/libhydra/plugins/kernel_pfkey/Makefile.in +++ b/src/libhydra/plugins/kernel_pfkey/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c index e1a58aa94..00ab5ab5a 100644 --- a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c +++ b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c @@ -1978,8 +1978,8 @@ METHOD(kernel_ipsec_t, query_sa, status_t, } if (packets) { - /* not supported by PF_KEY */ - *packets = 0; + /* at least on Linux and FreeBSD this contains the number of packets */ + *packets = response.lft_current->sadb_lifetime_allocations; } if (time) { diff --git a/src/libhydra/plugins/kernel_pfroute/Makefile.in b/src/libhydra/plugins/kernel_pfroute/Makefile.in index 7938a3d23..662f2fd7d 100644 --- a/src/libhydra/plugins/kernel_pfroute/Makefile.in +++ b/src/libhydra/plugins/kernel_pfroute/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c index c4e8664f7..26fae0d6b 100644 --- a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c +++ b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c @@ -875,6 +875,41 @@ static void process_link(private_kernel_pfroute_net_t *this, } } +#ifdef HAVE_RTM_IFANNOUNCE + +/** + * Process an RTM_IFANNOUNCE message from the kernel + */ +static void process_announce(private_kernel_pfroute_net_t *this, + struct if_announcemsghdr *msg) +{ + enumerator_t *enumerator; + iface_entry_t *iface; + + if (msg->ifan_what != IFAN_DEPARTURE) + { + /* we handle new interfaces in process_link() */ + return; + } + + this->lock->write_lock(this->lock); + enumerator = this->ifaces->create_enumerator(this->ifaces); + while (enumerator->enumerate(enumerator, &iface)) + { + if (iface->ifindex == msg->ifan_index) + { + DBG1(DBG_KNL, "interface %s disappeared", iface->ifname); + this->ifaces->remove_at(this->ifaces, enumerator); + iface_entry_destroy(iface); + break; + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); +} + +#endif /* HAVE_RTM_IFANNOUNCE */ + /** * Process an RTM_*ROUTE message from the kernel */ @@ -895,6 +930,9 @@ static bool receive_events(private_kernel_pfroute_net_t *this, int fd, struct rt_msghdr rtm; struct if_msghdr ifm; struct ifa_msghdr ifam; +#ifdef HAVE_RTM_IFANNOUNCE + struct if_announcemsghdr ifanm; +#endif }; char buf[sizeof(struct sockaddr_storage) * RTAX_MAX]; } msg; @@ -935,6 +973,11 @@ static bool receive_events(private_kernel_pfroute_net_t *this, int fd, case RTM_IFINFO: hdrlen = sizeof(msg.ifm); break; +#ifdef HAVE_RTM_IFANNOUNCE + case RTM_IFANNOUNCE: + hdrlen = sizeof(msg.ifanm); + break; +#endif /* HAVE_RTM_IFANNOUNCE */ case RTM_ADD: case RTM_DELETE: case RTM_GET: @@ -957,6 +1000,11 @@ static bool receive_events(private_kernel_pfroute_net_t *this, int fd, case RTM_IFINFO: process_link(this, &msg.ifm); break; +#ifdef HAVE_RTM_IFANNOUNCE + case RTM_IFANNOUNCE: + process_announce(this, &msg.ifanm); + break; +#endif /* HAVE_RTM_IFANNOUNCE */ case RTM_ADD: case RTM_DELETE: process_route(this, &msg.rtm); @@ -1518,8 +1566,7 @@ retry: { /* timed out? */ break; } - if (this->reply->rtm_msglen < sizeof(*this->reply) || - msg.hdr.rtm_seq != this->reply->rtm_seq) + if (!this->reply) { continue; } @@ -1559,6 +1606,8 @@ retry: { failed = TRUE; } + free(this->reply); + this->reply = NULL; /* signal completion of query to a waiting thread */ this->waiting_seq = 0; this->condvar->signal(this->condvar); diff --git a/src/libhydra/plugins/resolve/Makefile.in b/src/libhydra/plugins/resolve/Makefile.in index 32eed617a..5b4c7bc6a 100644 --- a/src/libhydra/plugins/resolve/Makefile.in +++ b/src/libhydra/plugins/resolve/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ |