From e41d837f57f9eba98672ddb27a6b05792ae2909b Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Tue, 29 Aug 2006 22:12:18 +0000 Subject: [PATCH] Initial commit using netlabel_tools-0.16.tar.gz as the source. --- CHANGELOG | 46 +++ LICENSE | 340 +++++++++++++++++ Makefile | 90 +++++ README | 72 ++++ docs/libnetlabel.txt | 5 + docs/man/netlabelctl.8 | 84 +++++ docs/netlabelctl.txt | 111 ++++++ docs/netlabeld.txt | 5 + include/libnetlabel.h | 186 +++++++++ include/linux/netlabel.h | 189 ++++++++++ libnetlabel/Makefile | 58 +++ libnetlabel/common.c | 66 ++++ libnetlabel/common.h | 34 ++ libnetlabel/fields.c | 427 +++++++++++++++++++++ libnetlabel/fields.h | 45 +++ libnetlabel/mod_cipsov4.c | 708 ++++++++++++++++++++++++++++++++++ libnetlabel/mod_cipsov4.h | 32 ++ libnetlabel/mod_mgmt.c | 731 ++++++++++++++++++++++++++++++++++++ libnetlabel/mod_mgmt.h | 32 ++ libnetlabel/mod_unlabeled.c | 351 +++++++++++++++++ libnetlabel/mod_unlabeled.h | 32 ++ libnetlabel/netlabel_init.c | 87 +++++ libnetlabel/netlink_comm.c | 327 ++++++++++++++++ macros.mk | 71 ++++ netlabel_tools.spec | 55 +++ netlabelctl/Makefile | 58 +++ netlabelctl/cipsov4.c | 443 ++++++++++++++++++++++ netlabelctl/main.c | 213 +++++++++++ netlabelctl/map.c | 329 ++++++++++++++++ netlabelctl/mgmt.c | 142 +++++++ netlabelctl/netlabelctl.h | 42 +++ netlabelctl/unlabeled.c | 139 +++++++ netlabeld/Makefile | 53 +++ 33 files changed, 5603 insertions(+) create mode 100644 CHANGELOG create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README create mode 100644 docs/libnetlabel.txt create mode 100644 docs/man/netlabelctl.8 create mode 100644 docs/netlabelctl.txt create mode 100644 docs/netlabeld.txt create mode 100644 include/libnetlabel.h create mode 100644 include/linux/netlabel.h create mode 100644 libnetlabel/Makefile create mode 100644 libnetlabel/common.c create mode 100644 libnetlabel/common.h create mode 100644 libnetlabel/fields.c create mode 100644 libnetlabel/fields.h create mode 100644 libnetlabel/mod_cipsov4.c create mode 100644 libnetlabel/mod_cipsov4.h create mode 100644 libnetlabel/mod_mgmt.c create mode 100644 libnetlabel/mod_mgmt.h create mode 100644 libnetlabel/mod_unlabeled.c create mode 100644 libnetlabel/mod_unlabeled.h create mode 100644 libnetlabel/netlabel_init.c create mode 100644 libnetlabel/netlink_comm.c create mode 100644 macros.mk create mode 100644 netlabel_tools.spec create mode 100644 netlabelctl/Makefile create mode 100644 netlabelctl/cipsov4.c create mode 100644 netlabelctl/main.c create mode 100644 netlabelctl/map.c create mode 100644 netlabelctl/mgmt.c create mode 100644 netlabelctl/netlabelctl.h create mode 100644 netlabelctl/unlabeled.c create mode 100644 netlabeld/Makefile diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..3fcb3f7 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,46 @@ +NetLabel Tools CHANGELOG +============================================================================== + +* Version 0.16 (August 3, 2006) +------------------------------------------------------------------------------ +o Added a "version" flag (-V) +o Moved the mapping commands to the new "map" class +o Added support for the unlabeled list command +o Updated the documentation to bring it up to date with the current options +o Cleanup the libnetlabel interfaces a little bit +o Shift to using NETLINK attributes, at some point we should use libnetlink + +* Version 0.15 (July 6, 2006) +------------------------------------------------------------------------------ +o Modified the NETLINK communication bits to support the newly aligned fields + +* Version 0.14 (June 27, 2006) +------------------------------------------------------------------------------ +o Added a RPM specfile based on a version from Steve Grubb +o Minor Makefile changes to ease tarball and RPM creation +o Modified the NETLINK communication bits to support the new Generic NETLINK + communication mechanism + +* Version 0.13 (June 23, 2006) +------------------------------------------------------------------------------ +o Added some text to the README to explain how to remove any pre-existing + NetLabel configuration +o Added two patches from Klaus Weidner to add some error + messages and better sendmsg() error reporting +o Fixed some compiler warnings (added -Wall to CFLAGS) on Klaus' recomendation + +* Version 0.12 (June 13, 2006) +------------------------------------------------------------------------------ +o Added support for the new CIPSO_V4_MAP_PASS CIPSO mapping type + +* Version 0.11 (June 7, 2006) +------------------------------------------------------------------------------ +o Corrected a problem with the netlabel.h header file + +* Version 0.11 (June 6, 2006) +------------------------------------------------------------------------------ +o Changed the libnetlabel to reflect changes to the NetLabel protocol + +* Version 0.10 (May 1, 2006) +------------------------------------------------------------------------------ +o Initial version diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f90922e --- /dev/null +++ b/LICENSE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a4a43a7 --- /dev/null +++ b/Makefile @@ -0,0 +1,90 @@ +# +# NetLabel Tools Makefile +# +# NetLabel Tools are a collection of user space programs and libraries for +# working with the Linux NetLabel subsystem. The NetLabel subsystem 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 +# + +# +# macros +# + +include macros.mk + +# +# configuration +# + +INSTALL_PREFIX = /usr/local + +INSTALL_SBIN_DIR = $(INSTALL_PREFIX)/sbin +INSTALL_BIN_DIR = $(INSTALL_PREFIX)/bin +INSTALL_MAN_DIR = $(INSTALL_PREFIX)/share/man + +OWNER = root +GROUP = root + +# +# targets +# + +SUBDIRS = libnetlabel netlabelctl + +.PHONY: tarball install clean $(SUBDIRS) + +all: $(SUBDIRS) + +$(SUBDIRS): + @echo "INFO: entering directory $@/ ..." + @$(MAKE) -s -C $@ + +tarball: clean + @name=$$(grep "^Name:" netlabel_tools.spec | awk '{ print $$2 }'); \ + ver=$$(grep "^Version:" netlabel_tools.spec | awk '{ print $$2 }'); \ + tarball=$$name-$$ver.tar.gz; \ + echo "INFO: creating the tarball ../$$tarball"; \ + tmp_dir=$$(mktemp -d /tmp/netlabel_tools.XXXXX); \ + rel_dir=$$tmp_dir/$$name-$$ver; \ + mkdir $$rel_dir; \ + tar cf - . | (cd $$rel_dir; tar xf -); \ + (cd $$tmp_dir; tar zcf $$tarball $$name-$$ver); \ + mv $$tmp_dir/$$tarball ..; \ + rm -rf $$tmp_dir; + +install: $(SUBDIRS) + @echo "INFO: installing files in $(INSTALL_PREFIX)" + @mkdir -p $(INSTALL_SBIN_DIR) + @mkdir -p $(INSTALL_MAN_DIR)/man8 + @install -o $(OWNER) -g $(GROUP) -m 755 netlabelctl/netlabelctl \ + $(INSTALL_SBIN_DIR)/netlabelctl + @install -o $(OWNER) -g $(GROUP) -m 644 docs/man/netlabelctl.8 \ + $(INSTALL_MAN_DIR)/man8 + +clean: + @for dir in $(SUBDIRS); do \ + echo "INFO: cleaning in $$dir/"; \ + $(MAKE) -s -C $$dir clean; \ + done + diff --git a/README b/README new file mode 100644 index 0000000..f16627d --- /dev/null +++ b/README @@ -0,0 +1,72 @@ +NetLabel Tools README +============================================================================== +Paul Moore + +* Note on the Documentation + +The text below is intended as a quick start guide to configuring the Linux +NetLabel subsystm using the tools provided in this package. For more +documentation please look in the "docs/" subdirectory. + +* Quick Start + +The first step is to compile and install the netlabelctl application. It +assumes you are already running a kernel with NetLabel support, if you are not +please configure your kernel for NetLabel support before going any further. +Once you have unpacked the NetLabel tools tarball run the following to build +the application: + + # make + +Then as root run the following command to install the required files (installs +to /usr/local by default): + + # make install + +Now you can proceed to configuring the NetLabel system in the kernel. Before +you begin you first need to see if your kernel is already configured to some +extent (it probably is), so run the following commands: + + # netlabelctl -p cipsov4 list + # netlabelctl -p map list + +If you see any configured CIPSO definitions you can remove them with the +following command: + + # netlabelctl -p cipsov4 del doi: + +If you see any domain mappings you can remove them with the following command: + + # netlabelctl -p map del domain: + +You can remove the default domain mapping with this command: + + # netlabelctl -p map del default + +Finally, you set NetLabel to allow or deny incoming unlabeled packets with +the following command: + + # netlabelctl -p unlbl accept on|off + +Now that you have removed any existing NetLabel configuration you can setup a +basic CIPSO configuration. The first step is to add a CIPSO/IPv4 definition +to the kernel. The command below creates a CIPSO/IPv4 definition using a DOI +value of 1, the permissive bitmask tag, and three levels and categories both +mapping straight from the CIPSO values to the local values. + + # netlabelctl cipsov4 add std doi:1 tags:1 levels:0=0,1=1,2=2 \ + categories:0=0,1=1,2=2 + +The next step is to tell the NetLabel system to use this CIPSO/IPv4 defintion +by default. You do that with the following command: + + # netlabelctl map add default protocol:cipsov4,1 + +You can verify that everything is configured correctly with the following two +commands: + + # netlabelctl -p cipsov4 list doi:1 + # netlabelctl -p map list + +For a greater explanation of what these commands do please see the "docs/" +directory, good luck! diff --git a/docs/libnetlabel.txt b/docs/libnetlabel.txt new file mode 100644 index 0000000..6e09e23 --- /dev/null +++ b/docs/libnetlabel.txt @@ -0,0 +1,5 @@ +NetLabel Library +============================================================================== +Paul Moore + +* TBD diff --git a/docs/man/netlabelctl.8 b/docs/man/netlabelctl.8 new file mode 100644 index 0000000..11899ea --- /dev/null +++ b/docs/man/netlabelctl.8 @@ -0,0 +1,84 @@ +.TH "netlabelctl" 1 "14 July 2006" "paul.moore@hp.com" "NetLabel Documentation" +.SH NAME +netlabelctl \- NetLabel control utility +.SH SYNOPSIS +.B netlabelctl +[] [] +.SH DESCRIPTION +.B netlabelctl +allows privileged users to query and manipulate the NetLabel subsystem within +the kernel. +.SH OPTIONS +.TP +Flags +.TP +.B \-h +Help message +.TP +.B \-p +Attempt to make the output "pretty" +.TP +.B \-t +Set a timeout to be used when waiting for the NetLabel subsystem to respond +.TP +.B \-v +Enable extra output +.TP +.B \-V +Display the version information +.TP +Modules +.TP +.B mgmt +The following commands are valid within this module +.nf + +version +protocols +.fi +.TP +.B map +The following commands are valid within this module +.nf + +add default|domain: protocol:[,] +del default|domain: +list +.fi +.TP +.B unlbl +The following commands are valid within this module +.nf + +accept on|off +list +.fi +.TP +.B cipsov4 +The following commands are valid within this module +.nf + +add std doi: tags:, levels:=,= + categories:=,= +add pass doi: tags:, +del doi: +list [doi:] +.fi +.SH "EXAMPLES" +.TP +.B netlabelctl cipsov4 add std doi:8 tags:1 levels:0=0,1=1 categories:0=1,1=0 +Add a CIPSO/IPv4 mapping with a DOI value of "8", using CIPSO tag "1" +(the permissive bitmap tag). The specified mapping converts local LSM levels +"0" and "1" to CIPSO levels "0" and "1" respectively while local LSM categories +"0" and "1" are mapped to CIPSO categories "1" and "0" respectively. +.TP +.B netlabelctl map add domain:lsm_specific_string protocol:cipsov4,8 +Add a domain mapping so that all outgoing packets asscoiated with the +specified LSM domain string will be labeled according to the CIPSO/IPv4 +protocol using DOI 8. +.SH "NOTES" +This program is currently under development, please report any bugs to the author. +.SH "AUTHOR" +Paul Moore +.SH "SEE ALSO" + diff --git a/docs/netlabelctl.txt b/docs/netlabelctl.txt new file mode 100644 index 0000000..cd7db3a --- /dev/null +++ b/docs/netlabelctl.txt @@ -0,0 +1,111 @@ +NetLabel Control Utility +============================================================================== +Paul Moore + +* Introduction + +The NetLabel control utility, netlabelctl, is a command line program designed +to allow system administrators to configure the NetLabel system in the kernel. +The utility is based around different "modules" which correspond to the +different types of NetLabel commands supported by the kernel. + +* The Management Module (mgmt) + +The management module, specified on the command line as "mgmt", is used to +perform general queries about the NetLabel system. The different commands are +as follows: + + # netlabelctl mgmt version + +This command displays the version of the kernel's NetLabel module. + + # netlabelctl mgmt protocols + +This command lists the supported NetLabel protocols. + + # netlabelctl mgmt list + +This command lists the current LSM domain to NetLabel protocol mappings. + +* The Domain Mapping Module (map) + +The domain mapping module, specified on the command line as "map", is used to +map different NetLabel protocols such as CIPSO/IPv4 to LSM domains. Using the +map module you can assign different labeling protcols to each LSM domain or use +a single default labeling protocol. + + # netlabelctl map list + +This command lists the current LSM domain to NetLabel protocol mappings. + + # netlabelctl map add default|domain: protocol:[,] + +This command adds a LSM domain to NetLabel protocol mapping to the kernel. +Users can specify either a specific domain by typing "domain:" or they +can set the default, used when no other mapping matches, by typing "default". +When specifying the protocol to use the following options, including the +"" fields are as follows: + + o protocol:cipsov4, + + This specifies the CIPSO/IPv4 protocol with DOI 1 + + o protocol:unlbl + + This specifies the Unlabeled protocol, there is no "" field + +You can see what mappings are already configured with the "list" command. + + # netlabelctl map del default|domain: + +This command removes a LSM domain to NetLabel protocol mapping from the kernel. + +* The Unlabled Module (unlbl) + +The Unlabeled module, specified on the command line as "unlbl", is used to +configure the handling on unlabeled packets by the NetLabel system in the +kernel. The different commands are as follows: + + # netlabelctl unlbl accept on|off + +This command enables or disables the receipt of unlabeled packets. + + # netlabelctl unlbl list + +This command displays the current unlabeled receive setting. + +* The CIPSO/IPv4 Module (cipsov4) + +The CIPSO/IPv4 module, specified on the command line as "cipsov4", is used to +configure the handling of CIPSO/IPv4 packets by the NetLabel system in the +kernel. The different commands are as follows: + + # netlabelctl cipsov4 list [doi:] + +This command lists all of the defined CIPSO/IPv4 definitions, or if a DOI value +is specified it displays detailed information about the DOI definition. + + # netlabelctl cipsov4 add std doi: tags:, \ + levels:=,= \ + categories:=,= + +This command adds a CIPSO/IPv4 DOI definition to the NetLabel system. The +"" field lets you specify the DOI value. The "" fields let you +specify the CIPSO tags you wish to use with preference given to the first tag +you list (currently only tag type 1 is supported). The "" and "" +fields allow you to define the local, "", to remote/CIPSO, "", +sensitivity level mapping. The "" and "" fields allow you to define +the local, "", to remote/CIPSO, "", category mappings. + + # netlabelctl cipsov4 add pass doi: tags:, + +This command adds a CIPSO/IPv4 DOI definition to the NetLabel system similar +to the "add std" CIPSO/IPv4 command. However, when using the "add pass" +command you do not have the option to translate levels or categories, they are +passed straight through the NetLabel system on both the outbound and inbound +side. + + # netlabelctl cipsov4 del doi: + +This command allows you delete a CIPSO/IPv4 DOI definition. + diff --git a/docs/netlabeld.txt b/docs/netlabeld.txt new file mode 100644 index 0000000..55eb2b0 --- /dev/null +++ b/docs/netlabeld.txt @@ -0,0 +1,5 @@ +NetLabel Daemon +============================================================================== +Paul Moore + +* TBD diff --git a/include/libnetlabel.h b/include/libnetlabel.h new file mode 100644 index 0000000..4e49602 --- /dev/null +++ b/include/libnetlabel.h @@ -0,0 +1,186 @@ +/* + * Header file for libnetlabel.a + * + * 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 + * + */ + +#ifndef _LIBNETLABEL_H +#define _LIBNETLABEL_H + +/* + * Version + */ +#define NETLBL_VER_STRING "0.16" +#define NETLBL_VER_DATE "August 3, 2006" + +/* + * Types + */ + +/* generic types */ +typedef int nlbl_socket; +typedef unsigned int nlbl_type; +typedef unsigned char nlbl_data; + +/* cipso/ipv4 types */ +typedef unsigned int cv4_doi; +typedef unsigned int cv4_maptype; +typedef unsigned char cv4_tag; +typedef struct cv4_tag_array_s { + cv4_tag *array; + ssize_t size; +} cv4_tag_array; +typedef unsigned int cv4_lvl; +typedef struct cv4_lvl_array_s { + cv4_lvl *array; + ssize_t size; +} cv4_lvl_array; +typedef unsigned int cv4_cat; +typedef struct cv4_cat_array_s { + cv4_cat *array; + ssize_t size; +} cv4_cat_array; + +/* management types */ +typedef struct mgmt_domain_s { + char *domain; + size_t domain_len; + nlbl_type proto_type; + union { + struct { + cv4_doi doi; + cv4_maptype maptype; + } cipsov4; + } proto; +} mgmt_domain; + +/* + * Functions + */ + +/*** init/exit */ +int nlbl_netlink_init(void); +void nlbl_netlink_exit(void); + +/*** field functions */ +#define NETLBL_LEN_U8 nlbl_len_payload(1) +#define NETLBL_LEN_U16 nlbl_len_payload(2) +#define NETLBL_LEN_U32 nlbl_len_payload(4) +size_t nlbl_len_payload(size_t len); +void nlbl_putinc_u8(nlbl_data **buffer, + const unsigned char val, + ssize_t *rem_len); +void nlbl_putinc_u16(nlbl_data **buffer, + const unsigned short val, + ssize_t *rem_len); +void nlbl_putinc_u32(nlbl_data **buffer, + const unsigned int val, + ssize_t *rem_len); +void nlbl_putinc_str(nlbl_data **buffer, + const char *val, + ssize_t *rem_len); +size_t nlbl_get_len(const nlbl_data *buffer); +void *nlbl_get_payload(const nlbl_data *buffer); +unsigned char nlbl_get_u8(const nlbl_data *buffer); +unsigned short nlbl_get_u16(const nlbl_data *buffer); +unsigned int nlbl_get_u32(const nlbl_data *buffer); +char *nlbl_get_str(const nlbl_data *buffer); +unsigned char nlbl_getinc_u8(nlbl_data **buffer, ssize_t *rem_len); +unsigned short nlbl_getinc_u16(nlbl_data **buffer, ssize_t *rem_len); +unsigned int nlbl_getinc_u32(nlbl_data **buffer, ssize_t *rem_len); +char *nlbl_getinc_str(nlbl_data **buffer, ssize_t *rem_len); + +/*** low-level communications */ + +/* utility functions */ +void nlbl_netlink_timeout(unsigned int seconds); +size_t nlbl_netlink_msgspace(size_t msg_len); + +/* raw netlink */ +int nlbl_netlink_open(nlbl_socket *sock); +int nlbl_netlink_close(nlbl_socket sock); +int nlbl_netlink_read(nlbl_socket sock, + nlbl_type *type, + nlbl_data **msg, + ssize_t *msg_len); +int nlbl_netlink_write(nlbl_socket sock, + nlbl_type type, + nlbl_data *msg, + size_t msg_len); + +/* management */ +int nlbl_mgmt_write(nlbl_socket sock, nlbl_data *msg, size_t msg_len); + +/* unlabeled */ +int nlbl_unlabeled_write(nlbl_socket sock, nlbl_data *msg, size_t msg_len); + +/* cipso/ipv4 */ +int nlbl_cipsov4_write(nlbl_socket sock, nlbl_data *msg, size_t msg_len); + +/*** operations */ + +/* management */ +int nlbl_mgmt_modules(nlbl_socket sock, + unsigned int **module_list, + size_t *module_count); +int nlbl_mgmt_version(nlbl_socket sock, unsigned int *version); +int nlbl_mgmt_add(nlbl_socket sock, + mgmt_domain *domain_list, + size_t domain_count, + unsigned int def_flag); +int nlbl_mgmt_del(nlbl_socket sock, + char **domains, + size_t *domain_len, + size_t domain_count, + unsigned int def_flag); +int nlbl_mgmt_list(nlbl_socket sock, + mgmt_domain **domain_list, + size_t *domain_count, + unsigned int def_flag); + +/* unlabeled */ +int nlbl_unlabeled_accept(nlbl_socket sock, unsigned int allow_flag); +int nlbl_unlabeled_list(nlbl_socket sock, unsigned int *allow_flag); + +/* cipso/ipv4 */ +int nlbl_cipsov4_add_std(nlbl_socket sock, + cv4_doi doi, + cv4_tag_array *tags, + cv4_lvl_array *lvls, + cv4_cat_array *cats); +int nlbl_cipsov4_add_pass(nlbl_socket sock, + cv4_doi doi, + cv4_tag_array *tags); +int nlbl_cipsov4_del(nlbl_socket sock, cv4_doi doi); +int nlbl_cipsov4_list(nlbl_socket sock, + cv4_doi doi, + cv4_maptype *maptype, + cv4_tag_array *tags, + cv4_lvl_array *lvls, + cv4_cat_array *cats); +int nlbl_cipsov4_list_all(nlbl_socket sock, + cv4_doi **doi_list, + cv4_maptype **mtype_list, + size_t *count); + +#endif diff --git a/include/linux/netlabel.h b/include/linux/netlabel.h new file mode 100644 index 0000000..a6695af --- /dev/null +++ b/include/linux/netlabel.h @@ -0,0 +1,189 @@ +/* + * 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 + * + */ + +#ifndef _NETLABEL_H +#define _NETLABEL_H + +/* + * Generic NETLINK interface + */ + +#define INCLUDE_NL_GUTS +#ifdef INCLUDE_NL_GUTS + +/* FIXME: perhaps some or all this lives in a system header file? */ + +#define NLMSG_HDRLEN NLMSG_ALIGN(sizeof(struct nlmsghdr)) + +struct nlattr +{ + unsigned short nla_len; + unsigned short nla_type; +}; + +enum { + NLA_UNSPEC, + NLA_U8, + NLA_U16, + NLA_U32, + NLA_U64, + NLA_STRING, + NLA_FLAG, + NLA_MSECS, + NLA_NESTED, + __NLA_TYPE_MAX, +}; +#define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1) + +#define NLA_HDRLEN NLMSG_ALIGN(sizeof(struct nlattr)) + +#define NETLINK_GENERIC 16 + +struct genlmsghdr { + unsigned char cmd; + unsigned char version; + unsigned short reserved; +}; +#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr)) + +#define GENL_ID_GENERATE 0 +#define GENL_ID_CTRL 0x10 + +enum { + CTRL_CMD_UNSPEC, + CTRL_CMD_NEWFAMILY, + CTRL_CMD_DELFAMILY, + CTRL_CMD_GETFAMILY, + CTRL_CMD_NEWOPS, + CTRL_CMD_DELOPS, + CTRL_CMD_GETOPS, + __CTRL_CMD_MAX, +}; +#define CTRL_CMD_MAX (__CTRL_CMD_MAX - 1) + +enum { + CTRL_ATTR_UNSPEC, + CTRL_ATTR_FAMILY_ID, + CTRL_ATTR_FAMILY_NAME, + __CTRL_ATTR_MAX, +}; +#define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1) + +#endif /* INCLUDE_NL_GUTS */ + +/* + * NetLabel NETLINK protocol + */ + +#define NETLBL_PROTO_VERSION 1 + +/* NetLabel NETLINK types/families */ +#define NETLBL_NLTYPE_NONE 0 +#define NETLBL_NLTYPE_MGMT 1 +#define NETLBL_NLTYPE_MGMT_NAME "NLBL_MGMT" +#define NETLBL_NLTYPE_RIPSO 2 +#define NETLBL_NLTYPE_RIPSO_NAME "NLBL_RIPSO" +#define NETLBL_NLTYPE_CIPSOV4 3 +#define NETLBL_NLTYPE_CIPSOV4_NAME "NLBL_CIPSOv4" +#define NETLBL_NLTYPE_CIPSOV6 4 +#define NETLBL_NLTYPE_CIPSOV6_NAME "NLBL_CIPSOv6" +#define NETLBL_NLTYPE_UNLABELED 5 +#define NETLBL_NLTYPE_UNLABELED_NAME "NLBL_UNLBL" + +/* Generic return codes */ +#define NETLBL_E_OK 0 + +/* + * MGMT + */ + +/* NetLabel Management commands */ +enum { + NLBL_MGMT_C_UNSPEC, + NLBL_MGMT_C_ACK, + NLBL_MGMT_C_ADD, + NLBL_MGMT_C_REMOVE, + NLBL_MGMT_C_LIST, + NLBL_MGMT_C_ADDDEF, + NLBL_MGMT_C_REMOVEDEF, + NLBL_MGMT_C_LISTDEF, + NLBL_MGMT_C_MODULES, + NLBL_MGMT_C_VERSION, + __NLBL_MGMT_C_MAX, +}; +#define NLBL_MGMT_C_MAX (__NLBL_MGMT_C_MAX - 1) + +/* + * RIPSO + */ + +/* XXX - TBD */ + +/* + * CIPSO V4 + */ + +/* CIPSOv4 DOI map types */ +#define CIPSO_V4_MAP_UNKNOWN 0 +#define CIPSO_V4_MAP_STD 1 +#define CIPSO_V4_MAP_PASS 2 + +/* NetLabel CIPSOv4 commands */ +enum { + NLBL_CIPSOV4_C_UNSPEC, + NLBL_CIPSOV4_C_ACK, + NLBL_CIPSOV4_C_ADD, + NLBL_CIPSOV4_C_REMOVE, + NLBL_CIPSOV4_C_LIST, + NLBL_CIPSOV4_C_LISTALL, + __NLBL_CIPSOV4_C_MAX, +}; +#define NLBL_CIPSOV4_C_MAX (__NLBL_CIPSOV4_C_MAX - 1) + +/* + * CIPSO V6 + */ + +/* XXX - TBD */ + +/* + * UNLABELED + */ + +/* NetLabel Unlabeled commands */ +enum { + NLBL_UNLABEL_C_UNSPEC, + NLBL_UNLABEL_C_ACK, + NLBL_UNLABEL_C_ACCEPT, + NLBL_UNLABEL_C_LIST, + __NLBL_UNLABEL_C_MAX, +}; +#define NLBL_UNLABEL_C_MAX (__NLBL_UNLABEL_C_MAX - 1) + +#endif /* _NETLABEL_H */ diff --git a/libnetlabel/Makefile b/libnetlabel/Makefile new file mode 100644 index 0000000..e135eef --- /dev/null +++ b/libnetlabel/Makefile @@ -0,0 +1,58 @@ +# +# NetLabel Library Makefile +# +# NetLabel Tools are a collection of user space programs and libraries for +# working with the Linux NetLabel subsystem. The NetLabel subsystem 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 +# + +# +# macros +# + +include ../macros.mk + +# +# configuration +# + +OBJS = netlabel_init.o netlink_comm.o fields.o common.o \ + mod_mgmt.o mod_unlabeled.o mod_cipsov4.o + +LIB = libnetlabel.a + +# +# targets +# + +.PHONY: clean + +all: $(LIB) + +$(LIB): $(OBJS) + $(ARCHIVE) + +clean: + $(RM) -f $(OBJS) $(LIB) + diff --git a/libnetlabel/common.c b/libnetlabel/common.c new file mode 100644 index 0000000..c076da8 --- /dev/null +++ b/libnetlabel/common.c @@ -0,0 +1,66 @@ +/* + * NetLabel Library Common Functions + * + * 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 + +/* + * NetLabel protocol functions + */ + +/** + * nlbl_common_ack_parse - Common ACK parser + * @msg: the NetLabel message + * @msg_len: the length in bytes + * @ack_type: the type of ACK to check for + * + * Description: + * Parse the ACK in @msg and return the negated return code, otherwise return + * -ENOMSG. + * + */ +int nlbl_common_ack_parse(nlbl_data *msg, + ssize_t msg_len, + unsigned int ack_type) +{ + struct genlmsghdr *genl_hdr = (struct genlmsghdr *)msg; + nlbl_data *msg_iter; + + if (genl_hdr->cmd != ack_type || + msg_len != GENL_HDRLEN + 2 * NETLBL_LEN_U32) + return -ENOMSG; + msg_iter = msg + GENL_HDRLEN + NETLBL_LEN_U32; + + return -nlbl_get_u32(msg_iter); +} diff --git a/libnetlabel/common.h b/libnetlabel/common.h new file mode 100644 index 0000000..b1e971e --- /dev/null +++ b/libnetlabel/common.h @@ -0,0 +1,34 @@ +/* + * NetLabel Library Common Functions + * + * 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 + * + */ + +#ifndef _COMMON_H_ +#define _COMMON_H_ + +int nlbl_common_ack_parse(nlbl_data *msg, + ssize_t msg_len, + unsigned int ack_type); + +#endif diff --git a/libnetlabel/fields.c b/libnetlabel/fields.c new file mode 100644 index 0000000..3137d0e --- /dev/null +++ b/libnetlabel/fields.c @@ -0,0 +1,427 @@ +/* + * NetLabel Library Field Functions + * + * 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 + +/** + * nlbl_put_hdr - Write a NETLINK header into a buffer + * @buffer: the buffer + * @msg_type: the NETLINK message type + * @msg_len: the NETLINK message length + * @msg_flags: the NETLINK message flags + * @msg_pid: the NETLINK message PID + * @msg_seq: the NETLINK message sequence number + * + * Description: + * Use the given values to write a NETLINK header into the given buffer. + * + */ +void nlbl_put_hdr(nlbl_data *buffer, + const unsigned int msg_type, + const unsigned short msg_len, + const unsigned short msg_flags, + const unsigned int msg_pid, + const unsigned int msg_seq) +{ + struct nlmsghdr *hdr = (struct nlmsghdr *)buffer; + hdr->nlmsg_len = msg_len; + hdr->nlmsg_type = msg_type; + hdr->nlmsg_flags = msg_flags; + hdr->nlmsg_seq = msg_seq; + hdr->nlmsg_pid = msg_pid; +} + +/** + * nlbl_put_genlhdr - Write a Generic NETLINK header into a buffer + * @buffer: the buffer + * @cmd: the command + * + * Description: + * Use the given values to write a Generic NETLINK header into the given + * buffer. + * + */ +void nlbl_put_genlhdr(nlbl_data *buffer, unsigned int cmd) +{ + struct genlmsghdr *hdr = (struct genlmsghdr *)buffer; + hdr->cmd = cmd; + hdr->version = NETLBL_PROTO_VERSION; + hdr->reserved = 0; +} + +/** + * nlbl_putinc_u8 - Write a u8 value into a buffer and increment the buffer + * @buffer: the buffer + * @val: the value + * @rem_len: remaining length + * + * Description: + * Write the value specified in @val into the buffer specified by @buffer + * and advance the buffer pointer past the newly written value. If @rem_len + * is not NULL then decrement it by the field length. + * + */ +void nlbl_putinc_u8(nlbl_data **buffer, + const unsigned char val, + ssize_t *rem_len) +{ + struct nlattr *nla = (struct nlattr *)*buffer; + + nla->nla_len = NLA_HDRLEN + sizeof(val); + nla->nla_type = NLA_U8; + + *buffer += NLA_HDRLEN; + *(unsigned char *)*buffer = val; + *buffer += NLMSG_ALIGN(sizeof(val)); + + if (rem_len != NULL) + *rem_len -= NLA_HDRLEN + NLMSG_ALIGN(sizeof(val)); +} + +/** + * nlbl_putinc_u16 - Write a u16 value into a buffer and increment the buffer + * @buffer: the buffer + * @val: the value + * @rem_len: remaining length + * + * Description: + * Write the value specified in @val into the buffer specified by @buffer + * and advance the buffer pointer past the newly written value. If @rem_len + * is not NULL then decrement it by the field length. + * + */ +void nlbl_putinc_u16(nlbl_data **buffer, + const unsigned short val, + ssize_t *rem_len) +{ + struct nlattr *nla = (struct nlattr *)*buffer; + + nla->nla_len = NLA_HDRLEN + sizeof(val); + nla->nla_type = NLA_U16; + + *buffer += NLA_HDRLEN; + *(unsigned short *)*buffer = val; + *buffer += NLMSG_ALIGN(sizeof(val)); + + if (rem_len != NULL) + *rem_len -= NLA_HDRLEN + NLMSG_ALIGN(sizeof(val)); +} + +/** + * nlbl_putinc_u32 - Write a u32 value into a buffer and increment the buffer + * @buffer: the buffer + * @val: the value + * @rem_len: remaining length + * + * Description: + * Write the value specified in @val into the buffer specified by @buffer + * and advance the buffer pointer past the newly written value. If @rem_len + * is not NULL then decrement it by the field length. + * + */ +void nlbl_putinc_u32(nlbl_data **buffer, + const unsigned int val, + ssize_t *rem_len) +{ + struct nlattr *nla = (struct nlattr *)*buffer; + + nla->nla_len = NLA_HDRLEN + sizeof(val); + nla->nla_type = NLA_U32; + + *buffer += NLA_HDRLEN; + *(unsigned int *)*buffer = val; + *buffer += NLMSG_ALIGN(sizeof(val)); + + if (rem_len != NULL) + *rem_len -= NLA_HDRLEN + NLMSG_ALIGN(sizeof(val)); +} + +/** + * nlbl_putinc_str - Write a string into a buffer and increment the buffer + * @buffer: the buffer + * @val: the value + * @rem_len: remaining length + * + * Description: + * Write the string specified in @val into the buffer specified by @buffer + * and advance the buffer pointer past the newly written value. If @rem_len + * is not NULL then decrement it by the field length. + * + */ +void nlbl_putinc_str(nlbl_data **buffer, + const char *val, + ssize_t *rem_len) +{ + struct nlattr *nla = (struct nlattr *)*buffer; + + nla->nla_len = NLA_HDRLEN + strlen(val) + 1; + nla->nla_type = NLA_STRING; + + *buffer += NLA_HDRLEN; + strcpy((char *)*buffer, val); + *buffer += NLMSG_ALIGN(strlen(val) + 1); + + if (rem_len != NULL) + *rem_len -= NLA_HDRLEN + NLMSG_ALIGN(strlen(val) + 1); +} + +/** + * nlbl_put_hdr - Write a NETLINK header into a buffer and increment the ptr + * @buffer: the buffer + * @msg_type: the NETLINK message type + * @msg_len: the NETLINK message length + * @msg_flags: the NETLINK message flags + * @msg_pid: the NETLINK message PID + * @msg_seq: the NETLINK message sequence number + * + * Description: + * Use the given values to write a NETLINK header into the given buffer and + * then increment the buffer pointer past the header. + * + */ +void nlbl_putinc_hdr(nlbl_data **buffer, + const unsigned int msg_type, + const unsigned short msg_len, + const unsigned short msg_flags, + const unsigned int msg_pid, + const unsigned int msg_seq) +{ + nlbl_put_hdr(*buffer, + msg_type, + msg_len, + msg_flags, + msg_pid, + msg_seq); + *buffer += NLMSG_HDRLEN; +} + +/** + * nlbl_putinc_genlhdr - Write a Generic NETLINK header into a buffer + * @buffer: the buffer + * @cmd: the command + * + * Description: + * Use the given values to write a Generic NETLINK header into the given + * buffer and then increment the buffer pointer past the header. + * + */ +void nlbl_putinc_genlhdr(nlbl_data **buffer, unsigned int cmd) +{ + nlbl_put_genlhdr(*buffer, cmd); + *buffer += GENL_HDRLEN; +} + +/** + * nlbl_get_len - Return the data length of the current field + * @buffer: the buffer + * + * Description: + * Returns the length, in bytes, of the current NetLabel field not including + * any padding. + * + */ +size_t nlbl_get_len(const nlbl_data *buffer) +{ + struct nlattr *nla = (struct nlattr *)buffer; + return nla->nla_len - NLA_HDRLEN; +} + +/** + * nlbl_get_payload - Return a pointer to the payload + * @buffer: the buffer + * + * Description: + * Return a pointer to the buffer's payload. + * + */ +void *nlbl_get_payload(const nlbl_data *buffer) +{ + return (void *)(buffer + NLA_HDRLEN); +} + +/** + * nlbl_get_u8 - Read a u8 value from a buffer + * @buffer: the buffer + * + * Description: + * Return a u8 value pointed to by @buffer. + * + */ +unsigned char nlbl_get_u8(const nlbl_data *buffer) +{ + return *(unsigned char *)nlbl_get_payload(buffer); +} + +/** + * nlbl_get_u16 - Read a u16 value from a buffer + * @buffer: the buffer + * + * Description: + * Return a u16 value pointed to by @buffer. + * + */ +unsigned short nlbl_get_u16(const nlbl_data *buffer) +{ + return *(unsigned short *)nlbl_get_payload(buffer); +} + +/** + * nlbl_get_u32 - Read a u32 value from a buffer + * @buffer: the buffer + * + * Description: + * Return a u32 value pointed to by @buffer. + * + */ +unsigned int nlbl_get_u32(const nlbl_data *buffer) +{ + return *(unsigned int *)nlbl_get_payload(buffer); +} + +/** + * nlbl_get_str - Read a string from a buffer + * @buffer: the buffer + * + * Description: + * Return a pointer to the string value pointed to by @buffer. + * + */ +char *nlbl_get_str(const nlbl_data *buffer) +{ + size_t len = nlbl_get_len(buffer); + char *str = malloc(len); + if (str == NULL) + return NULL; + strncpy(str, nlbl_get_payload(buffer), len); + return str; +} + +/** + * nlbl_getinc_u8 - Read a u8 value from a buffer and increment the buffer + * @buffer: the buffer + * @rem_len: remaining length + * + * Description: + * Return a u8 value pointed to by @buffer and increment the buffer pointer + * past the value. If @rem_len is not NULL, decrement it by the field size. + * + */ +unsigned char nlbl_getinc_u8(nlbl_data **buffer, ssize_t *rem_len) +{ + struct nlattr *nla = (struct nlattr *)*buffer; + size_t len = NLMSG_ALIGN(nla->nla_len); + unsigned char val = nlbl_get_u8(*buffer); + *buffer += len; + if (rem_len != NULL) + *rem_len -= len; + return val; +} + +/** + * nlbl_getinc_u16 - Read a u16 value from a buffer and increment the buffer + * @buffer: the buffer + * @rem_len: remaining length + * + * Description: + * Return a u16 value pointed to by @buffer and increment the buffer pointer + * past the value. If @rem_len is not NULL, decrement it by the field size. + * + */ +unsigned short nlbl_getinc_u16(nlbl_data **buffer, ssize_t *rem_len) +{ + struct nlattr *nla = (struct nlattr *)*buffer; + size_t len = NLMSG_ALIGN(nla->nla_len); + unsigned short val = nlbl_get_u16(*buffer); + *buffer += len; + if (rem_len != NULL) + *rem_len -= len; + return val; +} + +/** + * nlbl_getinc_u32 - Read a u32 value from a buffer and increment the buffer + * @buffer: the buffer + * @rem_len: remaining length + * + * Description: + * Return a u32 value pointed to by @buffer and increment the buffer pointer + * past the value. If @rem_len is not NULL, decrement it by the field size. + * + */ +unsigned int nlbl_getinc_u32(nlbl_data **buffer, ssize_t *rem_len) +{ + struct nlattr *nla = (struct nlattr *)*buffer; + size_t len = NLMSG_ALIGN(nla->nla_len); + unsigned int val = nlbl_get_u32(*buffer); + *buffer += len; + if (rem_len != NULL) + *rem_len -= len; + return val; +} + +/** + * nlbl_getinc_str - Read a string from a buffer and increment the buffer + * @buffer: the buffer + * @rem_len: remaining length + * + * Description: + * Return a string pointer pointed to by @buffer and increment the buffer + * pointer past the value. If @rem_len is not NULL, decrement it by the field + * size. + * + */ +char *nlbl_getinc_str(nlbl_data **buffer, ssize_t *rem_len) +{ + struct nlattr *nla = (struct nlattr *)*buffer; + size_t len = NLMSG_ALIGN(nla->nla_len); + char *val = nlbl_get_str(*buffer); + *buffer += len; + if (rem_len != NULL) + *rem_len -= len; + return val; +} + +/** + * nlbl_len_payload - Return the size of a NetLabel field + * @len: the length of the payload in bytes + * + * Description: + * Returns the size in bytes of a NetLabel field given a payload of + * length @len. + * + */ +size_t nlbl_len_payload(size_t len) +{ + return NLA_HDRLEN + NLMSG_ALIGN(len); +} diff --git a/libnetlabel/fields.h b/libnetlabel/fields.h new file mode 100644 index 0000000..34c7389 --- /dev/null +++ b/libnetlabel/fields.h @@ -0,0 +1,45 @@ +/* + * NetLabel Library Field Functions + * + * 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 + * + */ + +#ifndef _FIELDS_H_ +#define _FIELDS_H_ + +void nlbl_put_hdr(nlbl_data *buffer, + const unsigned int msg_type, + const unsigned short msg_len, + const unsigned short msg_flags, + const unsigned int msg_pid, + const unsigned int msg_seq); +void nlbl_put_genlhdr(nlbl_data *buffer, unsigned int cmd); +void nlbl_putinc_hdr(nlbl_data **buffer, + const unsigned int msg_type, + const unsigned short msg_len, + const unsigned short msg_flags, + const unsigned int msg_pid, + const unsigned int msg_seq); +void nlbl_putinc_genlhdr(nlbl_data **buffer, unsigned int cmd); + +#endif diff --git a/libnetlabel/mod_cipsov4.c b/libnetlabel/mod_cipsov4.c new file mode 100644 index 0000000..9ec8a03 --- /dev/null +++ b/libnetlabel/mod_cipsov4.c @@ -0,0 +1,708 @@ +/* + * CIPSO/IPv4 Module Functions + * + * 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 "fields.h" +#include "common.h" + +/* Generic NETLINK family ID */ +static nlbl_type nlbl_cipsov4_fid = -1; + +/* + * Init functions + */ + + +/** + * nlbl_cipsov4_init - Perform any setup needed + * + * Description: + * Do any setup needed for the CIPSOv4 component, including determining the + * NetLabel CIPSOv4 Generic NETLINK family ID. Returns zero on success, + * negative values on error. + * + */ +int nlbl_cipsov4_init(void) +{ + int ret_val; + nlbl_socket sock; + nlbl_data *msg = NULL; + nlbl_data *msg_iter; + ssize_t msg_len; + struct genlmsghdr *genl_hdr; + struct nlattr *nla_hdr; + nlbl_type nl_type; + + /* open a socket */ + ret_val = nlbl_netlink_open(&sock); + if (ret_val < 0) + return ret_val; + + /* allocate a buffer for the family id request */ + msg_len = GENL_HDRLEN + NLA_HDRLEN + strlen(NETLBL_NLTYPE_CIPSOV4_NAME) + 1; + msg = malloc(msg_len); + if (msg == NULL) { + ret_val = -ENOMEM; + goto init_return; + } + memset(msg, 0, msg_len); + msg_iter = msg; + + /* write the genetlink header into the buffer */ + genl_hdr = (struct genlmsghdr *)msg_iter; + genl_hdr->cmd = CTRL_CMD_GETFAMILY; + genl_hdr->version = 1; + + /* write the attribute into the buffer */ + msg_iter += GENL_HDRLEN; + nla_hdr = (struct nlattr *)msg_iter; + nla_hdr->nla_len = NLA_HDRLEN + strlen(NETLBL_NLTYPE_CIPSOV4_NAME) + 1; + nla_hdr->nla_type = CTRL_ATTR_FAMILY_NAME; + msg_iter += NLA_HDRLEN; + strcpy((char *)msg_iter, NETLBL_NLTYPE_CIPSOV4_NAME); + + /* send the message */ + ret_val = nlbl_netlink_write(sock, GENL_ID_CTRL, msg, msg_len); + if (ret_val < 0) + goto init_return; + free(msg); + msg = NULL; + msg_len = 0; + + /* read the response */ + ret_val = nlbl_netlink_read(sock, &nl_type, &msg, &msg_len); + if (ret_val < 0) + goto init_return; + if (nl_type != GENL_ID_CTRL) { + ret_val = -ENOMSG; + goto init_return; + } + msg_iter = msg + NLMSG_LENGTH(0); + + /* parse the response */ + genl_hdr = (struct genlmsghdr *) msg_iter; + if (genl_hdr->cmd != CTRL_CMD_NEWFAMILY) { + ret_val = -ENOMSG; + goto init_return; + } + msg_iter += GENL_HDRLEN; + do { + nla_hdr = (struct nlattr *)msg_iter; + msg_iter += NLMSG_ALIGN(nla_hdr->nla_len); + } while (msg_iter - msg < msg_len || + nla_hdr->nla_type != CTRL_ATTR_FAMILY_ID); + if (nla_hdr->nla_type != CTRL_ATTR_FAMILY_ID) { + ret_val = -ENOMSG; + goto init_return; + } + nlbl_cipsov4_fid = nlbl_get_u16((unsigned char *)nla_hdr); + + ret_val = 0; + + init_return: + if (msg) + free(msg); + nlbl_netlink_close(sock); + return ret_val; +} + +/* + * Low-level communications + */ + + +/** + * nlbl_cipsov4_write - Send a NetLabel CIPSOv4 message + * @sock: the socket + * @msg: the message + * @msg_len: the message length + * + * Description: + * Write the message in @msg to the NetLabel socket @sock. Returns zero on + * success, negative values on failure. + * + */ +int nlbl_cipsov4_write(nlbl_socket sock, nlbl_data *msg, size_t msg_len) +{ + return nlbl_netlink_write(sock, nlbl_cipsov4_fid, msg, msg_len); +} + +/** + * nlbl_cipsov4_read - Read a NetLbel CIPSOv4 message + * @sock: the socket + * @msg: the message + * @msg_len: the message length + * + * Description: + * Try to read a NetLabel CIPSOv4 message and return the message in @msg. + * Returns negative values on failure. + * + */ +int nlbl_cipsov4_read(nlbl_socket sock, nlbl_data **msg, ssize_t *msg_len) +{ + int ret_val; + nlbl_type nl_type; + + ret_val = nlbl_netlink_read(sock, &nl_type, msg, msg_len); + if (ret_val >= 0 && nl_type != nlbl_cipsov4_fid) + return -ENOMSG; + + return ret_val; +} + +/* + * NetLabel operations + */ + + +/** + * nlbl_cipsov4_add_std - Add a standard CIPSOv4 label mapping + * @sock: the NetLabel socket + * @doi: the CIPSO DOI number + * @tags: array of tag numbers + * @lvls: array of level mappings + * @cats: array of category mappings + * + * Description: + * Add the specified static CIPSO label mapping information to the NetLabel + * system. If @sock is zero then the function will handle opening and closing + * it's own NETLINK socket. Returns zero on success, negative values on + * failure. + * + */ +int nlbl_cipsov4_add_std(nlbl_socket sock, + cv4_doi doi, + cv4_tag_array *tags, + cv4_lvl_array *lvls, + cv4_cat_array *cats) +{ + int ret_val = -EPERM; + nlbl_socket local_sock = sock; + nlbl_data *msg = NULL; + nlbl_data *msg_iter; + ssize_t msg_len; + unsigned int iter; + unsigned int tmp_val; + + /* sanity checks */ + if (sock < 0 || tags == NULL || lvls == NULL || cats == NULL || + tags->size == 0 || lvls->size == 0 || cats->size == 0) + return -EINVAL; + + /* open a socket if we need one */ + if (sock == 0) { + ret_val = nlbl_netlink_open(&local_sock); + if (ret_val < 0) + return ret_val; + } + + /* allocate a buffer for the message */ + msg_len = GENL_HDRLEN + 7 * NETLBL_LEN_U32 + NETLBL_LEN_U8 + NETLBL_LEN_U16 + + tags->size * NETLBL_LEN_U8 + + lvls->size * (NETLBL_LEN_U32 + NETLBL_LEN_U8) + + cats->size * (NETLBL_LEN_U32 + NETLBL_LEN_U16); + msg = malloc(msg_len); + if (msg == NULL) { + ret_val = -ENOMEM; + goto add_std_return; + } + memset(msg, 0, msg_len); + msg_iter = msg; + + /* write the message into the buffer */ + nlbl_putinc_genlhdr(&msg_iter, NLBL_CIPSOV4_C_ADD); + nlbl_putinc_u32(&msg_iter, doi, NULL); + nlbl_putinc_u32(&msg_iter, CIPSO_V4_MAP_STD, NULL); + nlbl_putinc_u32(&msg_iter, tags->size, NULL); + for (iter = 0; iter < tags->size; iter++) + nlbl_putinc_u8(&msg_iter, tags->array[iter], NULL); + nlbl_putinc_u32(&msg_iter, lvls->size, NULL); + for (iter = 0, tmp_val = 0; iter < lvls->size; iter++) + if (lvls->array[iter * 2] > tmp_val) + tmp_val = lvls->array[iter * 2]; + nlbl_putinc_u32(&msg_iter, tmp_val + 1, NULL); + for (iter = 0, tmp_val = 0; iter < lvls->size; iter++) + if (lvls->array[iter * 2 + 1] > tmp_val) + tmp_val = lvls->array[iter * 2 + 1]; + nlbl_putinc_u8(&msg_iter, tmp_val + 1, NULL); + nlbl_putinc_u32(&msg_iter, cats->size, NULL); + for (iter = 0, tmp_val = 0; iter < cats->size; iter++) + if (cats->array[iter * 2] > tmp_val) + tmp_val = cats->array[iter * 2]; + nlbl_putinc_u32(&msg_iter, tmp_val + 1, NULL); + for (iter = 0, tmp_val = 0; iter < cats->size; iter++) + if (cats->array[iter * 2 + 1] > tmp_val) + tmp_val = cats->array[iter * 2 + 1]; + nlbl_putinc_u16(&msg_iter, tmp_val + 1, NULL); + for (iter = 0; iter < lvls->size; iter++) { + nlbl_putinc_u32(&msg_iter, lvls->array[iter * 2], NULL); + nlbl_putinc_u8(&msg_iter, lvls->array[iter * 2 + 1], NULL); + } + for (iter = 0; iter < cats->size; iter++) { + nlbl_putinc_u32(&msg_iter, cats->array[iter * 2], NULL); + nlbl_putinc_u16(&msg_iter, cats->array[iter * 2 + 1], NULL); + } + + /* send the request */ + ret_val = nlbl_cipsov4_write(local_sock, msg, msg_len); + if (ret_val < 0) + goto add_std_return; + free(msg); + msg = NULL; + msg_len = 0; + + /* read the results */ + ret_val = nlbl_cipsov4_read(local_sock, &msg, &msg_len); + if (ret_val < 0) + goto add_std_return; + + /* parse the response */ + ret_val = nlbl_common_ack_parse(msg + NLMSG_LENGTH(0), + msg_len - NLMSG_LENGTH(0), + NLBL_CIPSOV4_C_ACK); + + add_std_return: + if (msg) + free(msg); + if (sock == 0) + nlbl_netlink_close(local_sock); + + return ret_val; +} + +/** + * nlbl_cipsov4_add_pass - Add a pass through CIPSOv4 label mapping + * @sock: the NetLabel socket + * @doi: the CIPSO DOI number + * @tags: array of tag numbers + * + * Description: + * Add the specified pass through CIPSO label mapping information to the + * NetLabel system. If @sock is zero then the function will handle opening + * and closing it's own NETLINK socket. Returns zero on success, negative + * values on failure. + * + */ +int nlbl_cipsov4_add_pass(nlbl_socket sock, + cv4_doi doi, + cv4_tag_array *tags) +{ + int ret_val = -EPERM; + nlbl_socket local_sock = sock; + nlbl_data *msg = NULL; + nlbl_data *msg_iter; + ssize_t msg_len; + unsigned int iter; + + /* sanity checks */ + if (sock < 0 || tags == NULL || tags->size == 0) + return -EINVAL; + + /* open a socket if we need one */ + if (sock == 0) { + ret_val = nlbl_netlink_open(&local_sock); + if (ret_val < 0) + return ret_val; + } + + /* allocate a buffer for the message */ + msg_len = GENL_HDRLEN + 3 * NETLBL_LEN_U32 + tags->size * NETLBL_LEN_U8; + msg = malloc(msg_len); + if (msg == NULL) { + ret_val = -ENOMEM; + goto add_pass_return; + } + memset(msg, 0, msg_len); + msg_iter = msg; + + /* write the message into the buffer */ + nlbl_putinc_genlhdr(&msg_iter, NLBL_CIPSOV4_C_ADD); + nlbl_putinc_u32(&msg_iter, doi, NULL); + nlbl_putinc_u32(&msg_iter, CIPSO_V4_MAP_PASS, NULL); + nlbl_putinc_u32(&msg_iter, tags->size, NULL); + for (iter = 0; iter < tags->size; iter++) + nlbl_putinc_u8(&msg_iter, tags->array[iter], NULL); + + /* send the request */ + ret_val = nlbl_cipsov4_write(local_sock, msg, msg_len); + if (ret_val < 0) + goto add_pass_return; + free(msg); + msg = NULL; + msg_len = 0; + + /* read the results */ + ret_val = nlbl_cipsov4_read(local_sock, &msg, &msg_len); + if (ret_val < 0) + goto add_pass_return; + + /* parse the response */ + ret_val = nlbl_common_ack_parse(msg + NLMSG_LENGTH(0), + msg_len - NLMSG_LENGTH(0), + NLBL_CIPSOV4_C_ACK); + + add_pass_return: + if (msg) + free(msg); + if (sock == 0) + nlbl_netlink_close(local_sock); + + return ret_val; +} + +/** + * nlbl_cipsov4_del - Delete a CIPSOv4 label mapping + * @sock: the NetLabel socket + * @doi: the CIPSO DOI number + * + * Description: + * Remove the CIPSO label mapping with the DOI value matching @doi. If @sock + * is zero then the function will handle opening and closing it's own NETLINK + * socket. Returns zero on success, negative values on failure. + * + */ +int nlbl_cipsov4_del(nlbl_socket sock, cv4_doi doi) +{ + int ret_val = -EPERM; + nlbl_socket local_sock = sock; + nlbl_data *msg = NULL; + nlbl_data *msg_iter; + ssize_t msg_len; + + /* sanity checks */ + if (sock < 0) + return -EINVAL; + + /* open a socket if we need one */ + if (sock == 0) { + ret_val = nlbl_netlink_open(&local_sock); + if (ret_val < 0) + return ret_val; + } + + /* allocate a buffer for the message */ + msg_len = GENL_HDRLEN + NETLBL_LEN_U32; + msg = malloc(msg_len); + if (msg == NULL) { + ret_val = -ENOMEM; + goto del_return; + } + memset(msg, 0, msg_len); + msg_iter = msg; + + /* write the message into the buffer */ + nlbl_putinc_genlhdr(&msg_iter, NLBL_CIPSOV4_C_REMOVE); + nlbl_putinc_u32(&msg_iter, doi, NULL); + + /* send the request */ + ret_val = nlbl_cipsov4_write(local_sock, msg, msg_len); + if (ret_val < 0) + goto del_return; + free(msg); + msg = NULL; + msg_len = 0; + + /* read the results */ + ret_val = nlbl_cipsov4_read(local_sock, &msg, &msg_len); + if (ret_val < 0) + goto del_return; + + /* parse the response */ + ret_val = nlbl_common_ack_parse(msg + NLMSG_LENGTH(0), + msg_len - NLMSG_LENGTH(0), + NLBL_CIPSOV4_C_ACK); + + del_return: + if (msg) + free(msg); + if (sock == 0) + nlbl_netlink_close(local_sock); + + return ret_val; +} + +/** + * nlbl_cipsov4_list - List the details of a specific CIPSOv4 label mapping + * @sock: the NetLabel socket + * @doi: the CIPSO DOI number + * @maptype: the DOI mapping type + * @tags: array of tag numbers + * @lvls: array of level mappings + * @cats: array of category mappings + * + * Description: + * Query the kernel for the specified CIPSOv4 mapping specified by @doi and + * return the details of the mapping to the caller. If @sock is zero then the + * function will handle opening and closing it's own NETLINK socket. Returns + * zero on success, negative values on failure. + * + */ +int nlbl_cipsov4_list(nlbl_socket sock, + cv4_doi doi, + cv4_maptype *maptype, + cv4_tag_array *tags, + cv4_lvl_array *lvls, + cv4_cat_array *cats) +{ + int ret_val = -EPERM; + nlbl_socket local_sock = sock; + nlbl_data *msg = NULL; + nlbl_data *msg_iter; + ssize_t msg_len; + struct genlmsghdr *genl_hdr; + unsigned int iter; + + /* sanity checks */ + if (sock < 0 || tags == NULL || lvls == NULL || cats == NULL) + return -EINVAL; + + /* open a socket if we need one */ + if (sock == 0) { + ret_val = nlbl_netlink_open(&local_sock); + if (ret_val < 0) + return ret_val; + } + + /* allocate a buffer for the message */ + msg_len = GENL_HDRLEN + NETLBL_LEN_U32; + msg = malloc(msg_len); + if (msg == NULL) { + ret_val = -ENOMEM; + goto list_return; + } + memset(msg, 0, msg_len); + msg_iter = msg; + + /* write the message into the buffer */ + nlbl_putinc_genlhdr(&msg_iter, NLBL_CIPSOV4_C_LIST); + nlbl_putinc_u32(&msg_iter, doi, NULL); + + /* send the request */ + ret_val = nlbl_cipsov4_write(local_sock, msg, msg_len); + if (ret_val < 0) + goto list_return; + free(msg); + msg = NULL; + msg_len = 0; + + /* read the results */ + ret_val = nlbl_cipsov4_read(local_sock, &msg, &msg_len); + if (ret_val < 0) + goto list_return; + msg_iter = msg + NLMSG_LENGTH(0); + msg_len -= NLMSG_LENGTH(0); + + /* parse the response */ + genl_hdr = (struct genlmsghdr *)msg_iter; + if (genl_hdr->cmd != NLBL_CIPSOV4_C_LIST) { + ret_val = -ENOMSG; + goto list_return; + } + msg_iter += GENL_HDRLEN; + msg_len -= GENL_HDRLEN; + *maptype = nlbl_getinc_u32(&msg_iter, &msg_len); + switch (*maptype) { + case CIPSO_V4_MAP_STD: + tags->size = nlbl_getinc_u32(&msg_iter, &msg_len); + lvls->size = nlbl_getinc_u32(&msg_iter, &msg_len); + cats->size = nlbl_getinc_u32(&msg_iter, &msg_len); + tags->array = malloc(sizeof(cv4_tag) * tags->size); + lvls->array = malloc(sizeof(cv4_lvl) * lvls->size * 2); + cats->array = malloc(sizeof(cv4_cat) * cats->size * 2); + if (tags->array == NULL || lvls->array == NULL || cats->array == NULL) { + ret_val = -ENOMEM; + goto list_return; + } + for (iter = 0; iter < tags->size; iter++) + tags->array[iter] = nlbl_getinc_u8(&msg_iter, &msg_len); + for (iter = 0; iter < lvls->size; iter++) { + lvls->array[2 * iter] = nlbl_getinc_u32(&msg_iter, &msg_len); + lvls->array[2 * iter + 1] = nlbl_getinc_u8(&msg_iter, &msg_len); + } + for (iter = 0; iter < cats->size; iter++) { + cats->array[2 * iter] = nlbl_getinc_u32(&msg_iter, &msg_len); + cats->array[2 * iter + 1] = nlbl_getinc_u16(&msg_iter, &msg_len); + } + break; + case CIPSO_V4_MAP_PASS: + tags->size = nlbl_getinc_u32(&msg_iter, &msg_len); + tags->array = malloc(sizeof(cv4_tag) * tags->size); + if (tags->array == NULL) { + ret_val = -ENOMEM; + goto list_return; + } + for (iter = 0; iter < tags->size; iter++) + tags->array[iter] = nlbl_getinc_u8(&msg_iter, &msg_len); + break; + default: + ret_val = -ENOMSG; + goto list_return; + } + + ret_val = 0; + + list_return: + if (ret_val < 0) { + tags->size = 0; + if (tags->array) + free(tags->array); + lvls->size = 0; + if (lvls->array) + free(lvls->array); + cats->size = 0; + if (cats->array) + free(cats->array); + } + if (msg) + free(msg); + if (sock == 0) + nlbl_netlink_close(local_sock); + + return ret_val; +} + +/** + * nlbl_cipsov4_list_all - List the CIPSOv4 label mappings + * @sock: the NetLabel socket + * @doi_list: a list of DOI values + * @mtype_list: a list of the mapping types + * + * Description: + * Query the kernel for the configured CIPSOv4 mappings and return two lists; + * @doi_list which contains the DOI values and @mtype_list which contains the + * type of mapping. If @sock is zero then the function will handle opening and + * closing it's own NETLINK socket. Returns zero on success, negative values + * on failure. + * + */ +int nlbl_cipsov4_list_all(nlbl_socket sock, + cv4_doi **doi_list, + cv4_maptype **mtype_list, + size_t *count) +{ + int ret_val = -EPERM; + nlbl_socket local_sock = sock; + nlbl_data *msg = NULL; + nlbl_data *msg_iter; + ssize_t msg_len; + struct genlmsghdr *genl_hdr; + size_t doi_count; + cv4_doi *list_doi = NULL; + cv4_maptype *list_mtype = NULL; + unsigned int iter; + + /* sanity checks */ + if (sock < 0) + return -EINVAL; + + /* open a socket if we need one */ + if (sock == 0) { + ret_val = nlbl_netlink_open(&local_sock); + if (ret_val < 0) + return ret_val; + } + + /* allocate a buffer for the message */ + msg_len = GENL_HDRLEN; + msg = malloc(msg_len); + if (msg == NULL) { + ret_val = -ENOMEM; + goto list_all_return; + } + memset(msg, 0, msg_len); + + /* write the message into the buffer */ + nlbl_put_genlhdr(msg, NLBL_CIPSOV4_C_LISTALL); + + /* send the request */ + ret_val = nlbl_cipsov4_write(local_sock, msg, msg_len); + if (ret_val < 0) + goto list_all_return; + free(msg); + msg = NULL; + msg_len = 0; + + /* read the results */ + ret_val = nlbl_cipsov4_read(local_sock, &msg, &msg_len); + if (ret_val < 0) + goto list_all_return; + msg_iter = msg + NLMSG_LENGTH(0); + msg_len -= NLMSG_LENGTH(0); + + /* parse the response */ + genl_hdr = (struct genlmsghdr *)msg_iter; + if (genl_hdr->cmd != NLBL_CIPSOV4_C_LISTALL) { + ret_val = -ENOMSG; + goto list_all_return; + } + msg_iter += GENL_HDRLEN; + msg_len -= GENL_HDRLEN; + doi_count = nlbl_getinc_u32(&msg_iter, &msg_len); + list_doi = malloc(sizeof(cv4_doi) * doi_count); + list_mtype = malloc(sizeof(cv4_maptype) * doi_count); + if (list_doi == NULL || list_mtype == NULL) { + ret_val = -ENOMEM; + goto list_all_return; + } + for (iter = 0; iter < doi_count; iter++) { + list_doi[iter] = nlbl_getinc_u32(&msg_iter, &msg_len); + list_mtype[iter] = nlbl_getinc_u32(&msg_iter, &msg_len); + } + + *count = doi_count; + *doi_list = list_doi; + *mtype_list = list_mtype; + + ret_val = 0; + + list_all_return: + if (ret_val < 0) { + if (list_doi) + free(list_doi); + if (list_mtype) + free(list_mtype); + } + if (msg) + free(msg); + if (sock == 0) + nlbl_netlink_close(local_sock); + + return ret_val; +} + diff --git a/libnetlabel/mod_cipsov4.h b/libnetlabel/mod_cipsov4.h new file mode 100644 index 0000000..8939b50 --- /dev/null +++ b/libnetlabel/mod_cipsov4.h @@ -0,0 +1,32 @@ +/* + * CIPSO/IPv4 Module Functions + * + * 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 + * + */ + +#ifndef _MOD_CIPSOV4_H_ +#define _MOD_CIPSOV4_H_ + +int nlbl_cipsov4_init(void); + +#endif diff --git a/libnetlabel/mod_mgmt.c b/libnetlabel/mod_mgmt.c new file mode 100644 index 0000000..03405c8 --- /dev/null +++ b/libnetlabel/mod_mgmt.c @@ -0,0 +1,731 @@ +/* + * Management Module Functions + * + * 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 "fields.h" +#include "common.h" + +/* Generic NETLINK family ID */ +static nlbl_type nlbl_mgmt_fid = -1; + +/* + * Init functions + */ + + +/** + * nlbl_mgmt_init - Perform any setup needed + * + * Description: + * Do any setup needed for the management component, including determining the + * NetLabel Mangement Generic NETLINK family ID. Returns zero on success, + * negative values on error. + * + */ +int nlbl_mgmt_init(void) +{ + int ret_val; + nlbl_socket sock; + nlbl_data *msg = NULL; + nlbl_data *msg_iter; + ssize_t msg_len; + struct genlmsghdr *genl_hdr; + struct nlattr *nla_hdr; + nlbl_type nl_type; + + /* open a socket */ + ret_val = nlbl_netlink_open(&sock); + if (ret_val < 0) + return ret_val; + + /* allocate a buffer for the family id request */ + msg_len = GENL_HDRLEN + NLA_HDRLEN + strlen(NETLBL_NLTYPE_MGMT_NAME) + 1; + msg = malloc(msg_len); + if (msg == NULL) { + ret_val = -ENOMEM; + goto init_return; + } + memset(msg, 0, msg_len); + msg_iter = msg; + + /* write the genetlink header into the buffer */ + genl_hdr = (struct genlmsghdr *)msg_iter; + genl_hdr->cmd = CTRL_CMD_GETFAMILY; + genl_hdr->version = 1; + + /* write the attribute into the buffer */ + msg_iter += GENL_HDRLEN; + nla_hdr = (struct nlattr *)msg_iter; + nla_hdr->nla_len = NLA_HDRLEN + strlen(NETLBL_NLTYPE_MGMT_NAME) + 1; + nla_hdr->nla_type = CTRL_ATTR_FAMILY_NAME; + msg_iter += NLA_HDRLEN; + strcpy((char *)msg_iter, NETLBL_NLTYPE_MGMT_NAME); + + /* send the message */ + ret_val = nlbl_netlink_write(sock, GENL_ID_CTRL, msg, msg_len); + if (ret_val < 0) + goto init_return; + free(msg); + msg = NULL; + msg_len = 0; + + /* read the response */ + ret_val = nlbl_netlink_read(sock, &nl_type, &msg, &msg_len); + if (ret_val < 0) + goto init_return; + if (nl_type != GENL_ID_CTRL) { + ret_val = -ENOMSG; + goto init_return; + } + msg_iter = msg + NLMSG_LENGTH(0); + + /* parse the response */ + genl_hdr = (struct genlmsghdr *) msg_iter; + if (genl_hdr->cmd != CTRL_CMD_NEWFAMILY) { + ret_val = -ENOMSG; + goto init_return; + } + msg_iter += GENL_HDRLEN; + do { + nla_hdr = (struct nlattr *)msg_iter; + msg_iter += NLMSG_ALIGN(nla_hdr->nla_len); + } while (msg_iter - msg < msg_len || + nla_hdr->nla_type != CTRL_ATTR_FAMILY_ID); + if (nla_hdr->nla_type != CTRL_ATTR_FAMILY_ID) { + ret_val = -ENOMSG; + goto init_return; + } + nlbl_mgmt_fid = nlbl_get_u16((unsigned char *)nla_hdr); + + ret_val = 0; + + init_return: + if (msg) + free(msg); + nlbl_netlink_close(sock); + return ret_val; +} + +/* + * Low-level communications + */ + + +/** + * nlbl_mgmt_write - Send a NetLabel management message + * @sock: the socket + * @msg: the message + * @msg_len: the message length + * + * Description: + * Write the message in @msg to the NetLabel socket @sock. Returns zero on + * success, negative values on failure. + * + */ +int nlbl_mgmt_write(nlbl_socket sock, nlbl_data *msg, size_t msg_len) +{ + return nlbl_netlink_write(sock, nlbl_mgmt_fid, msg, msg_len); +} + +/** + * nlbl_mgmt_read - Read a NetLbel management message + * @sock: the socket + * @msg: the message + * @msg_len: the message length + * + * Description: + * Try to read a NetLabel management message and return the message in @msg. + * Returns negative values on failure. + * + */ +int nlbl_mgmt_read(nlbl_socket sock, nlbl_data **msg, ssize_t *msg_len) +{ + int ret_val; + nlbl_type nl_type; + + ret_val = nlbl_netlink_read(sock, &nl_type, msg, msg_len); + if (ret_val >= 0 && nl_type != nlbl_mgmt_fid) + return -ENOMSG; + + return ret_val; +} + +/* + * NetLabel operations + */ + + +/** + * nlbl_mgmt_modules - Determine the supported list of NetLabel modules + * @sock: the NetLabel socket + * @module_list: the module list + * @module_count: the number of modules in the list + * + * Description: + * Request a list of supported NetLabel modules from the kernel and return the + * result to the caller. If @sock is zero then the function will handle + * opening and closing it's own NETLINK socket. Returns zero on success, + * negative values on failure. + * + */ +int nlbl_mgmt_modules(nlbl_socket sock, + unsigned int **module_list, + size_t *module_count) +{ + int ret_val = -EPERM; + nlbl_socket local_sock = sock; + nlbl_data *msg = NULL; + nlbl_data *msg_iter; + ssize_t msg_len; + struct genlmsghdr *genl_hdr; + unsigned int *list; + unsigned int mod_count; + int iter; + + /* sanity checks */ + if (sock < 0 || module_list == NULL || module_count == NULL) + return -EINVAL; + + /* open a socket if we need one */ + if (sock == 0) { + ret_val = nlbl_netlink_open(&local_sock); + if (ret_val < 0) + return ret_val; + } + + /* allocate a buffer for the message */ + msg_len = GENL_HDRLEN; + msg = malloc(msg_len); + if (msg == NULL) { + ret_val = -ENOMEM; + goto modules_return; + } + memset(msg, 0, msg_len); + + /* write the message into the buffer */ + nlbl_put_genlhdr(msg, NLBL_MGMT_C_MODULES); + + /* send the request */ + ret_val = nlbl_mgmt_write(local_sock, msg, msg_len); + if (ret_val < 0) + goto modules_return; + free(msg); + msg = NULL; + msg_len = 0; + + /* read the results */ + ret_val = nlbl_mgmt_read(local_sock, &msg, &msg_len); + if (ret_val < 0) + goto modules_return; + msg_iter = msg + NLMSG_LENGTH(0); + msg_len -= NLMSG_LENGTH(0); + + /* parse the response */ + genl_hdr = (struct genlmsghdr *)msg_iter; + if (genl_hdr->cmd != NLBL_MGMT_C_MODULES) { + ret_val = -ENOMSG; + goto modules_return; + } + msg_iter += GENL_HDRLEN; + msg_len -= GENL_HDRLEN; + if (msg_len < NETLBL_LEN_U32) { + ret_val = -ENOMSG; + goto modules_return; + } + mod_count = nlbl_getinc_u32(&msg_iter, &msg_len); + if (mod_count == 0 || msg_len < mod_count * NETLBL_LEN_U32) { + ret_val = -ENOMSG; + goto modules_return; + } + + /* return the list of modules */ + list = malloc(mod_count * NETLBL_LEN_U32); + if (list == NULL) { + ret_val = -ENOMEM; + goto modules_return; + } + for (iter = 0; iter < mod_count; iter++) + list[iter] = nlbl_getinc_u32(&msg_iter, &msg_len); + *module_count = mod_count; + *module_list = list; + + ret_val = 0; + + modules_return: + if (msg) + free(msg); + if (sock == 0) + nlbl_netlink_close(local_sock); + + return ret_val; +} + +/** + * nlbl_mgmt_version - Determine the kernel's NetLabel version + * @sock: the NetLabel socket + * @ver: the version string buffer + * @ver_len: the length of the version string in bytes + * + * Description: + * Request the NetLabel version string from the kernel and return the result + * to the caller. If @sock is zero then the function will handle opening and + * closing it's own NETLINK socket. Returns zero on success, negative values + * on failure. + * + */ +int nlbl_mgmt_version(nlbl_socket sock, unsigned int *version) +{ + int ret_val = -EPERM; + nlbl_socket local_sock = sock; + nlbl_data *msg = NULL; + nlbl_data *msg_iter; + ssize_t msg_len; + struct genlmsghdr *genl_hdr; + + /* sanity checks */ + if (sock < 0 || version == NULL) + return -EINVAL; + + /* open a socket if we need one */ + if (sock == 0) { + ret_val = nlbl_netlink_open(&local_sock); + if (ret_val < 0) + return ret_val; + } + + /* allocate a buffer for the message */ + msg_len = GENL_HDRLEN; + msg = malloc(msg_len); + if (msg == NULL) { + ret_val = -ENOMEM; + goto version_return; + } + memset(msg, 0, msg_len); + + /* write the message into the buffer */ + nlbl_put_genlhdr(msg, NLBL_MGMT_C_VERSION); + + /* send the request */ + ret_val = nlbl_mgmt_write(local_sock, msg, msg_len); + if (ret_val < 0) + goto version_return; + free(msg); + msg = NULL; + msg_len = 0; + + /* read the results */ + ret_val = nlbl_mgmt_read(local_sock, &msg, &msg_len); + if (ret_val < 0) + goto version_return; + msg_iter = msg + NLMSG_LENGTH(0); + msg_len -= NLMSG_LENGTH(0); + + /* parse the response */ + genl_hdr = (struct genlmsghdr *)msg_iter; + if (genl_hdr->cmd != NLBL_MGMT_C_VERSION) { + ret_val = -ENOMSG; + goto version_return; + } + msg_iter += GENL_HDRLEN; + msg_len -= GENL_HDRLEN; + if (msg_len != NETLBL_LEN_U32) { + ret_val = -ENOMSG; + goto version_return; + } + *version = nlbl_get_u32(msg_iter); + + ret_val = 0; + + version_return: + if (msg) + free(msg); + if (sock == 0) + nlbl_netlink_close(local_sock); + + return ret_val; +} + +/** + * nlbl_mgmt_add - Add a domain mapping to the NetLabel system + * @sock: the NetLabel socket + * @domain_list: list of domain mappings + * @domain_count: number of entries in the domain mapping list + * @def_flag: default mapping flag + * + * Description: + * Add the domain mappings in @domain_list to the NetLabel system. If @sock is + * zero then the function will handle opening and closing it's own NETLINK + * socket. Returns zero on success, negative values on failure. + * + */ +int nlbl_mgmt_add(nlbl_socket sock, + mgmt_domain *domain_list, + size_t domain_count, + unsigned int def_flag) +{ + int ret_val = -EPERM; + nlbl_socket local_sock = sock; + nlbl_data *msg = NULL; + nlbl_data *msg_iter; + ssize_t msg_len; + unsigned int iter; + + /* sanity checks */ + if (sock < 0 || domain_list == NULL || domain_count < 1 || + (def_flag && domain_count != 1)) + return -EINVAL; + + /* open a socket if we need one */ + if (sock == 0) { + ret_val = nlbl_netlink_open(&local_sock); + if (ret_val < 0) + return ret_val; + } + + /* allocate a buffer for the message */ + msg_len = GENL_HDRLEN + (def_flag ? 0 : NETLBL_LEN_U32); + for (iter = 0; iter < domain_count; iter++) { + msg_len += NETLBL_LEN_U32; + if (!def_flag) + msg_len += nlbl_len_payload(domain_list[iter].domain_len); + switch (domain_list[iter].proto_type) + { + case NETLBL_NLTYPE_UNLABELED: + break; + case NETLBL_NLTYPE_CIPSOV4: + msg_len += NETLBL_LEN_U32; + break; + default: + ret_val = -EINVAL; + goto add_return; + } + } + msg = malloc(msg_len); + if (msg == NULL) { + ret_val = -ENOMEM; + goto add_return; + } + memset(msg, 0, msg_len); + msg_iter = msg; + + /* write the message into the buffer */ + if (!def_flag) { + nlbl_putinc_genlhdr(&msg_iter, NLBL_MGMT_C_ADD); + nlbl_putinc_u32(&msg_iter, domain_count, NULL); + } else + nlbl_putinc_genlhdr(&msg_iter, NLBL_MGMT_C_ADDDEF); + for (iter = 0; iter < domain_count; iter++) { + if (!def_flag) + nlbl_putinc_str(&msg_iter, domain_list[iter].domain, NULL); + nlbl_putinc_u32(&msg_iter, domain_list[iter].proto_type, NULL); + switch (domain_list[iter].proto_type) { + case NETLBL_NLTYPE_UNLABELED: + break; + case NETLBL_NLTYPE_CIPSOV4: + nlbl_putinc_u32(&msg_iter, domain_list[iter].proto.cipsov4.doi, NULL); + break; + default: + ret_val = -EINVAL; + goto add_return; + } + } + + /* send the request */ + ret_val = nlbl_mgmt_write(local_sock, msg, msg_len); + if (ret_val < 0) + goto add_return; + free(msg); + msg = NULL; + msg_len = 0; + + /* read the results */ + ret_val = nlbl_mgmt_read(local_sock, &msg, &msg_len); + if (ret_val < 0) + goto add_return; + + /* parse the response */ + ret_val = nlbl_common_ack_parse(msg + NLMSG_LENGTH(0), + msg_len - NLMSG_LENGTH(0), + NLBL_MGMT_C_ACK); + + add_return: + if (msg) + free(msg); + if (sock == 0) + nlbl_netlink_close(local_sock); + + return ret_val; +} + +/** + * nlbl_mgmt_del - Remove a domain mapping from the NetLabel system + * @sock: the NetLabel socket + * @domains: list of domain strings + * @domain_len: list of domain string lengths + * @domain_count: the number of domain strings + * @def_flag: default mapping flag + * + * Description: + * Remove the domain mappings in @domains from the NetLabel system. If @sock + * is zero then the function will handle opening and closing it's own NETLINK + * socket. Returns zero on success, negative values on failure. + * + */ +int nlbl_mgmt_del(nlbl_socket sock, + char **domains, + size_t *domain_len, + size_t domain_count, + unsigned int def_flag) +{ + int ret_val = -EPERM; + nlbl_socket local_sock = sock; + nlbl_data *msg = NULL; + nlbl_data *msg_iter; + ssize_t msg_len; + unsigned int iter; + + /* sanity checks */ + if (sock < 0 || (!def_flag && (domains == NULL || domain_len == NULL || + domain_count < 1))) + return -EINVAL; + + /* open a socket if we need one */ + if (sock == 0) { + ret_val = nlbl_netlink_open(&local_sock); + if (ret_val < 0) + return ret_val; + } + + /* allocate a buffer for the message */ + if (!def_flag) { + msg_len = GENL_HDRLEN + NETLBL_LEN_U32; + for (iter = 0; iter < domain_count; iter++) + msg_len += nlbl_len_payload(domain_len[iter]); + } else + msg_len = GENL_HDRLEN; + msg = malloc(msg_len); + if (msg == NULL) { + ret_val = -ENOMEM; + goto del_return; + } + memset(msg, 0, msg_len); + msg_iter = msg; + + /* write the message into the buffer */ + if (!def_flag) { + nlbl_putinc_genlhdr(&msg_iter, NLBL_MGMT_C_REMOVE); + nlbl_putinc_u32(&msg_iter, domain_count, NULL); + for (iter = 0; iter < domain_count; iter++) + nlbl_putinc_str(&msg_iter, domains[iter], NULL); + } else + nlbl_putinc_genlhdr(&msg_iter, NLBL_MGMT_C_REMOVEDEF); + + /* send the request */ + ret_val = nlbl_mgmt_write(local_sock, msg, msg_len); + if (ret_val < 0) + goto del_return; + free(msg); + msg = NULL; + msg_len = 0; + + /* read the results */ + ret_val = nlbl_mgmt_read(local_sock, &msg, &msg_len); + if (ret_val < 0) + goto del_return; + + /* parse the response */ + ret_val = nlbl_common_ack_parse(msg + NLMSG_LENGTH(0), + msg_len - NLMSG_LENGTH(0), + NLBL_MGMT_C_ACK); + + del_return: + if (msg) + free(msg); + if (sock == 0) + nlbl_netlink_close(local_sock); + + return ret_val; +} + +/** + * nlbl_mgmt_list - List the NetLabel domain mappings + * @sock: the NetLabel socket + * @domain_list: list of domain mappings + * @domain_count: number of domains in the list + * @def_flag: default mapping flag + * + * Description: + * List the configured domain mappings in the NetLabel system. If @sock is + * zero then the function will handle opening and closing it's own NETLINK + * socket. Returns zero on success, negative values on failure. + * + */ +int nlbl_mgmt_list(nlbl_socket sock, + mgmt_domain **domain_list, + size_t *domain_count, + unsigned int def_flag) +{ + int ret_val = -EPERM; + nlbl_socket local_sock = sock; + nlbl_data *msg = NULL; + nlbl_data *msg_iter; + ssize_t msg_len; + struct genlmsghdr *genl_hdr; + unsigned int iter; + mgmt_domain *domains = NULL; + + /* sanity checks */ + if (sock < 0 || domain_list == NULL || domain_count == NULL) + return -EINVAL; + + /* open a socket if we need one */ + if (sock == 0) { + ret_val = nlbl_netlink_open(&local_sock); + if (ret_val < 0) + return ret_val; + } + + /* allocate a buffer for the message */ + msg_len = GENL_HDRLEN; + msg = malloc(msg_len); + if (msg == NULL) { + ret_val = -ENOMEM; + goto list_return; + } + memset(msg, 0, msg_len); + + /* write the message into the buffer */ + if (!def_flag) + nlbl_put_genlhdr(msg, NLBL_MGMT_C_LIST); + else + nlbl_put_genlhdr(msg, NLBL_MGMT_C_LISTDEF); + + /* send the request */ + ret_val = nlbl_mgmt_write(local_sock, msg, msg_len); + if (ret_val < 0) + goto list_return; + free(msg); + msg = NULL; + msg_len = 0; + + /* read the results */ + ret_val = nlbl_mgmt_read(local_sock, &msg, &msg_len); + if (ret_val < 0) + goto list_return; + msg_iter = msg + NLMSG_LENGTH(0); + msg_len -= NLMSG_LENGTH(0); + + /* parse the response */ + genl_hdr = (struct genlmsghdr *)msg_iter; + if (!def_flag) { + if (genl_hdr->cmd != NLBL_MGMT_C_LIST) { + ret_val = -ENOMSG; + goto list_return; + } + } else { + if (genl_hdr->cmd != NLBL_MGMT_C_LISTDEF) { + ret_val = -ENOMSG; + goto list_return; + } + } + msg_iter += GENL_HDRLEN; + msg_len -= GENL_HDRLEN; + if (!def_flag) + *domain_count = nlbl_getinc_u32(&msg_iter, &msg_len); + else + *domain_count = 1; + for (iter = 0; iter < *domain_count; iter++) { + domains = realloc(domains, sizeof(mgmt_domain) * (iter + 1)); + if (domains == NULL) { + ret_val = -ENOMEM; + goto list_return; + } + if (!def_flag) { + domains[iter].domain_len = nlbl_get_len(msg_iter); + domains[iter].domain = nlbl_getinc_str(&msg_iter, &msg_len); + if (domains[iter].domain == NULL) { + ret_val = -ENOMEM; + goto list_return; + } + } else { + domains[iter].domain = NULL; + domains[iter].domain_len = 0; + } + domains[iter].proto_type = nlbl_getinc_u32(&msg_iter, &msg_len); + switch (domains[iter].proto_type) { + case NETLBL_NLTYPE_UNLABELED: + break; + case NETLBL_NLTYPE_CIPSOV4: + domains[iter].proto.cipsov4.maptype = nlbl_getinc_u32(&msg_iter, + &msg_len); + domains[iter].proto.cipsov4.doi = nlbl_getinc_u32(&msg_iter, + &msg_len); + break; + default: + if (def_flag) { + free(domains); + *domain_count = 0; + domains = NULL; + ret_val = 0; + } else + ret_val = -EBADMSG; + goto list_return; + } + } + *domain_list = domains; + + ret_val = 0; + + list_return: + if (msg) + free(msg); + if (ret_val < 0) { + if (domains) { + for (iter = 0; iter < *domain_count; iter++) { + if (domains[iter].domain) + free(domains[iter].domain); + } + free(domains); + } + } + if (sock == 0) + nlbl_netlink_close(local_sock); + + return ret_val; +} diff --git a/libnetlabel/mod_mgmt.h b/libnetlabel/mod_mgmt.h new file mode 100644 index 0000000..f67debd --- /dev/null +++ b/libnetlabel/mod_mgmt.h @@ -0,0 +1,32 @@ +/* + * Management Module Functions + * + * 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 + * + */ + +#ifndef _MOD_MGMT_H_ +#define _MOD_MGMT_H_ + +int nlbl_mgmt_init(void); + +#endif diff --git a/libnetlabel/mod_unlabeled.c b/libnetlabel/mod_unlabeled.c new file mode 100644 index 0000000..2059680 --- /dev/null +++ b/libnetlabel/mod_unlabeled.c @@ -0,0 +1,351 @@ +/* + * Unlabeled Module Functions + * + * 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 "fields.h" +#include "common.h" + +/* Generic NETLINK family ID */ +static nlbl_type nlbl_unlabeled_fid = -1; + +/* + * Init functions + */ + + +/** + * nlbl_unlabeled_init - Perform any setup needed + * + * Description: + * Do any setup needed for the unlabeled component, including determining the + * NetLabel Unlabeled Generic NETLINK family ID. Returns zero on success, + * negative values on error. + * + */ +int nlbl_unlabeled_init(void) +{ + int ret_val; + nlbl_socket sock; + nlbl_data *msg = NULL; + nlbl_data *msg_iter; + ssize_t msg_len; + struct genlmsghdr *genl_hdr; + struct nlattr *nla_hdr; + nlbl_type nl_type; + + /* open a socket */ + ret_val = nlbl_netlink_open(&sock); + if (ret_val < 0) + return ret_val; + + /* allocate a buffer for the family id request */ + msg_len = GENL_HDRLEN + NLA_HDRLEN + + strlen(NETLBL_NLTYPE_UNLABELED_NAME) + 1; + msg = malloc(msg_len); + if (msg == NULL) { + ret_val = -ENOMEM; + goto init_return; + } + memset(msg, 0, msg_len); + msg_iter = msg; + + /* write the genetlink header into the buffer */ + genl_hdr = (struct genlmsghdr *)msg_iter; + genl_hdr->cmd = CTRL_CMD_GETFAMILY; + genl_hdr->version = 1; + + /* write the attribute into the buffer */ + msg_iter += GENL_HDRLEN; + nla_hdr = (struct nlattr *)msg_iter; + nla_hdr->nla_len = NLA_HDRLEN + strlen(NETLBL_NLTYPE_UNLABELED_NAME) + 1; + nla_hdr->nla_type = CTRL_ATTR_FAMILY_NAME; + msg_iter += NLA_HDRLEN; + strcpy((char *)msg_iter, NETLBL_NLTYPE_UNLABELED_NAME); + + /* send the message */ + ret_val = nlbl_netlink_write(sock, GENL_ID_CTRL, msg, msg_len); + if (ret_val < 0) + goto init_return; + free(msg); + msg = NULL; + msg_len = 0; + + /* read the response */ + ret_val = nlbl_netlink_read(sock, &nl_type, &msg, &msg_len); + if (ret_val < 0) + goto init_return; + if (nl_type != GENL_ID_CTRL) { + ret_val = -ENOMSG; + goto init_return; + } + msg_iter = msg + NLMSG_LENGTH(0); + + /* parse the response */ + genl_hdr = (struct genlmsghdr *) msg_iter; + if (genl_hdr->cmd != CTRL_CMD_NEWFAMILY) { + ret_val = -ENOMSG; + goto init_return; + } + msg_iter += GENL_HDRLEN; + do { + nla_hdr = (struct nlattr *)msg_iter; + msg_iter += NLMSG_ALIGN(nla_hdr->nla_len); + } while (msg_iter - msg < msg_len || + nla_hdr->nla_type != CTRL_ATTR_FAMILY_ID); + if (nla_hdr->nla_type != CTRL_ATTR_FAMILY_ID) { + ret_val = -ENOMSG; + goto init_return; + } + nlbl_unlabeled_fid = nlbl_get_u16((unsigned char *)nla_hdr); + + ret_val = 0; + + init_return: + if (msg) + free(msg); + nlbl_netlink_close(sock); + return ret_val; +} + +/* + * Low-level communications + */ + + +/** + * nlbl_unlabeled_write - Send a NetLabel unlabeled message + * @sock: the socket + * @msg: the message + * @msg_len: the message length + * + * Description: + * Write the message in @msg to the NetLabel socket @sock. Returns zero on + * success, negative values on failure. + * + */ +int nlbl_unlabeled_write(nlbl_socket sock, nlbl_data *msg, size_t msg_len) +{ + return nlbl_netlink_write(sock, nlbl_unlabeled_fid, msg, msg_len); +} + +/** + * nlbl_unlabeled_read - Read a NetLbel unlabled message + * @sock: the socket + * @msg: the message + * @msg_len: the message length + * + * Description: + * Try to read a NetLabel unlabeled message and return the message in @msg. + * Returns negative values on failure. + * + */ +int nlbl_unlabeled_read(nlbl_socket sock, nlbl_data **msg, ssize_t *msg_len) +{ + int ret_val; + nlbl_type nl_type; + + ret_val = nlbl_netlink_read(sock, &nl_type, msg, msg_len); + if (ret_val >= 0 && nl_type != nlbl_unlabeled_fid) + return -ENOMSG; + + return ret_val; +} + +/* + * NetLabel operations + */ + + +/** + * nlbl_unlabeled_accept - Set the unlabeled accept flag + * @sock: the NetLabel socket + * @allow_flag: the desired accept flag setting + * + * Description: + * Set the unlabeled accept flag in the NetLabel system; if @allow_flag is + * true then set the accept flag, otherwise clear the flag. If @sock is zero + * then the function will handle opening and closing it's own NETLINK socket. + * Returns zero on success, negative values on failure. + * + */ +int nlbl_unlabeled_accept(nlbl_socket sock, unsigned int allow_flag) +{ + int ret_val = -EPERM; + nlbl_socket local_sock = sock; + nlbl_data *msg = NULL; + nlbl_data *msg_iter; + ssize_t msg_len; + + /* sanity checks */ + if (sock < 0) + return -EINVAL; + + /* open a socket if we need one */ + if (sock == 0) { + ret_val = nlbl_netlink_open(&local_sock); + if (ret_val < 0) + return ret_val; + } + + /* allocate a buffer for the message */ + msg_len = GENL_HDRLEN + NETLBL_LEN_U32; + msg = malloc(msg_len); + if (msg == NULL) { + ret_val = -ENOMEM; + goto accept_return; + } + memset(msg, 0, msg_len); + msg_iter = msg; + + /* write the message into the buffer */ + nlbl_putinc_genlhdr(&msg_iter, NLBL_UNLABEL_C_ACCEPT); + if (allow_flag) + nlbl_putinc_u32(&msg_iter, 1, NULL); + else + nlbl_putinc_u32(&msg_iter, 0, NULL); + + /* send the request */ + ret_val = nlbl_unlabeled_write(local_sock, msg, msg_len); + if (ret_val < 0) + goto accept_return; + free(msg); + msg = NULL; + msg_len = 0; + + /* read the results */ + ret_val = nlbl_unlabeled_read(local_sock, &msg, &msg_len); + if (ret_val < 0) + goto accept_return; + + /* parse the response */ + ret_val = nlbl_common_ack_parse(msg + NLMSG_LENGTH(0), + msg_len - NLMSG_LENGTH(0), + NLBL_UNLABEL_C_ACK); + + accept_return: + if (msg) + free(msg); + if (sock == 0) + nlbl_netlink_close(local_sock); + + return ret_val; +} + +/** + * nlbl_unlabeled_list - Query the unlabeled accept flag + * @sock: the NetLabel socket + * @allow_flag: the current accept flag setting + * + * Description: + * Query the unlabeled accept flag in the NetLabel system. If @sock is zero + * then the function will handle opening and closing it's own NETLINK socket. + * Returns zero on success, negative values on failure. + * + */ +int nlbl_unlabeled_list(nlbl_socket sock, unsigned int *allow_flag) +{ + int ret_val = -EPERM; + nlbl_socket local_sock = sock; + nlbl_data *msg = NULL; + nlbl_data *msg_iter; + ssize_t msg_len; + struct genlmsghdr *genl_hdr; + + /* sanity checks */ + if (sock < 0 || allow_flag == NULL) + return -EINVAL; + + /* open a socket if we need one */ + if (sock == 0) { + ret_val = nlbl_netlink_open(&local_sock); + if (ret_val < 0) + return ret_val; + } + + /* allocate a buffer for the message */ + msg_len = GENL_HDRLEN; + msg = malloc(msg_len); + if (msg == NULL) { + ret_val = -ENOMEM; + goto list_return; + } + memset(msg, 0, msg_len); + + /* write the message into the buffer */ + nlbl_put_genlhdr(msg, NLBL_UNLABEL_C_LIST); + + /* send the request */ + ret_val = nlbl_unlabeled_write(local_sock, msg, msg_len); + if (ret_val < 0) + goto list_return; + free(msg); + msg = NULL; + msg_len = 0; + + /* read the results */ + ret_val = nlbl_unlabeled_read(local_sock, &msg, &msg_len); + if (ret_val < 0) + goto list_return; + msg_iter = msg + NLMSG_LENGTH(0); + msg_len -= NLMSG_LENGTH(0); + + /* parse the response */ + genl_hdr = (struct genlmsghdr *)msg_iter; + if (genl_hdr->cmd != NLBL_UNLABEL_C_LIST) { + ret_val = -ENOMSG; + goto list_return; + } + msg_iter += GENL_HDRLEN; + msg_len -= GENL_HDRLEN; + if (msg_len != NETLBL_LEN_U32) { + ret_val = -ENOMSG; + goto list_return; + } + *allow_flag = nlbl_get_u32(msg_iter); + + ret_val = 0; + + list_return: + if (msg) + free(msg); + if (sock == 0) + nlbl_netlink_close(local_sock); + + return ret_val; +} diff --git a/libnetlabel/mod_unlabeled.h b/libnetlabel/mod_unlabeled.h new file mode 100644 index 0000000..caa7c5c --- /dev/null +++ b/libnetlabel/mod_unlabeled.h @@ -0,0 +1,32 @@ +/* + * Unlabeled Module Functions + * + * 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 + * + */ + +#ifndef _MOD_UNLABELED_H_ +#define _MOD_UNLABELED_H_ + +int nlbl_unlabeled_init(void); + +#endif diff --git a/libnetlabel/netlabel_init.c b/libnetlabel/netlabel_init.c new file mode 100644 index 0000000..29232c6 --- /dev/null +++ b/libnetlabel/netlabel_init.c @@ -0,0 +1,87 @@ +/* + * NetLabel Library init/exit Functions + * + * 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 + +#include + +#include "mod_mgmt.h" +#include "mod_cipsov4.h" +#include "mod_unlabeled.h" + +/** + * nlbl_netlink_init - Handle any NETLINK setup needed + * + * Description: + * Initialize the NETLINK communication link, but do not open any general use + * sockets. Returns zero on success, negative values on failure. + * + */ +int nlbl_netlink_init(void) +{ + int ret_val; + + ret_val = nlbl_mgmt_init(); + if (ret_val < 0) + goto init_failure; + + ret_val = nlbl_cipsov4_init(); + if (ret_val < 0) + goto init_failure; + + ret_val = nlbl_unlabeled_init(); + if (ret_val < 0) + goto init_failure; + + return 0; + + init_failure: + return ret_val; +} + +/** + * nlbl_netlink_exit - Handle any NETLINK cleanup + * + * Description: + * Perform any cleanup duties for the NETLINK communication link. + * + */ +void nlbl_netlink_exit(void) +{ + return; +} diff --git a/libnetlabel/netlink_comm.c b/libnetlabel/netlink_comm.c new file mode 100644 index 0000000..c3ee6a6 --- /dev/null +++ b/libnetlabel/netlink_comm.c @@ -0,0 +1,327 @@ +/* + * NETLINK Communication Functions + * + * 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 + +#include + +/* default buffer size */ +#define NLCOMM_BUF_SIZE 8192 + +/* NETLINK sequence number */ +static unsigned int nlcomm_seqnum = 0; + +/* NETLINK read timeout (in seconds) */ +static unsigned int nlcomm_read_timeout = 10; + +/** + * nlbl_netlink_timeout - Set the NETLINK timeout + * @seconds: the timeout in seconds + * + * Description: + * Set the timeout value used by the NETLINK communications layer. + * + */ +void nlbl_netlink_timeout(unsigned int seconds) +{ + nlcomm_read_timeout = seconds; +} + +/** + * nlbl_netlink_msgspace - Determine the correct size for a NETLINK payload + * @len: the payload size + * + * Description: + * Calculate the correct size for a NETLINK payload buffer. + * + */ +size_t nlbl_netlink_msgspace(size_t len) +{ + return NLMSG_ALIGN(len); +} + +/** + * nlbl_netlink_open - Create and bind a NETLINK socket + * @sock: the socket + * + * Description: + * Create a new NETLINK socket and bind it to the running process. Returns + * zero on success, negative values on failure. + * + */ +int nlbl_netlink_open(nlbl_socket *sock) +{ + nlbl_socket new_sock; + struct sockaddr_nl nlbl_addr; + + /* sanity checks */ + if (sock == NULL) + return -EINVAL; + + /* open a NetLabel socket */ + new_sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_GENERIC); + if (new_sock == -1) + return -errno; + + /* bind the NetLabel socket */ + memset(&nlbl_addr, 0, sizeof(struct sockaddr_nl)); + nlbl_addr.nl_family = AF_NETLINK; + nlbl_addr.nl_pid = getpid(); + if (bind(new_sock, (struct sockaddr *)&nlbl_addr, sizeof(nlbl_addr)) != 0) { + close(new_sock); + return -errno; + } + + *sock = new_sock; + return 0; +} + +/** + * nlbl_netlink_close - Closes and destroys a NETLINK socket + * @sock: the socket + * + * Description: + * Closes the given NETLINK socket. Returns zero on success, negative values + * on failure. + * + */ +int nlbl_netlink_close(nlbl_socket sock) +{ + /* sanity checks */ + if (sock < 0) + return -EINVAL; + + /* close the socket */ + if (close(sock) != 0) + return -errno; + + return 0; +} + +/** + * nlbl_netlink_read - Read a message from a NETLINK socket + * @sock: the socket + * @msg: the message buffer + * @msg_len: length of the buffer or message + * + * Description: + * Reads a message from the NETLINK socket. If the caller allocates it's own + * buffer it should set @msg to point to that buffer and @msg_len should be set + * to the size of the buffer. If the caller wants the function to allocate the + * buffer (using default values) it should set @msg_len equal to zero. The + * received message size is returned in @msg_len regardless of who allocates + * the buffer. Returns zero on success, negative values on failure. + * + */ +int nlbl_netlink_read(nlbl_socket sock, + nlbl_type *type, + nlbl_data **msg, + ssize_t *msg_len) +{ + int ret_val; + struct sockaddr_nl nlbl_addr; + struct msghdr msg_hdr; + struct iovec msg_iovec; + nlbl_data *buf = NULL; + size_t buf_len; + ssize_t rcv_len; + fd_set read_fds; + struct timeval timeout; + + /* sanity checks */ + if (sock < 0 || msg == NULL || msg_len == NULL) + return -EINVAL; + + /* get a buffer */ + if (*msg_len == 0) { + /* we need to allocate a buffer */ + buf = malloc(NLCOMM_BUF_SIZE); + if (buf == NULL) + return -ENOMEM; + buf_len = NLCOMM_BUF_SIZE; + } else { + /* caller already allocated a buffer for us */ + buf = *msg; + buf_len = *msg_len; + } + memset(buf, 0, buf_len); + + /* setup the message buffer */ + msg_iovec.iov_base = (void *)buf; + msg_iovec.iov_len = buf_len; + + /* setup the message header */ + msg_hdr.msg_name = (void *)&nlbl_addr; + msg_hdr.msg_namelen = sizeof(struct sockaddr_nl); + msg_hdr.msg_iov = &msg_iovec; + msg_hdr.msg_iovlen = 1; + + /* do a select() until the socket has data or we hit our timeout */ + timeout.tv_sec = nlcomm_read_timeout; + timeout.tv_usec = 0; + FD_ZERO(&read_fds); + FD_SET(sock, &read_fds); + ret_val = select(sock + 1, &read_fds, NULL, NULL, &timeout); + if (ret_val <= 0) { + if (buf != *msg) + free(buf); + if (ret_val == 0) + return -EAGAIN; + return -errno; + } + + /* do the read */ + rcv_len = recvmsg(sock, &msg_hdr, 0); + if (rcv_len < 0 || (msg_hdr.msg_flags & MSG_TRUNC)) { + if (buf != *msg) + free(buf); + return -errno; + } + +#if 0 + /* dump the raw message */ + { + unsigned int iter; + + printf("DEBUG: dumping raw incoming NetLabel message, %u bytes\n", + rcv_len); + for (iter = 0; iter < rcv_len; iter++) { + if (iter % 16 == 0) + printf(" %.8u:", iter); + if (iter % 4 == 0) + printf(" "); + printf("%.2x", buf[iter]); + if ((iter + 1) % 16 == 0) + printf("\n"); + } + printf("\n"); + } +#endif + + /* set the return values */ + *type = ((struct nlmsghdr *)buf)->nlmsg_type; + if (buf != *msg) + *msg = buf; + *msg_len = rcv_len; + + return 0; +} + +/** + * nlbl_netlink_write - Write a message to a NETLINK socket + * @sock: the socket + * @type: the message type + * @msg: the message + * @msg_len: the message length + * + * Description: + * Write the message in @msg to the NETLINK socket @sock. Returns zero on + * success, negative values on failure. + * + */ +int nlbl_netlink_write(nlbl_socket sock, + nlbl_type type, + nlbl_data *msg, + size_t msg_len) +{ + struct sockaddr_nl nlbl_addr; + struct msghdr msg_hdr; + struct nlmsghdr *msg_nlhdr; + struct iovec msg_iovec[2]; + ssize_t snd_len; + + /* sanity checks */ + if (sock < 0 || msg == NULL || msg_len <= 0) + return -EINVAL; + +#if 0 + /* dump the raw message */ + { + unsigned int iter; + + printf("DEBUG: dumping raw outgoing NetLabel message, %u bytes\n", + msg_len); + for (iter = 0; iter < msg_len; iter++) { + if (iter % 16 == 0) + printf(" %.8u:", iter); + if (iter % 4 == 0) + printf(" "); + printf("%.2x", msg[iter]); + if ((iter + 1) % 16 == 0) + printf("\n"); + } + printf("\n"); + } +#endif + + /* allocate the NETLINK message header + padding */ + msg_nlhdr = malloc(NLMSG_LENGTH(0)); + if (msg_nlhdr == NULL) + return -ENOMEM; + + /* setup the NETLINK message header */ + msg_nlhdr->nlmsg_len = NLMSG_LENGTH(msg_len); + msg_nlhdr->nlmsg_pid = getpid(); + msg_nlhdr->nlmsg_flags = NLM_F_REQUEST; + msg_nlhdr->nlmsg_seq = nlcomm_seqnum++; + msg_nlhdr->nlmsg_type = type; + + /* setup the message buffer */ + msg_iovec[0].iov_base = (void *)msg_nlhdr; + msg_iovec[0].iov_len = NLMSG_LENGTH(0); + msg_iovec[1].iov_base = (void *)msg; + msg_iovec[1].iov_len = msg_len; + + /* setup the message header */ + memset(&nlbl_addr, 0, sizeof(struct sockaddr_nl)); + nlbl_addr.nl_family = AF_NETLINK; + memset(&msg_hdr, 0, sizeof(struct msghdr)); + msg_hdr.msg_name = (void *)&nlbl_addr; + msg_hdr.msg_namelen = sizeof(struct sockaddr_nl); + msg_hdr.msg_iov = msg_iovec; + msg_hdr.msg_iovlen = 2; + + /* do the write */ + snd_len = sendmsg(sock, &msg_hdr, 0); + + free(msg_nlhdr); + if (snd_len < NLMSG_LENGTH(msg_len)) + return -errno; + return 0; +} + diff --git a/macros.mk b/macros.mk new file mode 100644 index 0000000..1df54a6 --- /dev/null +++ b/macros.mk @@ -0,0 +1,71 @@ +# +# NetLabel Makefile Configuration & Macros +# +# NetLabel Tools are a collection of user space programs and libraries for +# working with the Linux NetLabel subsystem. The NetLabel subsystem 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 +# + +# +# simple /bin/sh script to find the top of the tree +# + +TOPDIR = ` \ + ftd() { \ + cd $$1; \ + if [ -r "macros.mk" ]; then \ + pwd; \ + else \ + ftd "../"; \ + fi \ + }; \ + ftd .` + +# +# build configuration +# + +INCFLAGS = -I$(TOPDIR)/include +LIBFLAGS = + +CFLAGS = -O0 -g -Wall +LDFLAGS = -g + +# +# build macros +# + +ARCHIVE = @echo " AR $@ (add/update: $?)"; $(AR) -cru $@ $?; +COMPILE = @echo " CC $@"; $(CC) $(CFLAGS) $(INCFLAGS) -o $*.o -c $<; +LINK = @echo " LD $@"; $(CC) $(LDFLAGS) -o $@ $^ $(LIBFLAGS); + +# +# default build targets +# + +.c.o: + $(COMPILE) + + + diff --git a/netlabel_tools.spec b/netlabel_tools.spec new file mode 100644 index 0000000..091057f --- /dev/null +++ b/netlabel_tools.spec @@ -0,0 +1,55 @@ + +Summary: Tools to manage the Linux NetLabel subsystem +Name: netlabel_tools +Version: 0.16 +Release: 1 +License: GPL +Group: System Environment/Daemons +Source0: %{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-root + +%description +NetLabel is a kernel subsystem which implements explicit packet labeling +protocols such as CIPSO and RIPSO for Linux. Packet labeling is used in +secure networks to mark packets with the security attributes of the data they +contain. This package provides the necessary user space tools to query and +configure the kernel subsystem. + +%prep +%setup -n %{name}-%{version} + +%build +make + +%install +rm -rf $RPM_BUILD_ROOT +make INSTALL_PREFIX=${RPM_BUILD_ROOT} \ + INSTALL_MAN_DIR=${RPM_BUILD_ROOT}/usr/share/man \ + OWNER=`id -nu` GROUP=`id -ng` install + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +%doc docs/*.txt +%attr(0755,root,root) /sbin/* +%attr(0644,root,root) %{_mandir}/man8/* + +%changelog +* Thu Aug 3 2006 Paul Moore 0.16-1 +- Bumped version number. + +* Thu Jul 6 2006 Paul Moore 0.15-1 +- Bumped version number. + +* Mon Jun 26 2006 Paul Moore 0.14-1 +- Bumped version number. +- Changes related to including the version number in the path name. +- Changed the netlabelctl perms from 0750 to 0755. +- Removed the patch. (included in the base with edits) +- Updated the description. + +* Fri Jun 23 2006 Steve Grubb 0.13-1 +- Initial build. + diff --git a/netlabelctl/Makefile b/netlabelctl/Makefile new file mode 100644 index 0000000..899ae48 --- /dev/null +++ b/netlabelctl/Makefile @@ -0,0 +1,58 @@ +# +# NetLabel Control Makefile +# +# NetLabel Tools are a collection of user space programs and libraries for +# working with the Linux NetLabel subsystem. The NetLabel subsystem 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 +# + +# +# macros +# + +include ../macros.mk + +# +# configuration +# + +OBJS = main.o mgmt.o map.o unlabeled.o cipsov4.o + +LIBFLAGS = $(TOPDIR)/libnetlabel/libnetlabel.a + +# +# targets +# + +.PHONY: clean + +all: netlabelctl + +netlabelctl: $(OBJS) + $(LINK) + +clean: + $(RM) -f $(OBJS) + + diff --git a/netlabelctl/cipsov4.c b/netlabelctl/cipsov4.c new file mode 100644 index 0000000..c3c9d4e --- /dev/null +++ b/netlabelctl/cipsov4.c @@ -0,0 +1,443 @@ +/* + * CIPSO/IPv4 Functions + * + * 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 "netlabelctl.h" + +/** + * cipsov4_add - Add a CIPSOv4 label mapping + * @argc: the number of arguments + * @argv: the argument list + * + * Description: + * Add a CIPSOv4 label mapping to the NetLabel system. Returns zero on + * success, negative values on failure. + * + */ +int cipsov4_add(int argc, char *argv[]) +{ + int ret_val; + unsigned int arg_iter; + unsigned int cipso_type = 0; + cv4_doi doi = 0; + cv4_tag_array tags = { NULL, 0 }; + cv4_lvl_array lvls = { NULL, 0 }; + cv4_cat_array cats = { NULL, 0 }; + char *token_ptr; + + /* sanity checks */ + if (argc <= 0 || argv == NULL || argv[0] == NULL) + return -EINVAL; + + /* parse the arguments */ + arg_iter = 0; + while (arg_iter < argc && argv[arg_iter] != NULL) { + if (strcmp(argv[arg_iter], "std") == 0) { + cipso_type = 1; + } else if (strcmp(argv[arg_iter], "pass") == 0) { + cipso_type = 2; + } else if (strncmp(argv[arg_iter], "doi:", 4) == 0) { + /* doi */ + doi = (cv4_doi)atoi(argv[arg_iter] + 4); + } else if (strncmp(argv[arg_iter], "tags:", 5) == 0) { + /* tags */ + token_ptr = strtok(argv[arg_iter] + 5, ","); + while (token_ptr != NULL) { + tags.array = realloc(tags.array, sizeof(cv4_tag) * (tags.size + 1)); + if (tags.array == NULL) { + ret_val = -ENOMEM; + goto add_return; + } + tags.array[tags.size++] = (cv4_tag)atoi(token_ptr); + token_ptr = strtok(NULL, ","); + } + } else if (strncmp(argv[arg_iter], "levels:", 7) == 0) { + /* levels */ + token_ptr = strtok(argv[arg_iter] + 7, "="); + while (token_ptr != NULL) { + lvls.array = realloc(lvls.array, + sizeof(cv4_lvl) * 2 * (lvls.size + 1)); + if (lvls.array == NULL) { + ret_val = -ENOMEM; + goto add_return; + } + lvls.array[lvls.size * 2] = (cv4_lvl)atoi(token_ptr); + token_ptr = strtok(NULL, ","); + lvls.array[lvls.size * 2 + 1] = (cv4_lvl)atoi(token_ptr); + token_ptr = strtok(NULL, "="); + lvls.size++; + } + } else if (strncmp(argv[arg_iter], "categories:", 11) == 0) { + /* categories */ + token_ptr = strtok(argv[arg_iter] + 11, "="); + while (token_ptr != NULL) { + cats.array = realloc(cats.array, + sizeof(cv4_cat) * 2 * (cats.size + 1)); + if (cats.array == NULL) { + ret_val = -ENOMEM; + goto add_return; + } + cats.array[cats.size * 2] = (cv4_cat)atoi(token_ptr); + token_ptr = strtok(NULL, ","); + cats.array[cats.size * 2 + 1] = (cv4_cat)atoi(token_ptr); + token_ptr = strtok(NULL, "="); + cats.size++; + } + } else + return -EINVAL; + arg_iter++; + } + + /* push the mapping into the kernel */ + switch (cipso_type) { + case 1: + /* standard mapping */ + ret_val = nlbl_cipsov4_add_std(0, doi, &tags, &lvls, &cats); + break; + case 2: + /* pass through mapping */ + ret_val = nlbl_cipsov4_add_pass(0, doi, &tags); + break; + default: + ret_val = -EINVAL; + } + if (opt_pretty) { + if (ret_val < 0) + printf("Failed adding the CIPSOv4 mapping\n"); + else + printf("Added the CIPSOv4 mapping\n"); + } + + /* cleanup and return */ + add_return: + if (tags.array) + free(tags.array); + if (lvls.array) + free(lvls.array); + if (cats.array) + free(cats.array); + + return ret_val; +} + +/** + * cipsov4_del - Remove a CIPSOv4 label mapping + * @argc: the number of arguments + * @argv: the argument list + * + * Description: + * Remove a CIPSOv4 label mapping from the NetLabel system. Returns zero on + * success, negative values on failure. + * + */ +int cipsov4_del(int argc, char *argv[]) +{ + int ret_val; + unsigned int arg_iter; + cv4_doi doi = 0; + + /* sanity checks */ + if (argc <= 0 || argv == NULL || argv[0] == NULL) + return -EINVAL; + + /* parse the arguments */ + arg_iter = 0; + while (arg_iter < argc && argv[arg_iter] != NULL) { + if (strncmp(argv[arg_iter], "doi:", 4) == 0) { + /* doi */ + doi = (cv4_doi)atoi(argv[arg_iter] + 4); + } else + return -EINVAL; + arg_iter++; + } + + /* delete the mapping */ + ret_val = nlbl_cipsov4_del(0, doi); + if (opt_pretty) { + if (ret_val < 0) + printf("Failed to remove the CIPSOv4 mapping\n"); + else + printf("Removed the CIPSOv4 mapping\n"); + } + + return 0; +} + +/** + * cipsov4_list - List the CIPSOv4 label mappings + * @argc: the number of arguments + * @argv: the argument list + * + * Description: + * List the configured CIPSOv4 label mappings. Returns zero on success, + * negative values on failure. + * + */ +int cipsov4_list(int argc, char *argv[]) +{ + int ret_val; + unsigned int iter; + unsigned int doi_set = 0; + cv4_doi doi = 0; + cv4_doi *doi_list = NULL; + cv4_maptype *mtype_list = NULL; + cv4_maptype maptype; + size_t count; + cv4_tag_array tags = { NULL, 0 }; + cv4_lvl_array lvls = { NULL, 0 }; + cv4_cat_array cats = { NULL, 0 }; + + /* parse the arguments */ + iter = 0; + while (iter < argc && argv[iter] != NULL) { + if (strncmp(argv[iter], "doi:", 4) == 0) { + /* doi */ + doi = (cv4_doi)atoi(argv[iter] + 4); + doi_set = 1; + } else + return -EINVAL; + iter++; + } + + /* fetch the information from the kernel and display the results */ + if (doi_set == 0) { + /* list all the mappings */ + ret_val = nlbl_cipsov4_list_all(0, &doi_list, &mtype_list, &count); + if (ret_val < 0) + goto list_return; + + if (opt_pretty) { + printf("Configured CIPSOv4 mappings (%u)\n", count); + for (iter = 0; iter < count; iter++) { + /* doi value */ + printf(" DOI value : %u\n", doi_list[iter]); + /* map type */ + printf(" mapping type : "); + switch (mtype_list[iter]) { + case CIPSO_V4_MAP_STD: + printf("STANDARD\n"); + break; + case CIPSO_V4_MAP_PASS: + printf("PASS THROUGH\n"); + break; + default: + printf("UNKNOWN(%u)\n", mtype_list[iter]); + break; + } + } + } else { + for (iter = 0; iter < count; iter++) { + /* doi value */ + printf("%u,", doi_list[iter]); + /* map type */ + switch (mtype_list[iter]) { + case CIPSO_V4_MAP_STD: + printf("STANDARD"); + break; + case CIPSO_V4_MAP_PASS: + printf("PASS_THROUGH\n"); + break; + default: + printf("UNKNOWN(%u)", mtype_list[iter]); + break; + } + if (iter + 1 < count) + printf(" "); + } + printf("\n"); + } + } else { + /* list a specific mapping */ + ret_val = nlbl_cipsov4_list(0, doi, &maptype, &tags, &lvls, &cats); + if (ret_val < 0) + goto list_return; + + if (opt_pretty) { + printf("Configured CIPSOv4 mapping (DOI = %u)\n", doi); + switch (maptype) { + case CIPSO_V4_MAP_STD: + /* tags */ + printf(" tags (%u): \n", tags.size); + for (iter = 0; iter < tags.size; iter++) { + switch (tags.array[iter]) { + case 1: + printf(" RESTRICTED BITMAP\n"); + break; + case 2: + printf(" ENUMERATED\n"); + break; + case 5: + printf(" RANGED\n"); + break; + case 6: + printf(" PERMISSIVE BITMAP\n"); + break; + case 7: + printf(" FREEFORM\n"); + break; + default: + printf(" UNKNOWN(%u)\n", tags.array[iter]); + break; + } + } + /* levels */ + printf(" levels (%u): \n", lvls.size); + for (iter = 0; iter < lvls.size; iter++) + printf(" %u = %u\n", + lvls.array[iter * 2], + lvls.array[iter * 2 + 1]); + /* categories */ + printf(" categories (%u): \n", cats.size); + for (iter = 0; iter < cats.size; iter++) + printf(" %u = %u\n", + cats.array[iter * 2], + cats.array[iter * 2 + 1]); + break; + case CIPSO_V4_MAP_PASS: + /* tags */ + printf(" tags (%u): \n", tags.size); + for (iter = 0; iter < tags.size; iter++) { + switch (tags.array[iter]) { + case 1: + printf(" RESTRICTED BITMAP\n"); + break; + case 2: + printf(" ENUMERATED\n"); + break; + case 5: + printf(" RANGED\n"); + break; + case 6: + printf(" PERMISSIVE BITMAP\n"); + break; + case 7: + printf(" FREEFORM\n"); + break; + default: + printf(" UNKNOWN(%u)\n", tags.array[iter]); + break; + } + } + break; + default: + printf(" unknown mapping type\n"); + } + } else { + switch (maptype) { + case CIPSO_V4_MAP_STD: + /* tags */ + printf("tags:"); + for (iter = 0; iter < tags.size; iter++) { + printf("%u", tags.array[iter]); + if (iter + 1 < tags.size) + printf(","); + } + /* levels */ + printf(" levels:"); + for (iter = 0; iter < lvls.size; iter++) { + printf("%u=%u", lvls.array[iter * 2], lvls.array[iter * 2 + 1]); + if (iter + 1 < lvls.size) + printf(","); + } + /* categories */ + printf(" categories:"); + for (iter = 0; iter < cats.size; iter++) { + printf("%u=%u", cats.array[iter * 2], cats.array[iter * 2 + 1]); + if (iter + 1 < cats.size) + printf(","); + } + break; + case CIPSO_V4_MAP_PASS: + /* tags */ + printf("tags:"); + for (iter = 0; iter < tags.size; iter++) { + printf("%u", tags.array[iter]); + if (iter + 1 < tags.size) + printf(","); + } + break; + default: + printf("unknown mapping type\n"); + } + printf("\n"); + } + } + + ret_val = 0; + + list_return: + if (doi_list) + free(doi_list); + if (mtype_list) + free(mtype_list); + + return ret_val; +} + +/** + * cipsov4_main - Entry point for the NetLabel CIPSO/IPv4 functions + * @argc: the number of arguments + * @argv: the argument list + * + * Description: + * Parses the argument list and performs the requested operation. Returns zero + * on success, negative values on failure. + * + */ +int cipsov4_main(int argc, char *argv[]) +{ + int ret_val; + + /* sanity checks */ + if (argc <= 0 || argv == NULL || argv[0] == NULL) + return -EINVAL; + + /* handle the request */ + if (strcmp(argv[0], "add") == 0) { + /* add */ + ret_val = cipsov4_add(argc - 1, argv + 1); + } else if (strcmp(argv[0], "del") == 0) { + /* delete */ + ret_val = cipsov4_del(argc - 1, argv + 1); + } else if (strcmp(argv[0], "list") == 0) { + /* list */ + ret_val = cipsov4_list(argc - 1, argv + 1); + } else { + /* unknown request */ + fprintf(stderr, "error[cipsov4]: unknown command\n"); + ret_val = -EINVAL; + } + + return ret_val; +} diff --git a/netlabelctl/main.c b/netlabelctl/main.c new file mode 100644 index 0000000..7a7c536 --- /dev/null +++ b/netlabelctl/main.c @@ -0,0 +1,213 @@ +/* + * NetLabel Control Utility, netlabelctl + * + * 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 "netlabelctl.h" + +/* return values */ +#define RET_OK 0 +#define RET_ERR 1 +#define RET_USAGE 2 + +/* option variables */ +unsigned int opt_verbose = 0; +unsigned int opt_timeout = 10; +unsigned int opt_pretty = 0; + + +/** + * usage_print - Display usage information + * @fp: the output file pointer + * + * Description: + * Display brief usage information. + * + */ +static void usage_print(FILE *fp) +{ + fprintf(fp, + "usage: netlabelctl [] []\n"); +} + +/** + * version_print - Display version information + * @fp: the output file pointer + * + * Description: + * Display the version string. + * + */ +static void version_print(FILE *fp) +{ + fprintf(fp, + "NetLabel Control Utility, version %s (%s)\n", + NETLBL_VER_STRING, + NETLBL_VER_DATE); +} + +/** + * help_print - Display help information + * @fp: the output file pointer + * + * Description: + * Display help and usage information. + * + */ +static void help_print(FILE *fp) +{ + version_print(fp); + fprintf(fp, + " Usage: netlabelctl [] []\n" + "\n" + " Flags:\n" + " -h : help/usage message\n" + " -p : make the output pretty\n" + " -t : timeout\n" + " -v : verbose mode\n" + "\n" + " Modules and Commands:\n" + " mgmt : NetLabel management\n" + " version\n" + " protocols\n" + " map : Domain/Protocol mapping\n" + " add default|domain: protocol:[,]\n" + " del default|domain:\n" + " list\n" + " unlbl : Unlabeled packet handling\n" + " accept on|off\n" + " list\n" + " cipsov4 : CIPSO/IPv4 packet handling\n" + " add std doi: tags:,\n" + " levels:=,=\n" + " categories:=,=\n" + " add pass doi: tags:,\n" + " del doi:\n" + " list [doi:]\n" + "\n"); +} + +/** + * main + */ +int main(int argc, char *argv[]) +{ + int ret_val = RET_ERR; + int arg_iter; + main_function_t *module_main = NULL; + char *module_name; + + /* sanity checks */ + if (argc < 2) { + usage_print(stderr); + return RET_USAGE; + } + + /* get the command line arguments */ + do { + arg_iter = getopt(argc, argv, "hvt:pV"); + switch (arg_iter) { + case 'h': + /* help */ + help_print(stdout); + return RET_OK; + break; + case 'v': + /* verbose */ + opt_verbose = 1; + break; + case 'p': + /* pretty */ + opt_pretty = 1; + break; + case 't': + /* timeout */ + if (atoi(optarg) < 0) { + usage_print(stderr); + return RET_USAGE; + } + opt_timeout = atoi(optarg); + break; + case 'V': + /* version */ + version_print(stdout); + return RET_OK; + break; + } + } while (arg_iter > 0); + + /* perform any setup we have to do */ + ret_val = nlbl_netlink_init(); + if (ret_val < 0) { + fprintf(stderr, "%s: error: failed to initialize the NetLabel library\n", + argv[0]); + goto exit; + } + nlbl_netlink_timeout(opt_timeout); + + module_name = argv[optind]; + if (!module_name) goto exit; + + /* transfer control to the modules */ + if (!strcmp(module_name, "mgmt")) { + module_main = mgmt_main; + } else if (!strcmp(module_name, "map")) { + module_main = map_main; + } else if (!strcmp(module_name, "unlbl")) { + module_main = unlbl_main; + } else if (!strcmp(module_name, "cipsov4")) { + module_main = cipsov4_main; + } else { + fprintf(stderr, + "%s: error: unknown or missing module '%s'\n", + argv[0], + module_name); + goto exit; + } + ret_val = module_main(argc - optind - 1, argv + optind + 1); + if (ret_val < 0) { + fprintf(stderr, + "%s: %s: error: %s\n", + argv[0], + module_name, + strerror(-ret_val)); + ret_val = RET_ERR; + } else { + ret_val = RET_OK; + } + + nlbl_netlink_exit(); + +exit: + return ret_val; +} diff --git a/netlabelctl/map.c b/netlabelctl/map.c new file mode 100644 index 0000000..a63ec94 --- /dev/null +++ b/netlabelctl/map.c @@ -0,0 +1,329 @@ +/* + * Domain/Protocol Mapping Functions + * + * 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 "netlabelctl.h" + +/** + * map_add - Add a domain mapping to NetLabel + * @argc: the number of arguments + * @argv: the argument list + * + * Description: + * Add the specified domain mapping to the NetLabel system. Returns zero on + * success, negative values on failure. + * + */ +int map_add(int argc, char *argv[]) +{ + int ret_val; + unsigned int iter; + unsigned int def_flag = 0; + char *domain_str = NULL; + nlbl_type domain_proto = NETLBL_NLTYPE_NONE; + char *domain_proto_extra = NULL; + mgmt_domain domain; + + /* sanity checks */ + if (argc <= 0 || argv == NULL || argv[0] == NULL) + return -EINVAL; + + /* parse the arguments */ + iter = 0; + while (iter < argc && argv[iter] != NULL) { + if (strncmp(argv[iter], "domain:", 7) == 0) { + /* domain string */ + domain_str = argv[iter] + 7; + } else if (strncmp(argv[iter], "protocol:", 9) == 0) { + /* protocol specifics */ + if (strncmp(argv[iter] + 9, "cipsov4", 7) == 0) + domain_proto = NETLBL_NLTYPE_CIPSOV4; + else if (strncmp(argv[iter] + 9, "unlbl", 5) == 0) + domain_proto = NETLBL_NLTYPE_UNLABELED; + else + domain_proto = NETLBL_NLTYPE_NONE; + domain_proto_extra = strstr(argv[iter] + 9, ","); + if (domain_proto_extra) + domain_proto_extra++; + } else if (strncmp(argv[iter], "default", 7) == 0) { + /* default flag */ + def_flag = 1; + } else + return -EINVAL; + iter++; + } + if ((domain_str == NULL && def_flag == 0) || + domain_proto == NETLBL_NLTYPE_NONE) + return -EINVAL; + + /* generate the domain paramter */ + if (def_flag == 0) { + domain.domain = domain_str; + domain.domain_len = strlen(domain_str) + 1; + } else { + domain.domain = NULL; + domain.domain_len = 0; + } + domain.proto_type = domain_proto; + switch (domain_proto) { + case NETLBL_NLTYPE_CIPSOV4: + domain.proto.cipsov4.doi = (cv4_doi)atoi(domain_proto_extra); + break; + case NETLBL_NLTYPE_UNLABELED: + break; + default: + return -EINVAL; + } + + /* push the mapping into the kernel */ + ret_val = nlbl_mgmt_add(0, &domain, 1, def_flag); + if (opt_pretty) { + if (ret_val < 0) + printf("Failed adding the domain mapping\n"); + else + printf("Added the domain mapping\n"); + } + + return ret_val; +} + +/** + * map_del - Delete a domain mapping from NetLabel + * @argc: the number of arguments + * @argv: the argument list + * + * Description: + * Remove the specified domain mapping from the NetLabel system. Returns zero + * on success, negative values on failure. + * + */ +int map_del(int argc, char *argv[]) +{ + int ret_val; + unsigned int iter; + unsigned int def_flag = 0; + char *domain = NULL; + size_t domain_len; + + /* sanity checks */ + if (argc <= 0 || argv == NULL || argv[0] == NULL) + return -EINVAL; + + /* parse the arguments */ + iter = 0; + while (iter < argc && argv[iter] != NULL) { + if (strncmp(argv[iter], "domain:", 7) == 0) { + /* domain string */ + domain = argv[iter] + 7; + domain_len = strlen(domain) + 1; + } else if (strncmp(argv[iter], "default", 7) == 0) { + /* default flag */ + def_flag = 1; + } else + return -EINVAL; + iter++; + } + if (domain == NULL && def_flag == 0) + return -EINVAL; + + /* remove the mapping from the kernel */ + ret_val = nlbl_mgmt_del(0, &domain, &domain_len, 1, def_flag); + if (opt_pretty) { + if (ret_val < 0) + printf("Failed deleting the domain mapping\n"); + else + printf("Deleted the domain mapping\n"); + } + + return ret_val; +} + +/** + * map_list - List the NetLabel domains mappings + * @argc: the number of arguments + * @argv: the argument list + * + * Description: + * List the configured NetLabel domain mappings. Returns zero on success, + * negative values on failure. + * + */ +int map_list(int argc, char *argv[]) +{ + int ret_val; + mgmt_domain *domains = NULL; + size_t count; + unsigned int iter; + + /* get the mappings from the kernel */ + ret_val = nlbl_mgmt_list(0, &domains, &count, 0); + if (ret_val < 0) + goto list_return; + + /* display the results */ + if (opt_pretty) { + printf("Configured NetLabel domain mappings (%u, not including DEFAULT)\n", count); + for (iter = 0; iter < count; iter++) { + /* domain string */ + printf(" domain: \"%s\"\n", domains[iter].domain); + /* protocol */ + printf(" protocol: "); + switch (domains[iter].proto_type) { + case NETLBL_NLTYPE_UNLABELED: + printf("UNLABELED\n"); + break; + case NETLBL_NLTYPE_CIPSOV4: + printf("CIPSOv4, DOI = %u\n", domains[iter].proto.cipsov4.doi); + break; + default: + printf("UNKNOWN(%u)\n", domains[iter].proto_type); + break; + } + } + } else { + for (iter = 0; iter < count; iter++) { + /* domain string */ + printf("domain:\"%s\",", domains[iter].domain); + /* protocol */ + switch (domains[iter].proto_type) { + case NETLBL_NLTYPE_UNLABELED: + printf("UNLABELED"); + break; + case NETLBL_NLTYPE_CIPSOV4: + printf("CIPSOv4,%u", domains[iter].proto.cipsov4.doi); + break; + default: + printf("UNKNOWN(%u)", domains[iter].proto_type); + break; + } + printf(" "); + } + } + + /* release the mapping memory */ + for (iter = 0; iter < count; iter++) + if (domains[iter].domain) + free(domains[iter].domain); + free(domains); + domains = NULL; + + /* get the default mapping from the kernel */ + ret_val = nlbl_mgmt_list(0, &domains, &count, 1); + if (ret_val < 0) + goto list_return; + + if (count > 0) { + /* display the results */ + if (opt_pretty) { + /* domain string */ + printf(" domain: DEFAULT\n"); + /* protocol */ + printf(" protocol: "); + switch (domains[0].proto_type) { + case NETLBL_NLTYPE_UNLABELED: + printf("UNLABELED\n"); + break; + case NETLBL_NLTYPE_CIPSOV4: + printf("CIPSOv4, DOI = %u\n", domains[0].proto.cipsov4.doi); + break; + default: + printf("UNKNOWN(%u)\n", domains[0].proto_type); + break; + } + } else { + /* domain string */ + printf("domain:DEFAULT,"); + /* protocol */ + switch (domains[0].proto_type) { + case NETLBL_NLTYPE_UNLABELED: + printf("UNLABELED"); + break; + case NETLBL_NLTYPE_CIPSOV4: + printf("CIPSOv4,%u", domains[0].proto.cipsov4.doi); + break; + default: + printf("UNKNOWN(%u)", domains[0].proto_type); + break; + } + printf("\n"); + } + } + + list_return: + if (domains) { + for (iter = 0; iter < count; iter++) + if (domains[iter].domain) + free(domains[iter].domain); + free(domains); + } + + return ret_val; +} + +/** + * map_main - Entry point for the NetLabel mapping functions + * @argc: the number of arguments + * @argv: the argument list + * + * Description: + * Parses the argument list and performs the requested operation. Returns zero + * on success, negative values on failure. + * + */ +int map_main(int argc, char *argv[]) +{ + int ret_val; + + /* sanity checks */ + if (argc <= 0 || argv == NULL || argv[0] == NULL) + return -EINVAL; + + /* handle the request */ + if (strcmp(argv[0], "add") == 0) { + /* add a domain mapping */ + ret_val = map_add(argc - 1, argv + 1); + } else if (strcmp(argv[0], "del") == 0) { + /* delete a domain mapping */ + ret_val = map_del(argc - 1, argv + 1); + } else if (strcmp(argv[0], "list") == 0) { + /* list the domain mappings */ + ret_val = map_list(argc - 1, argv + 1); + } else { + /* unknown request */ + fprintf(stderr, "error[map]: unknown command\n"); + ret_val = -EINVAL; + } + + return ret_val; +} diff --git a/netlabelctl/mgmt.c b/netlabelctl/mgmt.c new file mode 100644 index 0000000..adf6376 --- /dev/null +++ b/netlabelctl/mgmt.c @@ -0,0 +1,142 @@ +/* + * Management Functions + * + * 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 "netlabelctl.h" + +/** + * mgmt_protocols - Display a list of the kernel's NetLabel protocols + * + * Description: + * Request the kernel's supported NetLabel protocols and display the list to + * the user. Returns zero on success, negative values on failure. + * + */ +int mgmt_protocols(void) +{ + int ret_val; + unsigned int *list; + size_t count; + unsigned int iter; + + ret_val = nlbl_mgmt_modules(0, &list, &count); + if (ret_val < 0) + return ret_val; + + if (opt_pretty) + printf("Kernel NetLabel protocols : "); + for (iter = 0; iter < count; iter++) { + switch (list[iter]) { + case NETLBL_NLTYPE_UNLABELED: + printf("UNLABELED"); + break; + case NETLBL_NLTYPE_RIPSO: + printf("RIPSO"); + break; + case NETLBL_NLTYPE_CIPSOV4: + printf("CIPSOv4"); + break; + case NETLBL_NLTYPE_CIPSOV6: + printf("CIPSOv6"); + break; + default: + printf("UNKNOWN(%u)", list[iter]); + break; + } + if (iter + 1 < count) + printf(" "); + } + printf("\n"); + + free(list); + return 0; +} + +/** + * mgmt_version - Display the kernel's NetLabel version + * + * Description: + * Request the kernel's NetLabel version string and display it to the user. + * Returns zero on success, negative values on failure. + * + */ +int mgmt_version(void) +{ + int ret_val; + unsigned int version; + + ret_val = nlbl_mgmt_version(0, &version); + if (ret_val < 0) + return ret_val; + + if (opt_pretty) + printf("Kernel NetLabel version : "); + printf("%u\n", version); + + return 0; +} + +/** + * mgmt_main - Entry point for the NetLabel management functions + * @argc: the number of arguments + * @argv: the argument list + * + * Description: + * Parses the argument list and performs the requested operation. Returns zero + * on success, negative values on failure. + * + */ +int mgmt_main(int argc, char *argv[]) +{ + int ret_val; + + /* sanity checks */ + if (argc <= 0 || argv == NULL || argv[0] == NULL) + return -EINVAL; + + /* handle the request */ + if (strcmp(argv[0], "version") == 0) { + /* kernel version */ + ret_val = mgmt_version(); + } else if (strcmp(argv[0], "protocols") == 0) { + /* module list */ + ret_val = mgmt_protocols(); + } else { + /* unknown request */ + fprintf(stderr, "error[mgmt]: unknown command\n"); + ret_val = -EINVAL; + } + + return ret_val; +} diff --git a/netlabelctl/netlabelctl.h b/netlabelctl/netlabelctl.h new file mode 100644 index 0000000..da6cb3a --- /dev/null +++ b/netlabelctl/netlabelctl.h @@ -0,0 +1,42 @@ +/* + * Header file for the NetLabel Control Utility + * + * 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 + * + */ + +#ifndef _NETLABELCTL_H +#define _NETLABELCTL_H + +/* option variables */ +extern unsigned int opt_verbose; +extern unsigned int opt_timeout; +extern unsigned int opt_pretty; + +/* module entry points */ +typedef int main_function_t(int argc, char *argv[]); +int mgmt_main(int argc, char *argv[]); +int map_main(int argc, char *argv[]); +int unlbl_main(int argc, char *argv[]); +int cipsov4_main(int argc, char *argv[]); + +#endif diff --git a/netlabelctl/unlabeled.c b/netlabelctl/unlabeled.c new file mode 100644 index 0000000..5d0d2d3 --- /dev/null +++ b/netlabelctl/unlabeled.c @@ -0,0 +1,139 @@ +/* + * Unlabeled Functions + * + * 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 "netlabelctl.h" + +/** + * unlbl_accept - Set the NetLabel accept flag + * @argc: the number of arguments + * @argv: the argument list + * + * Description: + * Set the kernel's unlabeled packet allow flag. Returns zero on success, + * negative values on failure. + * + */ +int unlbl_accept(int argc, char *argv[]) +{ + int ret_val; + unsigned int flag; + + /* sanity check */ + if (argc != 1 || argv == NULL || argv[0] == NULL) + return -EINVAL; + + /* set or reset the flag? */ + if (strcasecmp(argv[0], "on") == 0 || strcmp(argv[0], "1") == 0) + flag = 1; + else if (strcasecmp(argv[0], "off") == 0 || strcmp(argv[0], "0") == 0) + flag = 0; + else + return -EINVAL; + + ret_val = nlbl_unlabeled_accept(0, flag); + if (ret_val < 0) + return ret_val; + + if (opt_pretty) { + printf("Allow unlabeled packets : "); + if (flag) + printf("on\n"); + else + printf("off\n"); + } + + return 0; +} + +/** + * unlbl_list - Query the NetLabel accept flag + * + * Description: + * Query the unlabeled packet allow flag. Returns zero on success, negative + * values on failure. + * + */ +int unlbl_list(void) +{ + int ret_val; + unsigned int flag; + + ret_val = nlbl_unlabeled_list(0, &flag); + if (ret_val < 0) + return ret_val; + + if (opt_pretty) + printf("Allow unlabeled packets : "); + if (flag) + printf("on\n"); + else + printf("off\n"); + + return 0; +} + +/** + * unlbl_main - Entry point for the NetLabel unlabeled functions + * @argc: the number of arguments + * @argv: the argument list + * + * Description: + * Parses the argument list and performs the requested operation. Returns zero + * on success, negative values on failure. + * + */ +int unlbl_main(int argc, char *argv[]) +{ + int ret_val; + + /* sanity checks */ + if (argc <= 0 || argv == NULL || argv[0] == NULL) + return -EINVAL; + + /* handle the request */ + if (strcmp(argv[0], "accept") == 0) { + /* accept flag */ + ret_val = unlbl_accept(argc - 1, argv + 1); + } else if (strcmp(argv[0], "list") == 0) { + /* list */ + ret_val = unlbl_list(); + } else { + /* unknown request */ + fprintf(stderr, "error[unlbl]: unknown command\n"); + ret_val = -EINVAL; + } + + return ret_val; +} diff --git a/netlabeld/Makefile b/netlabeld/Makefile new file mode 100644 index 0000000..91be551 --- /dev/null +++ b/netlabeld/Makefile @@ -0,0 +1,53 @@ +# +# NetLabel Daemon Makefile +# +# NetLabel Tools are a collection of user space programs and libraries for +# working with the Linux NetLabel subsystem. The NetLabel subsystem 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 +# + +# +# macros +# + +include ../macros.mk + +# +# configuration +# + +OBJS = + +# +# targets +# + +.PHONY: clean + +all: + @echo "ERROR: netlabeld is not currently supported" + @exit 1 + +clean: + $(RM) -f $(OBJS)