/* * NetLabel Unlabeled Support * * This file defines functions for dealing with unlabeled packets for the * NetLabel system. The NetLabel system manages static and dynamic label * mappings for network protocols such as CIPSO and RIPSO. * * Author: Paul Moore * */ /* * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include #include #include #include #include #include #include #include #include "netlabel_user.h" #include "netlabel_domainhash.h" #include "netlabel_unlabeled.h" /* Accept unlabeled packets flag */ static atomic_t netlabel_unlabel_accept_flg = ATOMIC_INIT(0); /* NetLabel Generic NETLINK CIPSOv4 family */ static struct genl_family netlbl_unlabel_gnl_family = { .id = GENL_ID_GENERATE, .hdrsize = 0, .name = NETLBL_NLTYPE_UNLABELED_NAME, .version = NETLBL_PROTO_VERSION, .maxattr = 0, }; /* * NetLabel Command Handlers */ /** * netlbl_unlabel_accept - Handle an ACCEPT message * @skb: the NETLINK buffer * @info: the Generic NETLINK info block * * Description: * Process a user generated ACCEPT message and set the accept flag accordingly. * Returns zero on success, negative values on failure. * */ static int netlbl_unlabel_accept(struct sk_buff *skb, struct genl_info *info) { int ret_val; struct nlattr *data = netlbl_netlink_payload_data(skb); u32 value; ret_val = netlbl_netlink_cap_check(skb, CAP_NET_ADMIN); if (ret_val != 0) return ret_val; if (netlbl_netlink_payload_len(skb) == NETLBL_LEN_U32) { value = nla_get_u32(data); if (value == 1 || value == 0) { atomic_set(&netlabel_unlabel_accept_flg, value); netlbl_netlink_send_ack(info, netlbl_unlabel_gnl_family.id, NLBL_UNLABEL_C_ACK, NETLBL_E_OK); return 0; } } netlbl_netlink_send_ack(info, netlbl_unlabel_gnl_family.id, NLBL_UNLABEL_C_ACK, EINVAL); return -EINVAL; } /** * netlbl_unlabel_list - Handle a LIST message * @skb: the NETLINK buffer * @info: the Generic NETLINK info block * * Description: * Process a user generated LIST message and respond with the current status. * Returns zero on success, negative values on failure. * */ static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info) { int ret_val = -ENOMEM; struct sk_buff *ans_skb; ans_skb = netlbl_netlink_alloc_skb(0, GENL_HDRLEN + NETLBL_LEN_U32, GFP_KERNEL); if (ans_skb == NULL) goto list_failure; if (netlbl_netlink_hdr_put(ans_skb, info->snd_pid, 0, netlbl_unlabel_gnl_family.id, NLBL_UNLABEL_C_LIST) == NULL) goto list_failure; ret_val = nla_put_u32(ans_skb, NLA_U32, atomic_read(&netlabel_unlabel_accept_flg)); if (ret_val != 0) goto list_failure; ret_val = netlbl_netlink_snd(ans_skb, info->snd_pid); if (ret_val != 0) goto list_failure; return 0; list_failure: netlbl_netlink_send_ack(info, netlbl_unlabel_gnl_family.id, NLBL_UNLABEL_C_ACK, -ret_val); return ret_val; } /* * NetLabel Generic NETLINK Command Definitions */ static struct genl_ops netlbl_unlabel_genl_c_accept = { .cmd = NLBL_UNLABEL_C_ACCEPT, .flags = 0, .doit = netlbl_unlabel_accept, .dumpit = NULL, }; static struct genl_ops netlbl_unlabel_genl_c_list = { .cmd = NLBL_UNLABEL_C_LIST, .flags = 0, .doit = netlbl_unlabel_list, .dumpit = NULL, }; /* * NetLabel Generic NETLINK Protocol Functions */ /** * netlbl_unlabel_genl_init - Register the Unlabeled NetLabel component * * Description: * Register the unlabeled packet NetLabel component with the Generic NETLINK * mechanism. Returns zero on success, negative values on failure. * */ int netlbl_unlabel_genl_init(void) { int ret_val; ret_val = genl_register_family(&netlbl_unlabel_gnl_family); if (ret_val != 0) return ret_val; ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, &netlbl_unlabel_genl_c_accept); if (ret_val != 0) return ret_val; ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, &netlbl_unlabel_genl_c_list); if (ret_val != 0) return ret_val; return 0; } /* * NetLabel KAPI Hooks */ /** * netlbl_unlabel_getattr - Get the security attributes for an unlabled packet * @secattr: the security attributes * * Description: * Determine the security attributes, if any, for an unlabled packet and return * them in @secattr. Returns zero on success and negative values on failure. * */ int netlbl_unlabel_getattr(struct netlbl_lsm_secattr *secattr) { if (atomic_read(&netlabel_unlabel_accept_flg) == 1) { memset(secattr, 0, sizeof(*secattr)); return 0; } return -ENOMSG; } /** * netlbl_unlabel_defconf - Set the default config to allow unlabeled packets * * Description: * Set the default NetLabel configuration to allow incoming unlabeled packets * and to send unlabeled network traffic by default. * */ int netlbl_unlabel_defconf(void) { int ret_val; struct netlbl_dom_map *entry; entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (entry == NULL) return -ENOMEM; entry->type = NETLBL_NLTYPE_UNLABELED; ret_val = netlbl_domhsh_add_default(entry); if (ret_val != 0) return ret_val; atomic_set(&netlabel_unlabel_accept_flg, 1); return 0; }