All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/15] RFC Source Policy Support
@ 2010-01-26 22:08 Caleb Case
  2010-01-26 22:08 ` [PATCH 01/15] [src-policy] refpol language and tools Caleb Case
                   ` (2 more replies)
  0 siblings, 3 replies; 34+ messages in thread
From: Caleb Case @ 2010-01-26 22:08 UTC (permalink / raw)
  To: selinux; +Cc: csellers, kmacmillan, jwcart2, jbrindle, sds, Caleb Case

Our motivations for this patchset is to enable source modules to be
stored in the libsemanage store. These changes will allow users and
administrators to:

   1. Insert human readable and editable source modules into the module
      store.

   2. Retrieve existing modules in order to view or make changes.

   3. Stop storing and versioning policy source outside of the semanage
      store for minor local modifications (though it is possible the
      store could be used for general policy development, it is
      anticipated that for larger policy development activities an
      external source store and version control scheme will be used).

Additionally, switching to source modules will bring several other
long-term benefits:

   1. Reduction in the number of binary formats used in the SELinux
      toolchain, easing maintenance and development.

   2. Development path to tools that enable larger policy modifications
      on end systems (e.g., cloning application policies, removing rules
      from distribution provided policy, etc.).

   3. Development path to multiple high-level policy languages.
   
   4. Better Dependency Handling - e.g., updating an interface in one
      module will cause the new interface to be used in other modules
      without re-compiling those modules externally.

   5. The removal of a special base module, allowing more flexibility in
      policy construction and easier overriding, disabling, or removing
      of portions of the core policy.

[Design Considerations]

In creating this design there were several key questions around
backwards compatibility and user experience. Below are several of the
most important and potentially controversial design decisions.

No Support for Binary Modules - Many designs were made that included
support for binary modules including, in several cases, base modules. We
found that the compromises that each of these designs forced were
unacceptable and, perhaps more importantly, there was no way to provide
a user experience that would meet general expectations.  Further, it was
felt that most users either had the source for all of their modules or
in the rare cases when source was not available, the modules would be
trivial and the source could be reasonably extracted using a decompiler.
The most challenging problems were:

   1. Interface files - Because binary modules do not contain the
      interfaces created by their modules it would be necessary to
      locate the corresponding interface files for each binary module to
      allow source modules to be compiled. This is particularly true in
      the case of support for base modules. While it might have been
      possible to hack around this using the interface files in the
      selinux-policy-devel package, there were many problems with this
      approach.

   2. Dependencies - Binary modules would not be able to be updated
      based upon changes to the interfaces in other modules.

   3. Intermediate language - supporting binary modules would make it
      much more challenging to support compilation to the forthcoming
      intermediate language without creating a complex conversion tool.
      It was decided that enabling support for binary modules that would
      eventually be discontinued was not worth the complexity.

Single Source Files - The initial designs for source modules included
the possibility of supporting reference policy modules directly by
combining the three files for each module (.te, .if, and .fc) into a
tarball. This created a very unfriendly user experience and created many
corner cases (which tarball layouts were acceptable, how should the
infrastructure handle 'extra' files in a tarball, etc.).  These
complications led us to instead use a very simple sectioned text format
for reference policy modules and, in the future, to remove the need for
sections through language and compiler features.

Module Ordering - The current reference policy compilation
infrastructure devotes substantial attention to dealing with ordering
problems. Some of these problems are fundamental (such as the ordering
of portcon statements) while others are an artifact of the current
compiler and M4 (such as the need to separate out interface statements
in .if files). Rather than devote substantial effort to creating
mechanisms for specifying or dealing with ordering, it was felt that the
long term solution to this problem is in the improvements that will come
from the proposed common intermediate language [1]. Therefore, in the
short term, several modules will be ordered specially based upon name
and certain policy statements will only be supported in those specially
ordered modules (e.g., a module for specifying defines such as
DISTRO_REDHAT). These hacks can be removed at a later date.

Base Module Removal - The decision to support a special base binary
module was made to make bootstrapping a module store easier by including
a module that was required to have a minimal but complete system policy
and to deal with ordering by only allowing order dependent statements to
appear in the base (such as object class or portcon). Over time it has
become clear that the base module limitations outweigh any of the
intended benefits. This is especially true as support for overriding
policy modules is included. Therefore, the source semanage store will no
longer support or require a special base module.  Further, there will be
no restrictions on the use of policy statements in modules. While this
will allow some unintentional mistakes (e.g., including a broad portcon
in a module that gets processed first) it will also allow additional
freedom (e.g., the use of narrow portcon statements in modules).

[User Experience Overview]

The overall user experience will shift from using external tools to
compile a policy package (.pp) to working directly with source modules.

Source modules will be a single text file containing all of the policy
for that module. For the current reference policy that will require
combining the current interface, type enforcement, and file context
files into a single text file. The user will then use that text file
similarly to how the current binary modules are used. Insertion would be
performed using semodule (the 'ref' extension is for the single file
reference policy format):

# semodule -i apache.ref

Note that the language for the module will be inferred from the
extension to avoid the general tools, such as semodule, needing an
awareness of the format of all source policies. The name would be taken
from the input filename.

Removing a module would be the same as it is currently:

# semodule -r apache

Listing would be generally the same, though there would be the addition
of a language field to the full output:

# semodule -lfull
400 _access_vectors      2.20091117          ref    
400 _constraints         2.20091117          ref    
<snip>
400 _mls                 2.20091117 disabled ref    
<snip>
400 corenetwork          1.13.1              corenet
<snip>
400 zebra                1.10.0     disabled ref    
400 zosremote            1.1.0      disabled ref    

The first large change to user experience is the introduction of a
command to retrieve a module:

# semodule -g apache
# ls
apache.ref

# semodule -g apache -o myapache.ref
# ls
myapache.ref

Similarly, there is the addition of an edit command that is similar to
sudoedit. This is purely a convenience; it will retrieve the module to a
temporary location and install it after updates are made.

# semodule --edit apache

Finally, semodule now supports adding a user message when making
changes:

# semodule --edit apache -m "Allow apache to execute cowsay."

[Compilation]

In the interests of supporting multiple high-level languages (such as
domain specific languages) we provide a two part compilation process.

The first compilation is from a high-level language (HLL) module to a
common intermediate language (CIL) module. This compilation occurs when
a module is installed. The compilation is handled by a HLL specific
compiler conforming the HLL compiler specification.

The second compilation is from CIL modules to binary base module. This
compilation occurs during the commit process. The compilation is handled
by the CIL compiler.

In this implementation the CIL refers to a special formulation of the
refpol language called refpol_ilc and NOT the proposed CIL[1].

[HLL]

We provide an overview of high-level language treatment here. This
patchset introduces two high-level languages refpol and corenet. Please
see their respective patches for details on their languages.

[HLL Compiler Specification]

Each high-level language (HLL) has a compiler that converts from the HLL
to the CIL. The HLL compiler will be a command-line tool that takes the
HLL source as input on stdin and outputs the compiled CIL on stdout.
Errors from compilation will be output on stderr and a non-zero exit
status set. Additionally, the version of the module will be output on
file descriptor 3.

For example an invocation by hand of the refpol HLL compiler:

# refpolc < apache.ref > apache.cil 3<> apache.version

The compiler name, path, HLL extension, and any flags to the compiler
are specified in the language configuration file.

[HLL Configuration File]

Each language has a configuration file stored at:

/etc/selinux/language.d/<language>.conf

Where each <language>.conf contains:

NAME=<human readable name>
COMPILER=<full path to compiler>
EXTENSION=<file extension without dot>
FLAGS=<compiler flags>

For example:

NAME="Reference Policy"
COMPILER="/usr/bin/refpolc"
EXTENSION="ref"
FLAGS=""

Language extensions are required to be unique (at least from all other
languages and preferably globally unique).

[CIL]

Here we discuss the CIL treatment in general. This patchset uses a
special formulation of the refpol language combined with the traditional
Reference Policy build infrastructure as the common intermediary
language (referred to as refpol_ilc). For details on the refpol_ilc
please see its patch.

[CIL Compiler]

The common intermediate language (CIL) compiler converts from the
intermediate language to a binary base module. It is a command line tool
that takes the enabled and disabled modules as parameters. Errors from
compilation will be output on stderr and an non-zero exit status set.
The binary base module will be output on stdout. Disabled modules will
be specified with the -d option.

For example an invocation by hand of the refpol_ilc CIL compiler:

# refpol_ilc `find /var/lib/selinux/targeted/active/modules/400/ -iname cil` > base.pp

[ChangeLog Support]

Every successful commit will produce a log entry. The log entry will
contain the command run, who ran it, their context, when it occurred,
and any user specified message.

The log will be stored at:

/var/lib/selinux/<policy type>/ChangeLog

Each line of the log has the following format:

VERSION="<repo version>" COMMAND="<command + options>" USERNAME="<user name>" CONTEXT="<context>" TIME="<time stamp>" MSG="<message>"

All quoted strings have special characters escaped (quotes and anything
not printable [^:print:]|\").

The origins of the information in the fields is as follows:

   [Field]    [Origin]

   VER        Discovered from the 'SCM', for the time being this will be the
              commit number.

   CMD        Discovered from /proc/self/cmdline if available. May be set by
              the library user.

   USERNAME   Discovered from getpwuid(getuid())->pw_name.

   CONTEXT    Discovered from getprevcon.

   TIME       Discovered from ctime(time(&t)).

   MSG        Set by the library user.

[Setup]

The following steps setup a system with source policy support:

   1. Compile & install patched SELinux userland.

      Note: Remember to install the new python wrappers (install-pywrap)
            if you intend to use semanage.
   
   2. (On Fedora) Remove /lib/libsemanage.so.1. The default installation
      location for libsemanage does not overwrite the one shipped with
      Fedora.
   
   3. Get Reference Policy:

      # git clone http://oss.tresys.com/git/refpolicy.git
   
   4. Make the refpol_ilc build directory:

      # mkdir -p /usr/share/selinux/refpol_ilc/
   
   5. Create and install the refpol_ilc build environment:

      # refpolicy2refpol -b refpolicy /usr/share/selinux/refpol_ilc/build

   6. Convert Reference Policy modules to refpol modules:

      # refpolicy2refpol refpolicy refpol

   7. Copy an existing installed policy such as targeted to a 'test'
      store:

      # cp -R /etc/selinux/targeted /etc/selinux/test

   8. Create necessary directories for a 'test' store in
      /var/lib/selinux:

      # mkdir -p /var/lib/selinux/test/active/modules

   9. Install the source modules to the test store:
   
      # semodule -s test `find refpol -iname \*.ref -or -iname \*.corenet | xargs -I{} echo -i {}`

      Note: The current semanage policy does not allow executing
	    generated files, so you need to change the policy or put
	    semanage in permissive.

[1] CIL RFC: http://marc.info/?l=selinux&m=124759244409438&w=2

Caleb Case (15):
  [src-policy] refpol language and tools
  [src-policy] corenet language and tools
  [src-policy] Reference Policy to refpol conversion tool
  [src-policy] refpol intermediate language compiler (refpol_ilc)
  [src-policy] language.d and language.conf parser
  [src-policy] libsemanage: compile hll module
  [src-policy] libsemanage: compile common intermediary language
  [src-policy] libsemanage: remove binary interfaces
  [src-policy] semodule: remove base module support
  [src-policy] libsemanage: get source module
  [src-policy] semodule: get module source
  [src-policy] semodule: edit module
  [src-policy] libsemanage: ChangeLog support
  [src-policy] semodule: user message support
  [src-policy] semanage: source permissive module

 Makefile                                       |    2 +-
 corenet/COPYING                                |  504 ++++++++++
 corenet/Makefile                               |   27 +
 corenet/corenet.conf                           |    4 +
 corenet/corenet.py                             |   17 +
 corenet/corenet/corenet.py                     |  175 ++++
 corenet/corenet/corenetc.py                    |  129 +++
 corenet/corenetc.py                            |   17 +
 corenet/setup.py                               |   13 +
 libsemanage/include/semanage/modules.h         |   14 +-
 libsemanage/include/semanage/private/handle.h  |   31 +-
 libsemanage/include/semanage/private/modules.h |   28 +-
 libsemanage/src/Makefile                       |   16 +-
 libsemanage/src/direct_api.c                   | 1165 ++++++++++++++----------
 libsemanage/src/handle.c                       |   95 ++-
 libsemanage/src/handle.h                       |   10 +-
 libsemanage/src/lang-parse.y                   |  271 ++++++
 libsemanage/src/lang-scan.l                    |   84 ++
 libsemanage/src/libsemanage.map                |    6 +
 libsemanage/src/modules.c                      |   41 +-
 libsemanage/src/modules.h                      |    3 +-
 libsemanage/src/policy.h                       |   15 +-
 libsemanage/src/semanage_lang_conf.h           |   39 +
 libsemanage/src/semanage_store.c               |  884 ++++++++++++------
 libsemanage/src/semanage_store.h               |   55 +-
 policycoreutils/semanage/seobject.py           |   15 +-
 policycoreutils/semodule/semodule.8            |   27 +-
 policycoreutils/semodule/semodule.c            |  540 +++++++++++-
 refpol/COPYING                                 |  504 ++++++++++
 refpol/Makefile                                |   28 +
 refpol/refpol.conf                             |    4 +
 refpol/refpol.py                               |   17 +
 refpol/refpol/refpol.py                        |  176 ++++
 refpol/refpol/refpolc.py                       |   77 ++
 refpol/refpol/refpolicy2refpol.py              |  185 ++++
 refpol/refpolc.py                              |   17 +
 refpol/refpolicy2refpol.py                     |   17 +
 refpol/setup.py                                |   13 +
 refpol_ilc/COPYING                             |  504 ++++++++++
 refpol_ilc/Makefile                            |   24 +
 refpol_ilc/refpol_ilc.py                       |   17 +
 refpol_ilc/refpol_ilc/refpol_ilc.py            |  193 ++++
 refpol_ilc/setup.py                            |   13 +
 43 files changed, 5200 insertions(+), 816 deletions(-)
 create mode 100644 corenet/COPYING
 create mode 100644 corenet/Makefile
 create mode 100644 corenet/corenet.conf
 create mode 100755 corenet/corenet.py
 create mode 100644 corenet/corenet/__init__.py
 create mode 100644 corenet/corenet/corenet.py
 create mode 100644 corenet/corenet/corenetc.py
 create mode 100755 corenet/corenetc.py
 create mode 100755 corenet/setup.py
 create mode 100644 libsemanage/src/lang-parse.y
 create mode 100644 libsemanage/src/lang-scan.l
 create mode 100644 libsemanage/src/semanage_lang_conf.h
 create mode 100644 refpol/COPYING
 create mode 100644 refpol/Makefile
 create mode 100644 refpol/refpol.conf
 create mode 100755 refpol/refpol.py
 create mode 100644 refpol/refpol/__init__.py
 create mode 100644 refpol/refpol/refpol.py
 create mode 100644 refpol/refpol/refpolc.py
 create mode 100644 refpol/refpol/refpolicy2refpol.py
 create mode 100755 refpol/refpolc.py
 create mode 100755 refpol/refpolicy2refpol.py
 create mode 100755 refpol/setup.py
 create mode 100644 refpol_ilc/COPYING
 create mode 100644 refpol_ilc/Makefile
 create mode 100755 refpol_ilc/refpol_ilc.py
 create mode 100644 refpol_ilc/refpol_ilc/__init__.py
 create mode 100644 refpol_ilc/refpol_ilc/refpol_ilc.py
 create mode 100755 refpol_ilc/setup.py


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH 01/15] [src-policy] refpol language and tools
  2010-01-26 22:08 [PATCH 00/15] RFC Source Policy Support Caleb Case
@ 2010-01-26 22:08 ` Caleb Case
  2010-01-26 22:08   ` [PATCH 02/15] [src-policy] corenet " Caleb Case
  2010-01-27 19:39   ` [PATCH 01/15] [src-policy] refpol language and tools Stephen Smalley
  2010-01-26 22:41 ` [PATCH 00/15] RFC Source Policy Support Xavier Toth
  2010-01-27 20:00 ` Stephen Smalley
  2 siblings, 2 replies; 34+ messages in thread
From: Caleb Case @ 2010-01-26 22:08 UTC (permalink / raw)
  To: selinux; +Cc: csellers, kmacmillan, jwcart2, jbrindle, sds, Caleb Case

[refpol Language]

The refpol language is a simple transformation of a standard Reference
Policy module consisting of 3 files to a single file format with
sections. Each Reference Policy file is placed into a refpol section as
follows:

   <module>.if   =>   [interface]
   <module>.te   =>   [policy]
   <module>.fc   =>   [context]

* These are the only valid section headers.

* A section begins with a section marker and ends with the next marker
  encountered or the end of the file.

* If a file has at least one section marker and there is text before the
  first section then this is an error.

* There can be at most one of each valid section marker in a file.

* A file without any section markers is assumed to be only policy.

* The valid contents of each section are the same as for the separate
  reference policy files.

* The standard filename extension is '.ref'.

[refpol Tool]

The refpol tool can create a refpol module from a Reference Policy
module.

   Usage: refpol COMMAND [OPTIONS] MODULE.ref

   Commands:
     create		create a new refpol
     extract		extract .if, .te, and .fc files from a refpol

   Options:
     --version             show program's version number and exit
     -h, --help            show this help message and exit
     -f, --force           force overwriting existing files

     Create options:
       -i FILE, --interface=FILE
                           interface file
       -p FILE, --policy=FILE
                           policy file
       -c FILE, --context=FILE
                           context file

Example:

# refpol create -i alsa.if -p alsa.te -c alsa.fc alsa.ref

refpol modules should have the '.ref' extension. The resulting alsa.ref
looks like this:

   [interface]

   policy_module(alsa, 1.8.0)

   ########################################
   #
   # Declarations
   #
   <snip>

   [policy]
   ## <summary>Ainit ALSA configuration tool</summary>
   <snip>

   [context]
   /bin/alsaunmute		--	gen_context(system_u:object_r:alsa_exec_t,s0)
   <snip>

[refpol HLL compiler]

The refpolc high level language (HLL) compiler performs basic formatting
checks and extracts the policy version from the policy_module statement.

   Usage: refpolc [OPTIONS] [MODULE]

   Input is read from stdin unless MODULE is provided.
   Output is written to stdout unless -o is specified.

   Options:
     --version             show program's version number and exit
     -h, --help            show this help message and exit
     -f, --force           force overwriting existing files
     -o FILE, --output=FILE
                           output file

Example:

# refpolc < apache.ref > apache.cil 3<> apache.version
---
 Makefile                  |    2 +-
 refpol/COPYING            |  504 +++++++++++++++++++++++++++++++++++++++++++++
 refpol/Makefile           |   27 +++
 refpol/refpol.conf        |    4 +
 refpol/refpol.py          |   17 ++
 refpol/refpol/refpol.py   |  176 ++++++++++++++++
 refpol/refpol/refpolc.py  |   77 +++++++
 refpol/refpolc.py         |   17 ++
 refpol/setup.py           |   13 ++
 9 files changed, 836 insertions(+), 1 deletions(-)
 create mode 100644 refpol/COPYING
 create mode 100644 refpol/Makefile
 create mode 100644 refpol/refpol.conf
 create mode 100755 refpol/refpol.py
 create mode 100644 refpol/refpol/__init__.py
 create mode 100644 refpol/refpol/refpol.py
 create mode 100644 refpol/refpol/refpolc.py
 create mode 100755 refpol/refpolc.py
 create mode 100755 refpol/setup.py

diff --git a/Makefile b/Makefile
index 373ce23..c174327 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-SUBDIRS=libsepol libselinux libsemanage sepolgen checkpolicy policycoreutils # policy
+SUBDIRS=libsepol libselinux libsemanage sepolgen checkpolicy policycoreutils refpol # policy
 PYSUBDIRS=libselinux libsemanage
 
 ifeq ($(DEBUG),1)
diff --git a/refpol/COPYING b/refpol/COPYING
new file mode 100644
index 0000000..8add30a
--- /dev/null
+++ b/refpol/COPYING
@@ -0,0 +1,504 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     51 Franklin St, 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.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, 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 library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+  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.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+  If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be 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.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+  9. 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 Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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 with
+this License.
+\f
+  11. 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 Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  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.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/refpol/Makefile b/refpol/Makefile
new file mode 100644
index 0000000..f081eda
--- /dev/null
+++ b/refpol/Makefile
@@ -0,0 +1,27 @@
+PREFIX ?= $(DESTDIR)/usr
+BINDIR ?= $(PREFIX)/bin
+
+LANGUAGEDIR ?= $(DESTDIR)/etc/selinux/language.d
+
+PYTHON ?= python
+
+ifneq ($(origin DESTDIR), undefined)
+	PYDESTDIR ?= --root=$(DESTDIR)
+endif
+
+all: 
+	$(PYTHON) setup.py build
+
+install: all
+	$(PYTHON) setup.py install $(PYDESTDIR)
+	-mkdir -p $(BINDIR)
+	install -m 755 refpol.py $(BINDIR)/refpol
+	install -m 755 refpolc.py $(BINDIR)/refpolc
+	-mkdir -p $(LANGUAGEDIR)
+	install -m 644 refpol.conf $(LANGUAGEDIR)
+
+clean distclean:
+	$(PYTHON) setup.py clean
+	rm -fr build
+	rm -f refpol/*.pyc
+
diff --git a/refpol/refpol.conf b/refpol/refpol.conf
new file mode 100644
index 0000000..5f1b7b1
--- /dev/null
+++ b/refpol/refpol.conf
@@ -0,0 +1,4 @@
+NAME="Reference Policy"
+COMPILER="/usr/bin/refpolc"
+EXTENSION="ref"
+FLAGS=""
diff --git a/refpol/refpol.py b/refpol/refpol.py
new file mode 100755
index 0000000..c3ebba1
--- /dev/null
+++ b/refpol/refpol.py
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+# Authors:	Caleb Case <ccase@tresys.com>
+#
+# Copyright (C) 2009-2010 Tresys Technology, LLC
+#      This program is free software; you can redistribute it and/or modify
+#      it under the terms of the Lesser GNU General Public License as 
+#      published by the Free Software Foundation, version 2.
+
+import refpol.refpol
+import sys
+
+try:
+	refpol.refpol.main()
+except Exception as e:
+	sys.stderr.write(sys.argv[0] + ": Error: " + str(e) + "\n")
+	sys.exit(1)
diff --git a/refpol/refpol/__init__.py b/refpol/refpol/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/refpol/refpol/refpol.py b/refpol/refpol/refpol.py
new file mode 100644
index 0000000..ad82ef9
--- /dev/null
+++ b/refpol/refpol/refpol.py
@@ -0,0 +1,176 @@
+#!/usr/bin/python
+
+# Authors:	Caleb Case <ccase@tresys.com>
+#
+# Copyright (C) 2009-2010 Tresys Technology, LLC
+#      This program is free software; you can redistribute it and/or modify
+#      it under the terms of the Lesser GNU General Public License as 
+#      published by the Free Software Foundation, version 2.
+
+from optparse import OptionParser, OptionGroup
+import os.path
+import re
+import shutil
+import sys
+
+force = False
+
+def file_exists(path):
+	if os.path.isfile(path) and not force:
+		raise Exception("File already exists: %s" % path)
+
+def itf_to_ref(if_p, te_p, fc_p, ref_p):
+	file_exists(ref_p)
+
+	if not if_p and not te_p and not fc_p:
+		raise Exception("No input files specified.")
+
+	sections = [
+			("[interface]", if_p),
+			("[policy]", te_p),
+			("[context]", fc_p),
+			]
+
+	with open(ref_p, 'w') as out:
+		for (section, path) in sections:
+			if path:
+				with open(path, 'r') as f:
+					out.write("\n" + section + "\n")
+					shutil.copyfileobj(f, out)
+
+def ref_to_itf(ref_p, if_p, te_p, fc_p):
+	verify_ref(ref_p)
+
+	output = None
+	default = False
+
+	sections = {
+			"[interface]"	: if_p,
+			"[policy]"	: te_p,
+			"[context]"	: fc_p,
+			}
+
+	try:
+		with open(ref_p, 'r') as input:
+			for line in input:
+				section = line.strip()
+				if section in sections:
+					if default is True:
+						raise Exception("%s section defined, but already found rules in default section." % section)
+					if output is not None:
+						output.close()
+					file_exists(sections[section])
+					output = open(sections[section], 'w')
+				else:
+					if output is None:
+						if section == "":
+							# ignore blank lines before first section
+							continue
+
+						# output to the default (policy)
+						file_exists(te_p)
+						output = open(te_p, 'w')
+
+						# create empty if and fc
+						file_exists(if_p)
+						with open(if_p, 'w') as f:
+							f.write("## <summary> </summary>\n")
+						file_exists(fc_p)
+						open(fc_p, 'w').close()
+
+						default = True
+					output.write(line)
+	finally:
+		if output is not None:
+			output.close()
+
+def verify_ref(ref):
+	sections = {
+			"[interface]" : False,
+			"[policy]"    : False,
+			"[context]"   : False,
+			}
+
+	default = False
+
+	pattern = re.compile("\s*policy_module\((?P<name>\w+),\s*(?P<version>[0-9.]+)\).*")
+	result = None
+
+	if isinstance(ref, str):
+		with open(ref, 'r') as input:
+			return verify_ref(input)
+
+	lineno = 0
+	for line in ref:
+		lineno = lineno + 1
+		section = line.strip()
+
+		if section == "":
+			# ignore blank lines
+			continue
+		elif section in sections:
+			if sections[section] is True:
+				raise Exception("Too many %s sections (%s:%d)." % (section, ref.name, lineno))
+			if default is True:
+				raise Exception("%s section defined, but already found rules in default section (%s:%d)." % (section, ref.name, lineno))
+			sections[section] = True
+		else:
+			if not any(sections.values()):
+				# we aren't in a section, but we found information
+				# this means we are must start the default section
+				default = True
+
+			mod = pattern.match(line)
+			if mod:
+				result = { "name"	: mod.group("name"),
+					   "version"	: mod.group("version")}
+	if not result:
+		raise Exception("Failed to find the policy module statement! (%s)" % ref.name)
+
+	return result
+
+def verify_ext(ref_p):
+	ext = ref_p.rsplit('.', 1)[1]
+	if ext != "ref":
+		raise Exception("Invalid refpol file extension %s on %s." % (ext, ref_p))
+
+usage = """%prog COMMAND [OPTIONS] MODULE.ref
+
+Commands:
+  create		create a new refpol
+  extract		extract .if, .te, and .fc files from a refpol"""
+
+version = "%prog 1.0"
+
+def main():
+	parser = OptionParser(usage = usage, version = version)
+	parser.add_option("-f", "--force", action = "store_true", default = False, dest = "force", help = "force overwriting existing files")
+
+	create_options = OptionGroup(parser, "Create options")
+	create_options.add_option("-i", "--interface", action = "store", default = None, dest = "ifp", help = "interface file", metavar = "FILE")
+	create_options.add_option("-p", "--policy", action = "store", default = None, dest = "tep", help = "policy file", metavar = "FILE")
+	create_options.add_option("-c", "--context", action = "store", default = None, dest = "fcp", help = "context file", metavar = "FILE")
+	parser.add_option_group(create_options)
+
+	(options, args) = parser.parse_args()
+	if len(args) != 2:
+		parser.error("Invalid number of arguments %d." % len(args))
+	force = options.force
+
+	verify_ext(args[1])
+
+	command = args[0]
+	if command == "create":
+		itf_to_ref(options.ifp, options.tep, options.fcp, args[1])
+	elif command == "extract":
+		module = args[1].rsplit('.', 1)[0]
+		ref_to_itf(args[1], module + ".if", module + ".te", module + ".fc")
+	else:
+		parser.error("Invalid command %s." % command)
+
+if __name__ == '__main__':
+	try:
+		main()
+	except Exception as e:
+		sys.stderr.write(sys.argv[0] + ": Error: " + str(e) + "\n")
+		sys.exit(1)
diff --git a/refpol/refpol/refpolc.py b/refpol/refpol/refpolc.py
new file mode 100644
index 0000000..e04be32
--- /dev/null
+++ b/refpol/refpol/refpolc.py
@@ -0,0 +1,77 @@
+#!/usr/bin/python
+
+# Authors:	Caleb Case <ccase@tresys.com>
+#
+# Copyright (C) 2009-2010 Tresys Technology, LLC
+#      This program is free software; you can redistribute it and/or modify
+#      it under the terms of the Lesser GNU General Public License as 
+#      published by the Free Software Foundation, version 2.
+
+from optparse import OptionParser, OptionGroup
+import os
+import refpol
+import shutil
+import sys
+import tempfile
+
+usage = """%prog [OPTIONS] [MODULE]
+
+Input is read from stdin unless MODULE is provided.
+Output is written to stdout unless -o is specified."""
+
+version = "%prog 1.0"
+
+def main():
+	# create cmdline parser
+	parser = OptionParser(usage = usage, version = version)
+	parser.add_option("-f", "--force", action = "store_true", default = False, dest = "force", help = "force overwriting existing files")
+	parser.add_option("-o", "--output", action = "store", default = None, dest = "output", help = "output file", metavar = "FILE")
+
+	# parse cmdline
+	(options, args) = parser.parse_args()
+	options.input = sys.stdin
+
+	if len(args) > 1:
+		parser.error("Invalid number of arguments %d." % len(args))
+	elif len(args) == 1:
+		options.input = open(args[0])
+
+	force = options.force
+	refpol.force = options.force
+
+	if options.output is None:
+		options.output = sys.stdout
+	else:
+		refpol.file_exists(options.output)
+		options.output = open(options.output, "w")
+
+	try:
+		with tempfile.SpooledTemporaryFile(suffix="-refpolc") as tmp:
+			# copy input into a tmp location
+			# this is needed since you can't seek stdin
+			shutil.copyfileobj(options.input, tmp)
+
+			# borrow the input name so that error msg are correct
+			tmp.name = options.input.name
+
+			# reset & verify the tmp file
+			tmp.seek(0)
+			mod = refpol.verify_ref(tmp)
+
+			with os.fdopen(3, "w") as ver:
+				ver.write(mod["version"]);
+
+			# reset & copy tmp file to output
+			tmp.seek(0)
+			shutil.copyfileobj(tmp, options.output)
+
+	finally:
+		options.input.close()
+		options.output.close()
+
+if __name__ == '__main__':
+	try:
+		main()
+	except Exception as e:
+		sys.stderr.write(sys.argv[0] + ": Error: " + str(e) + "\n")
+		sys.exit(1)
diff --git a/refpol/refpolc.py b/refpol/refpolc.py
new file mode 100755
index 0000000..b98c43e
--- /dev/null
+++ b/refpol/refpolc.py
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+# Authors:	Caleb Case <ccase@tresys.com>
+#
+# Copyright (C) 2009-2010 Tresys Technology, LLC
+#      This program is free software; you can redistribute it and/or modify
+#      it under the terms of the Lesser GNU General Public License as 
+#      published by the Free Software Foundation, version 2.
+
+import refpol.refpolc
+import sys
+
+try:
+	refpol.refpolc.main()
+except Exception as e:
+	sys.stderr.write(sys.argv[0] + ": Error: " + str(e) + "\n")
+	sys.exit(1)
diff --git a/refpol/setup.py b/refpol/setup.py
new file mode 100755
index 0000000..2cac202
--- /dev/null
+++ b/refpol/setup.py
@@ -0,0 +1,13 @@
+#!/usr/bin/python
+
+from distutils.core import setup
+
+setup(	name		= "refpol",
+	version		= "0.1",
+	description	= "Refpol Tool",
+#	url		= "",
+	author		= "Caleb Case",
+	author_email	= "ccase@tresys.com",
+	license		= "LGPL v2.1",
+	packages	= ['refpol'],
+	)
-- 
1.6.3.3


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 02/15] [src-policy] corenet language and tools
  2010-01-26 22:08 ` [PATCH 01/15] [src-policy] refpol language and tools Caleb Case
@ 2010-01-26 22:08   ` Caleb Case
  2010-01-26 22:08     ` [PATCH 03/15] [src-policy] Reference Policy to refpol conversion tool Caleb Case
  2010-01-27 19:39   ` [PATCH 01/15] [src-policy] refpol language and tools Stephen Smalley
  1 sibling, 1 reply; 34+ messages in thread
From: Caleb Case @ 2010-01-26 22:08 UTC (permalink / raw)
  To: selinux; +Cc: csellers, kmacmillan, jwcart2, jbrindle, sds, Caleb Case

[corenet Language]

The corenet language is a simple transformation of the Reference Policy
corenetwork module consisting of 5 files to a single file format with
sections. Each corenetwork file is placed into a corenet section as
follows:

   <module>.if.in   =>   [interface in]
   <module>.if.m4   =>   [interface m4]
   <module>.te.in   =>   [policy in]
   <module>.te.m4   =>   [policy m4]
   <module>.fc      =>   [context]

* These are the only valid section headers.

* A section begins with a section marker and ends with the next marker
  encountered or the end of the file.

* All sections are required.

* Any text outside of a section is an error.

* The valid contents of each section are the same as for the separate
  reference policy files.

* The standard filename extension is '.corenet'.

[corenet Tool]

The corenet tool can create a corenet module from a Reference Policy
corenetwork module.

   Usage: corenet COMMAND -n [FILES] -m [FILES] -c [FILE] MODULE.corenet

   Commands:
     create		create a new corenet
     extract		extract .if.(in,m4), .te.(in,m4), and .fc files from a corenet

   Options:
     --version             show program's version number and exit
     -h, --help            show this help message and exit
     -f, --force           force overwriting existing files

     Modes:
       -n, --in            specify 'in' files (interface and policy)
       -m, --m4            specify 'm4' files (interface and policy)
       -c FILE, --context=FILE
                           context file

     Create options:
       -i FILE, --interface=FILE
                           interface file
       -p FILE, --policy=FILE
                           policy file

Example:

# corenet create -n -i corenetwork.if.in -p corenetwork.te.in -m -i corenetwork.if.m4 -p corenetwork.if.in -c corenetwork.fc corenetwork.corenet

corenet modules should have the '.corenet' extension. The resulting
corenetwork.corenet module looks like this:

   [interface in]
   ## <summary>Policy controlling access to network objects</summary>
   ## <required val="true">
   ##      Contains the initial SIDs for network objects.
   <snip>

   [interface m4]
   #
   # shiftn(num,list...)
   #
   <snip>

   [policy in]

   policy_module(corenetwork, 1.13.1)

   <snip>

   [policy m4]
   #
   # shiftn(num,list...)
   #
   <snip>

   [context]

   /dev/ippp.*     -c      gen_context(system_u:object_r:ppp_device_t,s0)
   /dev/ppp        -c      gen_context(system_u:object_r:ppp_device_t,s0)
   <snip>

[corenet HLL Compiler]

The corenetc high level language compiler compiles the the corenet
module into a refpol module and extracts the policy version from the
policy_module statement.

   Usage: corenetc [OPTIONS] [MODULE]

   Input is read from stdin unless MODULE is provided.
   Output is written to stdout unless -o is specified.

   Options:
     --version             show program's version number and exit
     -h, --help            show this help message and exit
     -f, --force           force overwriting existing files
     -t DIR, --tmp=DIR     temporary build directory
     -o FILE, --output=FILE
                           output file
     -c BOOL, --cleanup=BOOL
                           cleanup (remove) temporary directory (Default: True)

Example:

# corenetc < corenetwork.corenet > corenetwork.cil 3<> corenetwork.version
---
 Makefile                    |    2 +-
 corenet/COPYING             |  504 +++++++++++++++++++++++++++++++++++++++++++
 corenet/Makefile            |   27 +++
 corenet/corenet.conf        |    4 +
 corenet/corenet.py          |   17 ++
 corenet/corenet/corenet.py  |  175 +++++++++++++++
 corenet/corenet/corenetc.py |  129 +++++++++++
 corenet/corenetc.py         |   17 ++
 corenet/setup.py            |   13 ++
 9 files changed, 887 insertions(+), 1 deletions(-)
 create mode 100644 corenet/COPYING
 create mode 100644 corenet/Makefile
 create mode 100644 corenet/corenet.conf
 create mode 100755 corenet/corenet.py
 create mode 100644 corenet/corenet/__init__.py
 create mode 100644 corenet/corenet/corenet.py
 create mode 100644 corenet/corenet/corenetc.py
 create mode 100755 corenet/corenetc.py
 create mode 100755 corenet/setup.py

diff --git a/Makefile b/Makefile
index c174327..be2a4ec 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-SUBDIRS=libsepol libselinux libsemanage sepolgen checkpolicy policycoreutils refpol # policy
+SUBDIRS=libsepol libselinux libsemanage sepolgen checkpolicy policycoreutils refpol corenet # policy
 PYSUBDIRS=libselinux libsemanage
 
 ifeq ($(DEBUG),1)
diff --git a/corenet/COPYING b/corenet/COPYING
new file mode 100644
index 0000000..8add30a
--- /dev/null
+++ b/corenet/COPYING
@@ -0,0 +1,504 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     51 Franklin St, 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.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, 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 library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+  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.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+  If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be 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.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+  9. 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 Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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 with
+this License.
+\f
+  11. 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 Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  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.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/corenet/Makefile b/corenet/Makefile
new file mode 100644
index 0000000..f108f74
--- /dev/null
+++ b/corenet/Makefile
@@ -0,0 +1,27 @@
+PREFIX ?= $(DESTDIR)/usr
+BINDIR ?= $(PREFIX)/bin
+
+LANGUAGEDIR ?= $(DESTDIR)/etc/selinux/language.d
+
+PYTHON ?= python
+
+ifneq ($(origin DESTDIR), undefined)
+	PYDESTDIR ?= --root=$(DESTDIR)
+endif
+
+all: 
+	$(PYTHON) setup.py build
+
+install:
+	$(PYTHON) setup.py install $(PYDESTDIR)
+	-mkdir -p $(BINDIR)
+	install -m 755 corenet.py $(BINDIR)/corenet
+	install -m 755 corenetc.py $(BINDIR)/corenetc
+	-mkdir -p $(LANGUAGEDIR)
+	install -m 755 corenet.conf $(LANGUAGEDIR)
+
+clean distclean:
+	$(PYTHON) setup.py clean
+	rm -fr build
+	rm -f corenet/*.pyc
+
diff --git a/corenet/corenet.conf b/corenet/corenet.conf
new file mode 100644
index 0000000..c68ba26
--- /dev/null
+++ b/corenet/corenet.conf
@@ -0,0 +1,4 @@
+NAME="Corenetwork"
+COMPILER="/usr/bin/corenetc"
+EXTENSION="corenet"
+FLAGS=""
diff --git a/corenet/corenet.py b/corenet/corenet.py
new file mode 100755
index 0000000..8c6b1f4
--- /dev/null
+++ b/corenet/corenet.py
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+# Authors:	Caleb Case <ccase@tresys.com>
+#
+# Copyright (C) 2009-2010 Tresys Technology, LLC
+#      This program is free software; you can redistribute it and/or modify
+#      it under the terms of the Lesser GNU General Public License as 
+#      published by the Free Software Foundation, version 2.
+
+import corenet.corenet
+import sys
+
+try:
+	corenet.corenet.main()
+except Exception as e:
+	sys.stderr.write(sys.argv[0] + ": Error: " + str(e) + "\n")
+	sys.exit(1)
diff --git a/corenet/corenet/__init__.py b/corenet/corenet/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/corenet/corenet/corenet.py b/corenet/corenet/corenet.py
new file mode 100644
index 0000000..266861b
--- /dev/null
+++ b/corenet/corenet/corenet.py
@@ -0,0 +1,175 @@
+#!/usr/bin/python
+
+# Authors:	Caleb Case <ccase@tresys.com>
+#
+# Copyright (C) 2009-2010 Tresys Technology, LLC
+#      This program is free software; you can redistribute it and/or modify
+#      it under the terms of the Lesser GNU General Public License as 
+#      published by the Free Software Foundation, version 2.
+
+from optparse import OptionParser, OptionGroup
+import os.path
+import re
+from refpol import refpol
+import sys
+
+force = False
+
+def itf_to_corenet(if_in_p, if_m4_p, te_in_p, te_m4_p, fc_p, corenet_p):
+	refpol.file_exists(corenet_p)
+
+	sections = [
+			("[interface in]", if_in_p),
+			("[interface m4]", if_m4_p),
+			("[policy in]", te_in_p),
+			("[policy m4]", te_m4_p),
+			("[context]", fc_p),
+			]
+
+	with open(corenet_p, 'w') as out:
+		for (section, path) in sections:
+			with open(path, 'r') as f:
+				out.write("\n" + section + "\n")
+				out.write(f.read())
+
+def corenet_to_itf(corenet_p, if_in_p, if_m4_p, te_in_p, te_m4_p, fc_p):
+	verify_corenet(corenet_p)
+
+	output = None
+
+	sections = {
+			"[interface in]" : if_in_p,
+			"[interface m4]" : if_m4_p,
+			"[policy in]"    : te_in_p,
+			"[policy m4]"    : te_m4_p,
+			"[context]"      : fc_p,
+			}
+
+	try:
+		with open(corenet_p, 'r') as input:
+			for line in input:
+				if line.strip() in sections:
+					if output is not None:
+						output.close()
+					refpol.file_exists(sections[line.strip()])
+					output = open(sections[line.strip()], 'w')
+				else:
+					if output is None and line.strip() == "":
+						# ignore blank lines before first section
+						continue
+					output.write(line)
+	finally:
+		if output is not None:
+			output.close()
+
+def verify_corenet(corenet):
+	sections = {
+			"[interface in]" : False,
+			"[interface m4]" : False,
+			"[policy in]"    : False,
+			"[policy m4]"    : False,
+			"[context]"      : False,
+			}
+
+	pattern = re.compile("\s*policy_module\((?P<name>\w+),\s*(?P<version>[0-9.]+)\).*")
+	result = None
+
+	if isinstance(corenet, str):
+		with open(corenet, 'r') as input:
+			return verify_corenet(input)
+
+	lineno = 0
+	for line in corenet:
+		lineno = lineno + 1
+		section = line.strip()
+
+		if section == "":
+			# ignore blank lines
+			pass
+		elif section in sections:
+			if sections[section] is True:
+				raise Exception("Too many %s sections (%s:%d)." % (section, corenet.name, lineno))
+			sections[section] = True
+		else:
+			if not any(sections.values()):
+				raise Exception("Invalid data outside section at line %s:%d: %s" % (corenet.name, lineno, line))
+
+			mod = pattern.match(line)
+			if mod:
+				result = { "name"	: mod.group("name"),
+					   "version"	: mod.group("version") }
+	if not result:
+		raise Exception("Failed to discover module name and version. policy_module statement missing?")
+
+	return result
+
+def verify_ext(corenet_p):
+	ext = corenet_p.rsplit('.', 1)[1]
+	if ext != "corenet":
+		raise Exception("Invalid corenet file extension %s on %s." % (ext, corenet_p))
+
+usage = """%prog COMMAND -n [FILES] -m [FILES] -c [FILE] MODULE.corenet
+
+Commands:
+  create		create a new corenet
+  extract		extract .if.(in,m4), .te.(in,m4), and .fc files from a corenet"""
+
+version = "%prog 1.0"
+
+def main():
+	def create(option, opt_str, value, parser, *args, **kwargs):
+		if opt_str in ["-i", "--interface"]:
+			if parser.values.mode == "in":
+				parser.values.if_in_p = value
+			elif parser.values.mode == "m4":
+				parser.values.if_m4_p = value
+			else:
+				raise Exception("Invalid mode: %s" % parser.values.mode)
+		elif opt_str in ["-p", "--policy"]:
+			if parser.values.mode == "in":
+				parser.values.te_in_p = value
+			elif parser.values.mode == "m4":
+				parser.values.te_m4_p = value
+			else:
+				raise Exception("Invalid mode: %s" % parser.values.mode)
+		else:
+			raise Exception("Invalid file selector: %s" % option)
+
+	parser = OptionParser(usage = usage, version = version)
+	parser.add_option("-f", "--force", action = "store_true", default = False, dest = "force", help = "force overwriting existing files")
+
+	modes = OptionGroup(parser, "Modes")
+	modes.add_option("-n", "--in", action = "store_const", const = "in", dest = "mode", help = "specify 'in' files (interface and policy)")
+	modes.add_option("-m", "--m4", action = "store_const", const = "m4", dest = "mode", help = "specify 'm4' files (interface and policy)")
+	modes.add_option("-c", "--context", action = "store", default = None, dest = "fc_p", help = "context file", metavar = "FILE")
+	parser.add_option_group(modes)
+
+	create_options = OptionGroup(parser, "Create options")
+	create_options.add_option("-i", "--interface", action = "callback", callback = create, type = "string", help = "interface file", metavar = "FILE")
+	create_options.add_option("-p", "--policy", action = "callback", callback = create, type = "string", help = "policy file", metavar = "FILE")
+	parser.add_option_group(create_options)
+
+	(options, args) = parser.parse_args()
+	if len(args) != 2:
+		parser.error("Invalid number of arguments %d." % len(args))
+
+	force = options.force
+	refpol.force = options.force
+
+	verify_ext(args[1])
+
+	command = args[0]
+	if command == "create":
+		itf_to_corenet(options.if_in_p, options.if_m4_p, options.te_in_p, options.te_m4_p, options.fc_p, args[1])
+	elif command == "extract":
+		module = args[1].rsplit('.', 1)[0]
+		corenet_to_itf(args[1], module + ".if.in", module + ".if.m4", module + ".te.in", module + ".te.m4", module + ".fc")
+	else:
+		parser.error("Invalid command %s." % command)
+
+if __name__ == '__main__':
+	try:
+		main()
+	except Exception as e:
+		sys.stderr.write(sys.argv[0] + ": Error: " + str(e) + "\n")
+		sys.exit(1)
diff --git a/corenet/corenet/corenetc.py b/corenet/corenet/corenetc.py
new file mode 100644
index 0000000..f707590
--- /dev/null
+++ b/corenet/corenet/corenetc.py
@@ -0,0 +1,129 @@
+#!/usr/bin/python
+
+# Authors:	Caleb Case <ccase@tresys.com>
+#
+# Copyright (C) 2009-2010 Tresys Technology, LLC
+#      This program is free software; you can redistribute it and/or modify
+#      it under the terms of the Lesser GNU General Public License as 
+#      published by the Free Software Foundation, version 2.
+
+import corenet
+from optparse import OptionParser, OptionGroup
+import os
+import os.path
+import tempfile
+from refpol import refpol
+import shutil
+import subprocess
+import sys
+
+def to_bool(str):
+	return 	{
+			"true"	: True,
+			"t"	: True,
+			"1"	: True,
+			"false"	: False,
+			"f"	: False,
+			"0"	: False,
+		}[str.lower()]
+
+usage = """%prog [OPTIONS] [MODULE]
+
+Input is read from stdin unless MODULE is provided.
+Output is written to stdout unless -o is specified."""
+
+version = "%prog 1.0"
+
+def main():
+	# create cmdline parser
+	parser = OptionParser(usage = usage, version = version)
+	parser.add_option("-f", "--force", action = "store_true", default = False, dest = "force", help = "force overwriting existing files")
+	parser.add_option("-t", "--tmp", action = "store", default = None, dest = "tmp", help = "temporary build directory", metavar = "DIR")
+	parser.add_option("-o", "--output", action = "store", default = None, dest = "output", help = "output file", metavar = "FILE")
+	parser.add_option("-c", "--cleanup", action = "store", default = "True", dest = "cleanup", help = "cleanup (remove) temporary directory (Default: True)", metavar = "BOOL")
+
+	# parse cmdline
+	(options, args) = parser.parse_args()
+	options.input = sys.stdin
+
+	if len(args) > 1:
+		parser.error("Invalid number of arguments %d." % len(args))
+	elif len(args) == 1:
+		options.input = open(args[0])
+
+	# save the working directory
+	saved_cwd = os.getcwd()
+
+	force = options.force
+	refpol.force = options.force
+
+	if options.output is None:
+		options.output = sys.stdout
+	else:
+		refpol.file_exists(options.output)
+		options.output = open(options.output, "w")
+
+	try:
+		if not options.tmp:
+			# create tmp build dir if one isn't provided
+			options.tmp = tempfile.mkdtemp("-corenetc")
+		else:
+			shutil.rmtree(options.tmp, ignore_errors = True)
+			os.mkdir(options.tmp)
+
+		os.chdir(options.tmp)
+
+		with open("input.corenet", "w") as input:
+			shutil.copyfileobj(options.input, input)
+
+		with open("input.corenet", "r") as input:
+			# verify corenet (and write out version)
+			mod = corenet.verify_corenet(input)
+
+			with os.fdopen(3, "w") as ver:
+				ver.write(mod["version"]);
+
+		# unpack corenet
+		corenet.corenet_to_itf("input.corenet",
+				       "input.if",
+				       "input.if.m4",
+				       "input.te.in",
+				       "input.te.m4",
+				       "input.fc")
+
+		# make corenet if
+		p = subprocess.Popen("egrep '^[[:blank:]]*network_(interface|node|port|packet)(_controlled)?\(.*\)' input.te.in | m4 input.if.m4 - | sed -e 's/dollarsone/\$1/g' -e 's/dollarszero/\$0/g'", shell = True, stdout = open("input.if", "a"), stderr = subprocess.PIPE, close_fds = True)
+		(stdout, stderr) = p.communicate()
+		sys.stderr.write(stderr)
+		if p.returncode != 0:
+			raise Exception("Failed to compile corenet module if (%d)." % p.returncode)
+
+		# make corenet te
+		p = subprocess.Popen("m4 input.te.m4 input.te.in | sed -e 's/dollarsone/\$1/g' -e 's/dollarszero/\$0/g'", shell = True, stdout = open("input.te", "w"), stderr = subprocess.PIPE, close_fds = True)
+		(stdout, stderr) = p.communicate()
+		sys.stderr.write(stderr)
+		if p.returncode != 0:
+			raise Exception("Failed to compile corenet module te (%d)." % p.returncode)
+
+		# combine into a refpol
+		refpol.itf_to_ref("input.if", "input.te", "input.fc", "input.ref")
+
+		with open("input.ref", "r") as input:
+			shutil.copyfileobj(input, options.output)
+
+	finally:
+		if to_bool(options.cleanup):
+			shutil.rmtree(options.tmp)
+
+		options.input.close()
+		options.output.close()
+
+		# return the saved directory
+		os.chdir(saved_cwd)
+
+if __name__ == '__main__':
+	try:
+		main()
+	except Exception as e:
+		sys.stderr.write(sys.argv[0] + ": Error: " + str(e) + "\n")
+		sys.exit(1)
diff --git a/corenet/corenetc.py b/corenet/corenetc.py
new file mode 100755
index 0000000..2afb4c5
--- /dev/null
+++ b/corenet/corenetc.py
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+# Authors:	Caleb Case <ccase@tresys.com>
+#
+# Copyright (C) 2009-2010 Tresys Technology, LLC
+#      This program is free software; you can redistribute it and/or modify
+#      it under the terms of the Lesser GNU General Public License as 
+#      published by the Free Software Foundation, version 2.
+
+import corenet.corenetc
+import sys
+
+try:
+	corenet.corenetc.main()
+except Exception as e:
+	sys.stderr.write(sys.argv[0] + ": Error: " + str(e) + "\n")
+	sys.exit(1)
diff --git a/corenet/setup.py b/corenet/setup.py
new file mode 100755
index 0000000..11b2b98
--- /dev/null
+++ b/corenet/setup.py
@@ -0,0 +1,13 @@
+#!/usr/bin/python
+
+from distutils.core import setup
+
+setup(	name		= "corenet",
+	version		= "0.1",
+	description	= "Corenet Tool",
+#	url		= "",
+	author		= "Caleb Case",
+	author_email	= "ccase@tresys.com",
+	license		= "LGPL v2.1",
+	packages	= ['corenet'],
+	)
-- 
1.6.3.3


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 03/15] [src-policy] Reference Policy to refpol conversion tool
  2010-01-26 22:08   ` [PATCH 02/15] [src-policy] corenet " Caleb Case
@ 2010-01-26 22:08     ` Caleb Case
  2010-01-26 22:08       ` [PATCH 04/15] [src-policy] refpol intermediate language compiler (refpol_ilc) Caleb Case
  0 siblings, 1 reply; 34+ messages in thread
From: Caleb Case @ 2010-01-26 22:08 UTC (permalink / raw)
  To: selinux; +Cc: csellers, kmacmillan, jwcart2, jbrindle, sds, Caleb Case

The refpolicy2refpol tool automates the conversion from the upstream
reference policy modules into refpol modules. It also automates the
process of creating the refpol_ilc[1] build environment from the
upstream reference policy tree.

   Usage: refpolicy2refpol [OPTIONS] SOURCE TARGET

   Options:
     --version    show program's version number and exit
     -h, --help   show this help message and exit
     -b, --build  create the Refpol ILC build environment (default: False)
     -f, --force  force overwriting existing files

Examples:

Converting Reference Policy modules to refpol modules:

# refpolicy2refpol refpolicy refpol
# find refpol
refpol/policy/_rolemap.ref
<snip>
refpol/policy/modules/services/cyrus.ref
refpol/policy/modules/services/metadata.xml
refpol/policy/modules/services/pxe.ref
<snip>

Creating the refpol_ilc build environment:

# refpolicy2refpol -b refpolicy /usr/share/selinux/refpol_ilc/build

[1] See next patch for the refpol_ilc.
---
 refpol/Makefile                   |    1 +
 refpol/refpol/refpolicy2refpol.py |  185 +++++++++++++++++++++++++++++++++++++
 refpol/refpolicy2refpol.py        |   17 ++++
 3 files changed, 203 insertions(+), 0 deletions(-)
 create mode 100644 refpol/refpol/refpolicy2refpol.py
 create mode 100755 refpol/refpolicy2refpol.py

diff --git a/refpol/Makefile b/refpol/Makefile
index f081eda..00c81b8 100644
--- a/refpol/Makefile
+++ b/refpol/Makefile
@@ -17,6 +17,7 @@ install: all
 	-mkdir -p $(BINDIR)
 	install -m 755 refpol.py $(BINDIR)/refpol
 	install -m 755 refpolc.py $(BINDIR)/refpolc
+	install -m 755 refpolicy2refpol.py $(BINDIR)/refpolicy2refpol
 	-mkdir -p $(LANGUAGEDIR)
 	install -m 644 refpol.conf $(LANGUAGEDIR)
 
diff --git a/refpol/refpol/refpolicy2refpol.py b/refpol/refpol/refpolicy2refpol.py
new file mode 100644
index 0000000..c6b290a
--- /dev/null
+++ b/refpol/refpol/refpolicy2refpol.py
@@ -0,0 +1,185 @@
+#!/usr/bin/python
+
+# Authors:	Caleb Case <ccase@tresys.com>
+#
+# Copyright (C) 2009-2010 Tresys Technology, LLC
+#      This program is free software; you can redistribute it and/or modify
+#      it under the terms of the Lesser GNU General Public License as 
+#      published by the Free Software Foundation, version 2.
+
+from corenet import corenet
+import glob
+from optparse import OptionParser
+import os
+import refpol
+from shutil import copytree, ignore_patterns, rmtree, copyfileobj
+import sys
+
+force = False
+
+def modules(source):
+	return [item.rsplit('.', 1)[0] for item in glob.glob(source + "/policy/modules/*/*.te")]
+
+def specials(source):
+	return [source + item for item in [
+		"/policy/constraints",
+		"/policy/global_booleans",
+		"/policy/global_tunables",
+		"/policy/mcs",
+		"/policy/mls",
+		"/policy/policy_capabilities",
+		"/policy/rolemap",
+		"/policy/users",
+		"/policy/flask/access_vectors",
+		"/policy/flask/initial_sids",
+		"/policy/flask/security_classes",
+		"/policy/support/file_patterns.spt",
+		"/policy/support/ipc_patterns.spt",
+		"/policy/support/loadable_module.spt",
+		"/policy/support/misc_macros.spt",
+		"/policy/support/misc_patterns.spt",
+		"/policy/support/mls_mcs_macros.spt",
+		"/policy/support/obj_perm_sets.spt",
+		]]
+
+def discards(source):
+	return [source + item for item in [
+		"/policy/modules/admin",
+		"/policy/modules/apps",
+		"/policy/modules/roles",
+		"/policy/modules/services",
+		"/policy/modules/system",
+		]]
+
+def corenets(source):
+	return [source + item.rsplit('.', 1)[0] for item in [
+		"/policy/modules/kernel/corenetwork"
+		]]
+
+def build_conf_to_defines(source, target, version):
+	defines_table = ["OUTPUT_POLICY",
+			 "NAME",
+			 "DISTRO",
+			 "UNK_PERMS",
+			 "DIRECT_INITRC",
+			 "UBAC",
+			 "MLS_SENS",
+			 "MLS_CATS",
+			 "MCS_CATS",
+			 "QUIET",
+			 ]
+
+	with open(source, "r") as build_conf:
+		with open(target, "w") as defines:
+			defines.write("policy_module(_defines, %s)\n" % version)
+
+			buffer = []
+			for line in build_conf:
+				sline = line.strip()
+				if sline.startswith("#") or sline.strip() == "":
+					   buffer[len(buffer):] = [line]
+				elif sline.split('=')[0].strip() in defines_table:
+					defines.writelines(buffer)
+					defines.write(line)
+					buffer = []
+				else:
+					buffer = []
+
+def refpolicy2refpol(source, target):
+	if force:
+		rmtree(target, ignore_errors = True)
+
+	copytree(source, target)
+
+	# extract version for use with special modules
+	version = "0"
+	with open(target + "/VERSION") as f:
+		version = f.readline().strip()
+
+	for module in modules(target):
+		# convert to ref
+		refpol.itf_to_ref(module + ".if", module + ".te", module + ".fc", module + ".ref")
+
+		# remove old files
+		os.remove(module + ".if")
+		os.remove(module + ".te")
+		os.remove(module + ".fc")
+	
+	for special in specials(target):
+		name = os.path.basename(special).rsplit('.', 1)[0]
+		path = os.path.dirname(special) + "/_" + name + ".ref"
+		with open(path, "w") as new:
+			new.write("policy_module(%s, %s)\n\n" % (name, version))
+
+			with open(special, "r") as old:
+				copyfileobj(old, new)
+		os.remove(special)
+
+	for cnet in corenets(target):
+		corenet.itf_to_corenet(cnet + ".if.in",
+				       cnet + ".if.m4",
+				       cnet + ".te.in",
+				       cnet + ".te.m4",
+				       cnet + ".fc",
+				       cnet + ".corenet")
+
+		# remove old files
+		os.remove(cnet + ".if.in")
+		os.remove(cnet + ".if.m4")
+		os.remove(cnet + ".te.in")
+		os.remove(cnet + ".te.m4")
+		os.remove(cnet + ".fc")
+
+	# create _defines.ref
+	build_conf_to_defines(target + "/build.conf", target + "/_defines.ref", version)
+
+	# remove build.conf (will be created as part of build)
+	os.remove(target + "/build.conf")
+
+def create_ilc_environment(source, target):
+	if force:
+		rmtree(target, ignore_errors = True)
+
+	copytree(source, target, ignore = ignore_patterns("*.if", "*.te", "*.fc", "*.if.m4", "*.if.in", "*.te.m4", "*.te.in"))
+	for item in specials(target):
+		os.remove(item)
+	for item in discards(target):
+		rmtree(item, ignore_errors = True)
+	os.remove(target + "/build.conf")
+
+	# Create blank mls and mcs specials so that the build process
+	# does not complain when they are missing (i.e., _mls is disabled).
+	# These will get over written if the _mls/_mcs modules are installed.
+	open(target + "/policy/mls", "w").close()
+	open(target + "/policy/mcs", "w").close()
+
+usage = "%prog [OPTIONS] SOURCE TARGET"
+version = "%prog 1.0"
+
+def main():
+	# build cmdline parser
+	parser = OptionParser(usage = usage, version = version)
+	parser.add_option("-b", "--build", action = "store_true", default = False, dest = "build", help = "create the Refpol ILC build environment (default: False)")
+	parser.add_option("-f", "--force", action = "store_true", default = False, dest = "force", help = "force overwriting existing files")
+
+	# parse cmdline
+	(options, args) = parser.parse_args()
+
+	if len(args) != 2:
+		parser.error("Invalid number of arguments %d." % len(args))
+
+	force = options.force
+	source = args[0]
+	target = args[1]
+
+	if options.build:
+		create_ilc_environment(source, target)
+	else:
+		refpolicy2refpol(source, target)
+
+if __name__ == "__main__":
+	try:
+		main()
+	except Exception as e:
+		sys.stderr.write(sys.argv[0] + ": Error: " + str(e) + "\n")
+		sys.exit(1)
diff --git a/refpol/refpolicy2refpol.py b/refpol/refpolicy2refpol.py
new file mode 100755
index 0000000..bc908c3
--- /dev/null
+++ b/refpol/refpolicy2refpol.py
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+# Authors:	Caleb Case <ccase@tresys.com>
+#
+# Copyright (C) 2009-2010 Tresys Technology, LLC
+#      This program is free software; you can redistribute it and/or modify
+#      it under the terms of the Lesser GNU General Public License as 
+#      published by the Free Software Foundation, version 2.
+
+import refpol.refpolicy2refpol
+import sys
+
+try:
+	refpol.refpolicy2refpol.main()
+except Exception as e:
+	sys.stderr.write(sys.argv[0] + ": Error: " + str(e) + "\n")
+	sys.exit(1)
-- 
1.6.3.3


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 04/15] [src-policy] refpol intermediate language compiler (refpol_ilc)
  2010-01-26 22:08     ` [PATCH 03/15] [src-policy] Reference Policy to refpol conversion tool Caleb Case
@ 2010-01-26 22:08       ` Caleb Case
  2010-01-26 22:08         ` [PATCH 05/15] [src-policy] language.d and language.conf parser Caleb Case
  2010-01-28 21:03         ` [PATCH 04/15] [src-policy] refpol intermediate language compiler (refpol_ilc) James Carter
  0 siblings, 2 replies; 34+ messages in thread
From: Caleb Case @ 2010-01-26 22:08 UTC (permalink / raw)
  To: selinux; +Cc: csellers, kmacmillan, jwcart2, jbrindle, sds, Caleb Case

In the interim, before the completion of the proposed CIL[1], the
intermediate language will be a specialized version of refpol and the
Reference Policy build environment.

[refpol_ilc CIL Compiler]

The repfol intermediate language compiler (refpol_ilc) builds a binary
base module from refpol module.  Producing a binary base module allows
the existing libsemanage framework to continue to operate essentially as
it does today (load base module, apply database changes, create loadable
policy).

   Usage: refpol_ilc [OPTIONS] MODULE MODULE ...

   Options:
     --version             show program's version number and exit
     -h, --help            show this help message and exit
     -d FILE, --disabled=FILE
                           indicates module is disabled
     -f, --force           force overwriting existing files
     -t DIR, --tmp=DIR     temporary build directory
     -b DIR, --build-template=DIR
                           build template directory (Default:
                           /usr/share/selinux/refpol_ilc/build)
     -o FILE, --output=FILE
                           output file
     -c BOOL, --cleanup=BOOL
                           cleanup (remove) temporary directory (Default: True)

Note: The paths passed to the refpol_ilc need to be in the format of the
      semanage store in /var/lib/selinux. The refpol_ilc extracts the
      module name from the path. Future CIL will also likely extract the
      priority of the module from the path.

Example:

The compiles the moduless installed in the 'test' store into a base.pp:

# refpol_ilc `find /var/lib/selinux/test/active/modules/400/ -iname cil` > base.pp

[Compilation]

Compilation proceeds as follows:

  1. Copy build environment to temporary location.

     Note: refpol_ilc anticipates the build environment being installed
           to /usr/share/selinux/refpol_ilc/build by default.

  2. Install modules (see Special Modules and Normal Modules below).

  3. Create conf files.

  4. Set all modules to base or off as appropriate in modules.conf.

  5. Create base module (base.pp).

[Special Modules]

A number of modules are considered to be special and are installed into
special locations in the build environment:

   [Module Name]         [Reference Policy File]

   _constraints           policy/constraints
   _global_booleans       policy/global_booleans
   _global_tunables       policy/global_tunables
   _mcs                   policy/mcs
   _mls                   policy/mls
   _policy_capabilities   policy/policy_capabilities
   _rolemap               policy/rolemap
   _users                 policy/users
   _access_vectors        policy/flask/access_vectors
   _initial_sids          policy/flask/initial_sids
   _security_classes      policy/flask/security_classes
   _file_patterns         policy/support/file_patterns.spt
   _ipc_patterns          policy/support/ipc_patterns.spt
   _loadable_module       policy/support/loadable_module.spt
   _misc_macros           policy/support/misc_macros.spt
   _misc_patterns         policy/support/misc_patterns.spt
   _mls_mcs_macros        policy/support/mls_mcs_macros.spt
   _obj_perm_sets         policy/support/obj_perm_sets.spt

The build.conf file is handled with another special module _defines.
This module provides some of the variables for the traditional
build.conf with the remaining variables determined by the build
environment as follows:

   OUTPUT_POLICY   =>   Copied from _defines.
   TYPE            =>   Detect from the presence of the mls/mcs modules.
                        mls > mcs > none: meaning that if there is an
                        _mls module, then TYPE = mls, even if there is an
                        mcs module present.
   NAME            =>   Copied from _defines.
   DISTRO          =>   Copied from _defines.
   UNK_PERMS       =>   Copied from _defines.
   DIRECT_INITRC   =>   Copied from _defines.
   MONOLITHIC      =>   Fixed to 'n'.
   UBAC            =>   Copied from _defines.
   MLS_SENS        =>   Copied from _defines.
   MLS_CATS        =>   Copied from _defines.
   MCS_CATS        =>   Copied from _defines.
   QUIET           =>   Copied from _defines.

No other special modules are permitted. All special modules are
prepended with '_' to distinguish them from normal modules.

Note: The MLS/MCS/Standard setting of the policy is derived from the
      presense of the _mls or _mcs modules. It is no longer necessary to
      specify the policy type explicitly via the TYPE statement. This
      also allows policy type to be switched simply by enabling/disabled
      the _mls/_mcs modules.

[Normal Modules]

All normal (non-special) modules are copied to policy/modules/kernel/
and unpacked into the Reference Policy module 3 file format.

[1] CIL RFC: http://marc.info/?l=selinux&m=124759244409438&w=2
---
 Makefile                            |    2 +-
 refpol_ilc/COPYING                  |  504 +++++++++++++++++++++++++++++++++++
 refpol_ilc/Makefile                 |   24 ++
 refpol_ilc/refpol_ilc.py            |   17 ++
 refpol_ilc/refpol_ilc/refpol_ilc.py |  193 +++++++++++++
 refpol_ilc/setup.py                 |   13 +
 6 files changed, 752 insertions(+), 1 deletions(-)
 create mode 100644 refpol_ilc/COPYING
 create mode 100644 refpol_ilc/Makefile
 create mode 100755 refpol_ilc/refpol_ilc.py
 create mode 100644 refpol_ilc/refpol_ilc/__init__.py
 create mode 100644 refpol_ilc/refpol_ilc/refpol_ilc.py
 create mode 100755 refpol_ilc/setup.py

diff --git a/Makefile b/Makefile
index be2a4ec..afb4843 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-SUBDIRS=libsepol libselinux libsemanage sepolgen checkpolicy policycoreutils refpol corenet # policy
+SUBDIRS=libsepol libselinux libsemanage sepolgen checkpolicy policycoreutils refpol corenet refpol_ilc # policy
 PYSUBDIRS=libselinux libsemanage
 
 ifeq ($(DEBUG),1)
diff --git a/refpol_ilc/COPYING b/refpol_ilc/COPYING
new file mode 100644
index 0000000..8add30a
--- /dev/null
+++ b/refpol_ilc/COPYING
@@ -0,0 +1,504 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     51 Franklin St, 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.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, 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 library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+  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.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+  If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be 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.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+  9. 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 Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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 with
+this License.
+\f
+  11. 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 Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  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.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/refpol_ilc/Makefile b/refpol_ilc/Makefile
new file mode 100644
index 0000000..f6cdb14
--- /dev/null
+++ b/refpol_ilc/Makefile
@@ -0,0 +1,24 @@
+PREFIX ?= $(DESTDIR)/usr
+BINDIR ?= $(PREFIX)/bin
+
+PYTHON ?= python
+
+ifneq ($(origin DESTDIR), undefined)
+	PYDESTDIR ?= --root=$(DESTDIR)
+endif
+
+TARGET = refpol_ilc.py
+
+all:
+	$(PYTHON) setup.py build
+
+install:
+	$(PYTHON) setup.py install $(PYDESTDIR)
+	-mkdir -p $(BINDIR)
+	install -m 755 $(TARGET) $(BINDIR)/$(TARGET:.py=)
+
+clean distclean:
+	$(PYTHON) setup.py clean
+	rm -fr build
+	rm -f refpol_ilc/*.pyc
+
diff --git a/refpol_ilc/refpol_ilc.py b/refpol_ilc/refpol_ilc.py
new file mode 100755
index 0000000..31021b4
--- /dev/null
+++ b/refpol_ilc/refpol_ilc.py
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+# Authors:	Caleb Case <ccase@tresys.com>
+#
+# Copyright (C) 2009-2010 Tresys Technology, LLC
+#      This program is free software; you can redistribute it and/or modify
+#      it under the terms of the Lesser GNU General Public License as 
+#      published by the Free Software Foundation, version 2.
+
+import refpol_ilc.refpol_ilc
+import sys
+
+try:
+	refpol_ilc.refpol_ilc.main()
+except Exception as e:
+	sys.stderr.write(sys.argv[0] + ": Error: " + str(e) + "\n")
+	sys.exit(1)
diff --git a/refpol_ilc/refpol_ilc/__init__.py b/refpol_ilc/refpol_ilc/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/refpol_ilc/refpol_ilc/refpol_ilc.py b/refpol_ilc/refpol_ilc/refpol_ilc.py
new file mode 100644
index 0000000..7e5430e
--- /dev/null
+++ b/refpol_ilc/refpol_ilc/refpol_ilc.py
@@ -0,0 +1,193 @@
+#!/usr/bin/python
+
+# Authors:	Caleb Case <ccase@tresys.com>
+#
+# Copyright (C) 2009-2010 Tresys Technology, LLC
+#      This program is free software; you can redistribute it and/or modify
+#      it under the terms of the Lesser GNU General Public License as 
+#      published by the Free Software Foundation, version 2.
+
+from optparse import OptionParser, OptionGroup
+import os
+import os.path
+import tempfile
+from refpol import refpol
+from refpol import refpolicy2refpol
+import shutil
+import subprocess
+import sys
+
+build_directory = "/usr/share/selinux/refpol_ilc/build"
+
+# setup PATH (for gcc) if missing
+if not "PATH" in os.environ:
+	os.environ["PATH"] = "/bin:/usr/bin"
+
+def to_bool(str):
+	return 	{
+			"true"	: True,
+			"t"	: True,
+			"1"	: True,
+			"false"	: False,
+			"f"	: False,
+			"0"	: False,
+		}[str.lower()]
+
+usage = "%prog [OPTIONS] MODULE MODULE ..."
+version = "%prog 1.0"
+
+def main():
+	def disabled(option, opt_str, value, parser, *args, **kwargs):
+		parser.values.disabled.append(value)
+
+	# create cmdline parser
+	parser = OptionParser(usage = usage, version = version)
+	parser.add_option("-d", "--disabled", action = "callback", callback = disabled, type = "string", default = [], dest = "disabled", help = "indicates module is disabled", metavar = "FILE")
+	parser.add_option("-f", "--force", action = "store_true", default = False, dest = "force", help = "force overwriting existing files")
+	parser.add_option("-t", "--tmp", action = "store", default = None, dest = "tmp", help = "temporary build directory", metavar = "DIR")
+	parser.add_option("-b", "--build-template", action = "store", default = build_directory, dest = "build_template", help = "build template directory (Default: %s)" % build_directory, metavar = "DIR")
+	parser.add_option("-o", "--output", action = "store", default = None, dest = "output", help = "output file", metavar = "FILE")
+	parser.add_option("-c", "--cleanup", action = "store", default = "True", dest = "cleanup", help = "cleanup (remove) temporary directory (Default: True)", metavar = "BOOL")
+
+	# parse cmdline
+	(options, args) = parser.parse_args()
+	if len(args) <= 0:
+		parser.error("Invalid number of arguments %d." % len(args))
+
+	# save the working directory
+	saved_cwd = os.getcwd()
+
+	force = options.force
+	refpol.force = options.force
+	refpolicy2refpol.force = options.force
+
+	if options.output is None:
+		options.output = sys.stdout
+	else:
+		refpol.file_exists(options.output)
+		options.output = open(options.output, "w")
+
+	try:
+		if not options.tmp:
+			# create tmp build dir if one isn't provided
+			options.tmp = tempfile.mkdtemp("-refpol_ilc")
+		else:
+			shutil.rmtree(options.tmp, ignore_errors = True)
+			os.mkdir(options.tmp)
+
+		# copy build dir template
+		build_root = options.tmp + "/build"
+		shutil.copytree(options.build_template, build_root)
+
+		# set default policy TYPE
+		type = "standard"
+
+		# copy modules into build dir
+		special_names = dict(zip(["_" + os.path.basename(i).rsplit('.', 1)[0] for i in refpolicy2refpol.specials("")], refpolicy2refpol.specials(build_root)))
+		disabled_names = [os.path.basename(os.path.dirname(i)) for i in options.disabled]
+
+		all_modules = []
+		all_modules.extend(args)
+		all_modules.extend(options.disabled)
+		for path in all_modules:
+			module_name = os.path.basename(os.path.dirname(path))
+
+			if module_name in special_names and not module_name in disabled_names:
+				if module_name == "_mls":
+					type = "mls"
+				elif module_name == "_mcs" and type != "mls":
+					type = "mcs"
+
+				# copy to special location
+				with open(path, "r") as input:
+					with open(special_names[module_name], "w") as output:
+						for line in input:
+							# remove policy_module statement
+							if not line.strip().startswith("policy_module"):
+								output.write(line)
+			elif module_name == "_defines":
+				shutil.copy(path, build_root + "/_defines.ref")
+			else:
+				# copy module to policy/kernel/
+				dest_ref = build_root + "/policy/modules/kernel/" + module_name + ".ref"
+				dest_name = build_root + "/policy/modules/kernel/" + module_name
+				shutil.copy(path, dest_ref)
+				
+				refpol.ref_to_itf(dest_ref, dest_name + ".if", dest_name + ".te", dest_name + ".fc")
+
+		os.chdir(build_root)
+
+		# compose build.conf (build.conf.in from _defines.ref)
+		with open("_defines.ref", "r") as input:
+			with open("build.conf", "w") as output:
+				# write out the type
+				output.write("TYPE = %s\n\n" % type)
+
+				# write out monolithic
+				output.write("MONOLITHIC = n\n\n")
+
+				for line in input:
+					# remove policy_module statement
+					if not line.strip().startswith("policy_module"):
+						output.write(line)
+
+		# make conf
+		p = subprocess.Popen("make conf", shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE, close_fds = True)
+
+		(stdout, stderr) = p.communicate()
+		sys.stderr.write(stdout)
+		sys.stderr.write(stderr)
+
+		if p.returncode != 0:
+			raise Exception("Failed to run make conf (%d)." % p.returncode)
+
+		# sed modules.conf to base module if enabled
+		sed_cmd = "sed -i '1,/^END/{ s/= module/= base/; "
+		disabled_len = len(options.disabled)
+		if disabled_len > 0:
+			sed_cmd = sed_cmd + "s/\\("
+			i = 0
+			for d in options.disabled:
+				i = i + 1
+				sed_cmd = sed_cmd + os.path.basename(os.path.dirname(d))
+				if i != disabled_len:
+					sed_cmd = sed_cmd + "\\|"
+			sed_cmd = sed_cmd + "\\) = base/\\1 = off/ "
+		sed_cmd = sed_cmd + "}' policy/modules.conf"
+
+		p = subprocess.Popen(sed_cmd, shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE, close_fds = True)
+
+		(stdout, stderr) = p.communicate()
+		sys.stderr.write(stdout)
+		sys.stderr.write(stderr)
+
+		if p.returncode != 0:
+			raise Exception("Failed to modify modules.conf (%d)." % p.returncode)
+
+		# make base module
+		p = subprocess.Popen("make base.pp", shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE, close_fds = True)
+
+		(stdout, stderr) = p.communicate()
+		sys.stderr.write(stdout)
+		sys.stderr.write(stderr)
+
+		if p.returncode != 0:
+			raise Exception("Failed to run make base.pp (%d)." % p.returncode)
+
+		# output base module
+		options.output.write(open("base.pp", "r").read())
+	finally:
+		if to_bool(options.cleanup):
+			shutil.rmtree(options.tmp)
+
+		options.output.close()
+
+		# return the saved directory
+		os.chdir(saved_cwd)
+
+if __name__ == '__main__':
+	try:
+		main()
+	except Exception as e:
+		sys.stderr.write(sys.argv[0] + ": Error: " + str(e) + "\n")
+		sys.exit(1)
diff --git a/refpol_ilc/setup.py b/refpol_ilc/setup.py
new file mode 100755
index 0000000..31c3a14
--- /dev/null
+++ b/refpol_ilc/setup.py
@@ -0,0 +1,13 @@
+#!/usr/bin/python
+
+from distutils.core import setup
+
+setup(	name		= "refpol_ilc",
+	version		= "0.1",
+	description	= "Refpol Intermediate Language Compiler",
+#	url		= "",
+	author		= "Caleb Case",
+	author_email	= "ccase@tresys.com",
+	license		= "LGPL v2.1",
+	packages	= ['refpol_ilc'],
+	)
-- 
1.6.3.3


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 05/15] [src-policy] language.d and language.conf parser
  2010-01-26 22:08       ` [PATCH 04/15] [src-policy] refpol intermediate language compiler (refpol_ilc) Caleb Case
@ 2010-01-26 22:08         ` Caleb Case
  2010-01-26 22:08           ` [PATCH 06/15] [src-policy] libsemanage: compile hll module Caleb Case
  2010-01-28 21:03         ` [PATCH 04/15] [src-policy] refpol intermediate language compiler (refpol_ilc) James Carter
  1 sibling, 1 reply; 34+ messages in thread
From: Caleb Case @ 2010-01-26 22:08 UTC (permalink / raw)
  To: selinux; +Cc: csellers, kmacmillan, jwcart2, jbrindle, sds, Caleb Case

This patch provides support for language.conf. The language
configuration files indicate which compiler a high level language needs
for compilation to the intermediate language (e.g., corenet to refpol).
Each language.conf consists of the following:

NAME="Reference Policy"		# Human readable compiler name.
COMPILER="/usr/bin/refpolc"	# Path to the compiler.
EXTENSION="ref"			# Extension for this language (no dot).
FLAGS=""			# Any additional flags for the compiler.

Each compiler is expected to accept the high level language on stdin,
output the intermediate language on stdout, compilation log to stderr,
and the module version to fd 3. A non-zero exit status indicates an
error occured during compilation.

The language of a module is identified by matching its file extension to
one of the language configuration files. Each language.conf must specify
a _unique_ language extension for the language.
---
 libsemanage/src/Makefile             |   16 ++-
 libsemanage/src/handle.c             |   40 +++++-
 libsemanage/src/handle.h             |    7 +-
 libsemanage/src/lang-parse.y         |  271 ++++++++++++++++++++++++++++++++++
 libsemanage/src/lang-scan.l          |   84 +++++++++++
 libsemanage/src/semanage_lang_conf.h |   39 +++++
 libsemanage/src/semanage_store.c     |   11 ++-
 libsemanage/src/semanage_store.h     |    3 +-
 8 files changed, 463 insertions(+), 8 deletions(-)
 create mode 100644 libsemanage/src/lang-parse.y
 create mode 100644 libsemanage/src/lang-scan.l
 create mode 100644 libsemanage/src/semanage_lang_conf.h

diff --git a/libsemanage/src/Makefile b/libsemanage/src/Makefile
index 67afc60..42ee9d6 100644
--- a/libsemanage/src/Makefile
+++ b/libsemanage/src/Makefile
@@ -43,8 +43,8 @@ LIBSO=$(TARGET).$(LIBVERSION)
 SWIGGEN=$(SWIGCOUT) $(SWIGRUBYCOUT)
 SRCS= $(filter-out $(SWIGGEN),$(wildcard *.c))
 
-OBJS= $(patsubst %.c,%.o,$(SRCS)) conf-scan.o conf-parse.o
-LOBJS= $(patsubst %.c,%.lo,$(SRCS)) conf-scan.lo conf-parse.lo
+OBJS= $(patsubst %.c,%.o,$(SRCS)) conf-scan.o conf-parse.o lang-scan.o lang-parse.o
+LOBJS= $(patsubst %.c,%.lo,$(SRCS)) conf-scan.lo conf-parse.lo lang-scan.lo lang-parse.lo
 CFLAGS ?= -Wall -W -Wundef -Wshadow -Wmissing-noreturn -Wmissing-format-attribute -Wno-unused-parameter
 
 override CFLAGS += -I../include -I$(INCLUDEDIR) -D_GNU_SOURCE 
@@ -53,7 +53,7 @@ SWIG = swig -Wall -python -o $(SWIGCOUT) -outdir ./
 
 SWIGRUBY = swig -Wall -ruby -o $(SWIGRUBYCOUT) -outdir ./
 
-GENERATED=$(SWIGCOUT) $(SWIGRUBYCOUT) $(wildcard conf-*.[ch])
+GENERATED=$(SWIGCOUT) $(SWIGRUBYCOUT) $(wildcard conf-*.[ch]) $(wildcard lang-*.[ch])
 
 all: $(LIBA) $(LIBSO) $(LIBPC)
 
@@ -92,6 +92,14 @@ conf-parse.c: conf-parse.y
 
 conf-parse.h: conf-parse.c
 
+lang-scan.c: lang-scan.l lang-parse.h
+	$(LEX) $(LFLAGS) -t $< > $@
+
+lang-parse.c: lang-parse.y
+	$(YACC) $(YFLAGS) -o $@ $<
+
+lang-parse.h: lang-parse.c
+
 %.o:  %.c 
 	$(CC) $(CFLAGS) -c -o $@ $<
 
@@ -141,7 +149,7 @@ relabel:
 	/sbin/restorecon $(SHLIBDIR)/$(LIBSO)
 
 clean: 
-	rm -f $(LIBPC) $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) $(TARGET) conf-parse.c conf-parse.h conf-scan.c
+	rm -f $(LIBPC) $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) $(TARGET) conf-parse.c conf-parse.h conf-scan.c lang-parse.c lang-parse.h lang-scan.c
 
 distclean: clean
 	rm -f $(SWIGCOUT) $(SWIGFILES)
diff --git a/libsemanage/src/handle.c b/libsemanage/src/handle.c
index 8300cae..71c3165 100644
--- a/libsemanage/src/handle.c
+++ b/libsemanage/src/handle.c
@@ -1,7 +1,7 @@
 /* Author: Joshua Brindle <jbrindle@tresys.co
  *	   Jason Tang	  <jtang@tresys.com>
  *
- * Copyright (C) 2004-2005 Tresys Technology, LLC
+ * Copyright (C) 2004-2005,2010 Tresys Technology, LLC
  * Copyright (C) 2005 Red Hat, Inc.
  * 
  *  This library is free software; you can redistribute it and/or
@@ -42,6 +42,7 @@ semanage_handle_t *semanage_handle_create(void)
 {
 	semanage_handle_t *sh = NULL;
 	const char *conf_name = NULL;
+	const char *lang_conf_path = NULL;
 
 	/* Allocate handle */
 	if ((sh = calloc(1, sizeof(semanage_handle_t))) == NULL)
@@ -53,6 +54,13 @@ semanage_handle_t *semanage_handle_create(void)
 	if ((sh->conf = semanage_conf_parse(conf_name)) == NULL)
 		goto err;
 
+	if ((lang_conf_path = semanage_lang_conf_path()) == NULL)
+		goto err;
+
+	sh->lang_conf_list = semanage_lang_conf_parse(lang_conf_path);
+	if (sh->lang_conf_list == NULL)
+		goto err;
+
 	/* Link to sepol handle */
 	sh->sepolh = sepol_handle_create();
 	if (!sh->sepolh)
@@ -160,6 +168,26 @@ int semanage_set_default_priority(semanage_handle_t *sh, uint16_t priority)
 	return 0;
 }
 
+const semanage_lang_conf_t *semanage_get_lang_conf(semanage_handle_t *sh,
+						   const char *lang_ext)
+{
+	assert(sh != NULL);
+	assert(lang_ext != NULL);
+
+	semanage_lang_conf_t *conf = NULL;
+
+	semanage_lang_conf_list_t *item = sh->lang_conf_list;
+	while (item != NULL) {
+		if (strcmp(item->data->ext, lang_ext) == 0) {
+			conf = item->data;
+			break;
+		}
+		item = item->next;
+	}
+	
+	return conf;
+}
+
 int semanage_is_connected(semanage_handle_t * sh)
 {
 	assert(sh != NULL);
@@ -271,6 +299,16 @@ void semanage_handle_destroy(semanage_handle_t * sh)
 
 	if (sh->funcs != NULL && sh->funcs->destroy != NULL)
 		sh->funcs->destroy(sh);
+
+	semanage_lang_conf_list_t *head = sh->lang_conf_list;
+	semanage_lang_conf_list_t *next = NULL;
+	while (head != NULL) {
+		next = head->next;
+		semanage_lang_conf_destroy(head->data);
+		free(head);
+		head = next;
+	}
+
 	semanage_conf_destroy(sh->conf);
 	sepol_handle_destroy(sh->sepolh);
 	free(sh);
diff --git a/libsemanage/src/handle.h b/libsemanage/src/handle.h
index 64175c4..0f8794a 100644
--- a/libsemanage/src/handle.h
+++ b/libsemanage/src/handle.h
@@ -2,7 +2,7 @@
  *         Jason Tang     <jtang@tresys.com>
  *         Ivan Gyurdiev  <ivg2@cornell.edu>
  *           
- * Copyright (C) 2005 Tresys Technology, LLC
+ * Copyright (C) 2005,2010 Tresys Technology, LLC
  * Copyright (C) 2005 Red Hat Inc.
  *
  *  This library is free software; you can redistribute it and/or
@@ -29,6 +29,7 @@
 #include <sepol/handle.h>
 #include "modules.h"
 #include "semanage_conf.h"
+#include "semanage_lang_conf.h"
 #include "database.h"
 #include "direct_api.h"
 #include "policy.h"
@@ -56,6 +57,7 @@ struct semanage_handle {
 	sepol_handle_t *sepolh;
 
 	semanage_conf_t *conf;
+	semanage_lang_conf_list_t *lang_conf_list;
 
 	uint16_t priority;
 	int is_connected;
@@ -226,4 +228,7 @@ static inline
 	return &handle->dbase[DBASE_ACTIVE_BOOLEANS];
 }
 
+const semanage_lang_conf_t *semanage_get_lang_conf(semanage_handle_t *sh,
+						   const char *lang_ext);
+
 #endif
diff --git a/libsemanage/src/lang-parse.y b/libsemanage/src/lang-parse.y
new file mode 100644
index 0000000..12a1090
--- /dev/null
+++ b/libsemanage/src/lang-parse.y
@@ -0,0 +1,271 @@
+/* Authors: Mark Goldman   <mgoldman@tresys.com>
+ *          Caleb Case     <ccase@tresys.com>
+ *
+ * Copyright (C) 2009-2010 Tresys Technology, LLC
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License.
+ *
+ *  This library 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+%{
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+
+#include "semanage_lang_conf.h"
+#include "debug.h"
+
+extern int semanage_lang_lex();                /* defined in lang-scan.c */
+int semanage_lang_error(char *msg);
+
+extern FILE *semanage_lang_in;
+extern char *semanage_lang_text;
+
+static semanage_lang_conf_t *lang_conf;
+static int parse_errors;
+
+%}
+
+%name-prefix="semanage_lang_"
+
+%union {
+        char *s;
+}
+
+%token NAME EXTENSION COMPILER FLAGS
+%token <s> ARG
+
+%%
+
+config_file:    config_line config_file
+        |       /* empty */
+        ;
+
+config_line: name_line
+	   | ext_line
+	   | comp_line
+	   | flags_line
+        ;
+
+name_line: NAME '=' ARG {
+		if ($3 == NULL) {
+			parse_errors++;
+			YYABORT;
+		}
+		lang_conf->name = $3;
+		if (lang_conf->name == NULL) {
+			parse_errors++;
+			YYABORT;
+		}
+	 }
+	 ;
+
+ext_line: EXTENSION '=' ARG {
+		if ($3 == NULL) {
+			parse_errors++;
+			YYABORT;
+		}
+		lang_conf->ext = $3;
+		if (lang_conf->ext == NULL) {
+			parse_errors++;
+			YYABORT;
+		}
+	}
+	;
+
+comp_line: COMPILER '=' ARG {
+		if ($3 == NULL) {
+			parse_errors++;
+			YYABORT;
+		}
+		lang_conf->compiler = $3;
+		if (lang_conf->compiler == NULL) {
+			parse_errors++;
+			YYABORT;
+		}
+	 }
+	 ;
+
+flags_line: FLAGS '=' ARG {
+		if ($3 == NULL) {
+			$3 = strdup("");
+		}
+		lang_conf->flags = $3;
+		if (lang_conf->flags == NULL) {
+			parse_errors++;
+			YYABORT;
+		}
+	  }
+	  ;
+
+%%
+
+static int semanage_lang_conf_init(semanage_lang_conf_t *conf)
+{
+	conf->name = NULL;
+	conf->ext = NULL;
+	conf->compiler = NULL;
+	conf->flags = NULL;
+
+	return STATUS_SUCCESS;
+}
+
+void semanage_lang_conf_destroy(semanage_lang_conf_t *conf)
+{
+	if (conf != NULL) {
+		free(conf->name);
+		free(conf->ext);
+		free(conf->compiler);
+		free(conf->flags);
+		free(conf);
+	}
+}
+
+int semanage_lang_conf_check(semanage_lang_conf_t *conf)
+{
+	if (	conf->name != NULL &&
+		conf->ext != NULL &&
+		conf->compiler != NULL &&
+		conf->flags != NULL) {
+
+		return STATUS_SUCCESS;
+	}
+	return STATUS_ERR;
+}
+
+int semanage_lang_error(char *msg)
+{
+	fprintf(stderr, "error parsing semanage language configuration file: %s\n", msg);
+	parse_errors++;
+	return 0;
+}
+
+static semanage_lang_conf_t *semanage_lang_conf_parse_file(const char *fullpath)
+{
+	int status = 0;
+
+	lang_conf = malloc(sizeof(*lang_conf));
+	if (lang_conf == NULL) goto err;
+
+	status = semanage_lang_conf_init(lang_conf);
+	if (status != 0) goto err;
+
+	semanage_lang_in = fopen(fullpath, "r");
+	if (semanage_lang_in == NULL) goto err;
+
+	parse_errors = 0;
+	semanage_lang_parse();
+
+	fclose(semanage_lang_in);
+
+	if (parse_errors != 0) {
+		goto err;
+	}
+
+	status = semanage_lang_conf_check(lang_conf);
+	if (status != 0) goto err;
+
+	return lang_conf;
+err:
+	semanage_lang_conf_destroy(lang_conf);
+
+	return NULL;
+}
+
+static int ignore_hidden(const struct dirent *dent)
+{
+	if (dent->d_name[0] == '.') return 0;
+	return 1;
+}
+
+/* Parse a libsemanage language configuration file.  THIS FUNCTION IS NOT
+ * THREAD-SAFE!	 Return a newly allocated semanage_lang_conf_t *.
+ * If the file could not be parsed correctly or if out of memory return NULL.
+ */
+semanage_lang_conf_list_t *semanage_lang_conf_parse(const char *path)
+{
+	int status = 0;
+	int cnt = 0;
+	int i = 0;
+	semanage_lang_conf_list_t *head = NULL;
+	semanage_lang_conf_list_t *tail = NULL;
+	semanage_lang_conf_list_t *next = NULL;
+	char fullpath[PATH_MAX];
+	struct stat sb;
+	struct dirent **names = NULL;
+	semanage_lang_conf_t *conf = NULL;
+
+	/* get directory entries */
+	status = scandir(path, &names, ignore_hidden, alphasort);
+	if (status < 0) goto err;
+	cnt = status;
+
+	/* parse each of the langauge confs */
+	for (i = cnt - 1; i >= 0; i--) {
+
+		/* get the full path */
+		snprintf(fullpath, sizeof(fullpath), "%s/%s", path, names[i]->d_name);
+		if (stat(fullpath, &sb)) goto err;
+
+		/* only look at regular files */
+		if (!S_ISREG(sb.st_mode)) continue;
+
+		/* parse the file */
+		conf = semanage_lang_conf_parse_file(fullpath);
+		if (conf == NULL) goto err;
+
+		/* create the list entry */
+		next = malloc(sizeof(semanage_lang_conf_list_t));
+		if (next == NULL) {
+			semanage_lang_conf_destroy(conf);
+			goto err;
+		}
+
+		if (head == NULL) {
+			head = next;
+		}
+
+		/* append */
+		next->data = conf;
+		next->next = NULL;
+
+		if (tail != NULL) {
+			tail->next = next;
+		}
+		tail = next;
+        }
+
+	goto ok;
+err:
+	while (head != NULL) {
+		next = head->next;
+		semanage_lang_conf_destroy(head->data);
+		free(head);
+		head = next;
+	}
+
+ok:
+	if (names != NULL) {
+		for (i = cnt - 1; i >= 0; i--) {
+			free(names[i]);
+		}
+	}
+	free(names);
+
+	return head;
+}
+
diff --git a/libsemanage/src/lang-scan.l b/libsemanage/src/lang-scan.l
new file mode 100644
index 0000000..085ceae
--- /dev/null
+++ b/libsemanage/src/lang-scan.l
@@ -0,0 +1,84 @@
+/* Authors: Jason Tang     <jtang@tresys.com>
+ *          James Athey    <jathey@tresys.com>
+ *          Mark Goldman   <mgoldman@tresys.com>
+ *          Caleb Case     <ccase@tresys.com>
+ *
+ * Copyright (C) 2004-2006,2009-2010 Tresys Technology, LLC
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+%{
+#include "lang-parse.h"
+
+#include <ctype.h>
+#include <string.h>
+
+static char *my_strdup (char * s);
+static char *my_qstrdup (char * s);
+
+int yywrap(void);
+ 
+%}
+
+%option stack prefix="semanage_lang_"
+%option noinput nounput noyy_push_state noyy_pop_state noyy_top_state
+
+%x arg
+
+%%
+
+#.*               /* ignore comments */
+NAME		return NAME;
+COMPILER	return COMPILER;
+EXTENSION	return EXTENSION;
+FLAGS		return FLAGS;
+[ \t]*=[ \t]*     BEGIN arg; return '=';
+[ \t\n]+          /* ignore */
+.                 return semanage_lang_text[0];
+<arg>\"\"         BEGIN INITIAL; semanage_lang_lval.s = NULL; return ARG;
+<arg>\".+\"       BEGIN INITIAL; semanage_lang_lval.s = my_qstrdup(semanage_lang_text); return ARG;
+<arg>.*[^\"\n]    BEGIN INITIAL; semanage_lang_lval.s = my_strdup(semanage_lang_text); return ARG;
+<arg>.|\n         BEGIN INITIAL; semanage_lang_lval.s = NULL; return ARG;
+
+%%
+
+int yywrap(void) {
+	return 1;
+}
+
+/* Like strdup(), but also trim leading and trailing whitespace.
+ * Returns NULL on error. */
+static char *my_strdup(char *s) {
+	char *t;
+	while (isspace(*s)) {
+		s++;
+	}
+	t = s + strlen(s) - 1;
+	while (t >= s && isspace(*t)) {
+		*t = '\0';
+		t--;
+	}
+	return strdup(s);
+}
+
+/* strdup() a string sans initial and trailing characters.  Does /not/
+ * trim any whitespace.	 Returns NULL on error. */
+static char *my_qstrdup(char *s) {
+	s++;
+	s[strlen(s) - 1] = '\0';
+	return strdup(s);
+}
+
diff --git a/libsemanage/src/semanage_lang_conf.h b/libsemanage/src/semanage_lang_conf.h
new file mode 100644
index 0000000..9af1d54
--- /dev/null
+++ b/libsemanage/src/semanage_lang_conf.h
@@ -0,0 +1,39 @@
+/* Authors: Mark Goldman <mgoldman@tresys.com>
+ *          Caleb Case   <ccase@tresys.com>
+ *
+ * Copyright (C) 2009-2010 Tresys Technology, LLC
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License.
+ *
+ *  This library 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef SEMANAGE_LANG_CONF_H
+#define SEMANAGE_LANG_CONF_H
+
+typedef struct semanage_lang_conf {
+	char *name;
+	char *ext;
+	char *compiler;
+	char *flags;
+} semanage_lang_conf_t;
+
+typedef struct semanage_lang_conf_list {
+	semanage_lang_conf_t *data;
+	struct semanage_lang_conf_list *next;
+} semanage_lang_conf_list_t;
+
+semanage_lang_conf_list_t *semanage_lang_conf_parse(const char *config_filename);
+void semanage_lang_conf_destroy(semanage_lang_conf_t *conf);
+
+#endif
diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
index f077ac3..2bda1e2 100644
--- a/libsemanage/src/semanage_store.c
+++ b/libsemanage/src/semanage_store.c
@@ -5,7 +5,7 @@
  *          Chris PeBenito <cpebenito@tresys.com>
  *	    Caleb Case <ccase@tresys.com>
  *
- * Copyright (C) 2004-2006,2009 Tresys Technology, LLC
+ * Copyright (C) 2004-2006,2009-2010 Tresys Technology, LLC
  * Copyright (C) 2005 Red Hat, Inc.
  *
  *  This library is free software; you can redistribute it and/or
@@ -492,6 +492,15 @@ const char *semanage_conf_path(void)
 	return "/etc/selinux/semanage.conf";
 }
 
+/* Return a fully-qualified path + filename to the semanage language
+ * configuration files.  The caller must not alter the string returned
+ * (and hence why this function return type is const).
+ */
+const char *semanage_lang_conf_path(void)
+{
+	return "/etc/selinux/language.d";
+}
+
 /* Locates the highest priority enabled base module
  * and fills @path in with that value. @path must be
  * pre-allocated with size @len.
diff --git a/libsemanage/src/semanage_store.h b/libsemanage/src/semanage_store.h
index 16148ef..4ad0b21 100644
--- a/libsemanage/src/semanage_store.h
+++ b/libsemanage/src/semanage_store.h
@@ -3,7 +3,7 @@
  *	    Jason Tang <jtang@tresys.com>
  *	    Christopher Ashworth <cashworth@tresys.com>
  *
- * Copyright (C) 2004-2006 Tresys Technology, LLC
+ * Copyright (C) 2004-2006,2010 Tresys Technology, LLC
  * Copyright (C) 2005 Red Hat, Inc.
  *
  *  This library is free software; you can redistribute it and/or
@@ -79,6 +79,7 @@ const char *semanage_root_path(void);
  * global configuration moved to another file.
  */
 const char *semanage_conf_path(void);
+const char *semanage_lang_conf_path(void);
 
 int semanage_check_init(semanage_handle_t *sh, const char *prefix);
 
-- 
1.6.3.3


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 06/15] [src-policy] libsemanage: compile hll module
  2010-01-26 22:08         ` [PATCH 05/15] [src-policy] language.d and language.conf parser Caleb Case
@ 2010-01-26 22:08           ` Caleb Case
  2010-01-26 22:08             ` [PATCH 07/15] [src-policy] libsemanage: compile common intermediary language Caleb Case
  2010-01-27 20:18             ` [PATCH 06/15] [src-policy] libsemanage: compile hll module Stephen Smalley
  0 siblings, 2 replies; 34+ messages in thread
From: Caleb Case @ 2010-01-26 22:08 UTC (permalink / raw)
  To: selinux; +Cc: csellers, kmacmillan, jwcart2, jbrindle, sds, Caleb Case

This provides the basic compilation function semanage_compile_hll that
is called during module installation. semanage_exec is a helper function
which sets up the redirected io for the child process, executes it,
waits for the child to exit, and then propagates the child's exit
status. An additional helper function semanage_fd_to_data reads a given
file descriptor into a buffer (unzipping it if necessary). The
compilation messages are stored in
/var/lib/selinux/.../modules/<priority>/<module>/log.
---
 libsemanage/src/direct_api.c     |    9 +-
 libsemanage/src/modules.c        |    7 +-
 libsemanage/src/modules.h        |    3 +-
 libsemanage/src/semanage_store.c |  354 ++++++++++++++++++++++++++++++++++++++
 libsemanage/src/semanage_store.h |   29 +++
 5 files changed, 398 insertions(+), 4 deletions(-)

diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index 9bbe96d..61e5b92 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -1,7 +1,7 @@
 /* Author: Jason Tang	  <jtang@tresys.com>
  *         Christopher Ashworth <cashworth@tresys.com>
  *
- * Copyright (C) 2004-2006 Tresys Technology, LLC
+ * Copyright (C) 2004-2006,2010 Tresys Technology, LLC
  * Copyright (C) 2005 Red Hat, Inc.
  * 
  *  This library is free software; you can redistribute it and/or
@@ -2486,6 +2486,13 @@ static int semanage_direct_install_info(semanage_handle_t *sh,
 		goto cleanup;
 	}
 
+	/* compile hll to cil */
+	ret = semanage_compile_hll(sh, modinfo);
+	if (ret != 0) {
+		status = -3;
+		goto cleanup;
+	}
+
 cleanup:
 	semanage_module_key_destroy(sh, &higher_key);
 	semanage_module_info_destroy(sh, higher_info);
diff --git a/libsemanage/src/modules.c b/libsemanage/src/modules.c
index 6f6f8b1..be30517 100644
--- a/libsemanage/src/modules.c
+++ b/libsemanage/src/modules.c
@@ -2,7 +2,7 @@
  *	   Jason Tang	  <jtang@tresys.com>
  *	   Caleb Case	  <ccase@tresys.com>
  *
- * Copyright (C) 2004-2005,2009 Tresys Technology, LLC
+ * Copyright (C) 2004-2005,2009-2010 Tresys Technology, LLC
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -666,6 +666,8 @@ int semanage_module_get_path(semanage_handle_t *sh,
 			if (file == NULL) file = "lang_ext";
 		case SEMANAGE_MODULE_PATH_VERSION:
 			if (file == NULL) file = "version";
+		case SEMANAGE_MODULE_PATH_LOG:
+			if (file == NULL) file = "log";
 
 			/* verify priority and name */
 			ret = semanage_module_validate_priority(modinfo->priority);
@@ -989,10 +991,11 @@ int semanage_module_validate_name(const char * name)
 	}
 
 	if (strcmp(name, "_base") == 0) {
+		status = -1;
 		goto exit;
 	}
 
-	if (!isalpha(*name)) {
+	if (!isalpha(*name) && *name != '_') {
 		status = -1;
 		goto exit;
 	}
diff --git a/libsemanage/src/modules.h b/libsemanage/src/modules.h
index 38e1e0c..3d2cc1a 100644
--- a/libsemanage/src/modules.h
+++ b/libsemanage/src/modules.h
@@ -2,7 +2,7 @@
  *         Jason Tang     <jtang@tresys.com>
  *         Caleb Case     <ccase@tresys.com>
  *
- * Copyright (C) 2005,2009 Tresys Technology, LLC
+ * Copyright (C) 2005,2009-2010 Tresys Technology, LLC
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -86,6 +86,7 @@ enum semanage_module_path_type {
 	SEMANAGE_MODULE_PATH_LANG_EXT,
 	SEMANAGE_MODULE_PATH_VERSION,
 	SEMANAGE_MODULE_PATH_DISABLED,
+	SEMANAGE_MODULE_PATH_LOG,
 };
 
 /* Get the module path for the given path @type.
diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
index 2bda1e2..dd96a75 100644
--- a/libsemanage/src/semanage_store.c
+++ b/libsemanage/src/semanage_store.c
@@ -3034,3 +3034,357 @@ int semanage_nc_sort(semanage_handle_t * sh, const char *buf, size_t buf_len,
 
 	return 0;
 }
+
+/* Execute @cmd with @args and redirect the @io.
+ *
+ * @io is an array of fd's to redirect. Indices correspond to fds. The fds
+ * are not closed. Indices set to -1 are ignored, otherwise they are
+ * dup2'd.
+ *
+ * Returns:
+ * 	 0	success
+ * 	-1	failure, error outside HLL compiler
+ * 	+N	failure, HLL compiler exit status N
+ */
+static int semanage_exec(semanage_handle_t *sh,
+			 const char *cmd,
+			 char *argv[],
+			 int io[],
+			 int io_len)
+{
+	int status = 0;
+	int ret = 0;
+
+	char *env[] = { NULL };
+
+	ret = fork();
+	if (ret < 0) {
+		ERR(sh, "Failed to fork");
+		status = -1;
+		goto cleanup;
+	}
+
+	if (ret == 0) {		/* child */
+		int i;
+		for (i = 0; i < io_len; i++) {
+			if (io[i] >= 0) {
+				ret = dup2(io[i], i);
+				if (ret < 0) {
+					exit(EXIT_FAILURE);
+				}
+			}
+		}
+
+		execve(cmd, argv, env);
+
+		/* If we made it here, then something bad happened. */
+		ERR(sh, "Failed to execute %s.", cmd);
+		exit(EXIT_FAILURE);
+	}
+	else {			/* parent */
+		ret = wait(&status);
+		if (ret < 0) {
+			status = -1;
+			goto cleanup;
+		}
+
+		if (WIFEXITED(status)) {
+			status = WEXITSTATUS(status);
+		}
+		else {
+			status = -1;
+		}
+	}
+
+cleanup:
+	if (status != 0) {
+		ERR(sh, "Failed to execute %s (exit status %d).", cmd, status);
+	}
+
+	return status;
+}
+
+int semanage_fd_to_data(semanage_handle_t *sh,
+			int fd,
+			char **data,
+			size_t *data_len)
+{
+	assert(sh);
+	assert(data);
+	assert(data_len);
+
+	int status = 0;
+	int ret = 0;
+
+	*data = NULL;
+	*data_len = 0;
+
+	FILE *fp = NULL;
+	struct stat sb;
+	sb.st_size = 0;
+	ssize_t nread = 0;
+	char *data_tmp = NULL;
+
+	/* Find out how big it is. */
+	ret = fstat(fd, &sb);
+	if (ret != 0) {
+		ERR(sh, "Failed to stat file");
+		status = -2;
+		goto cleanup;
+	}
+	*data_len = sb.st_size;
+
+	/* Allocate a buffer for the file. */
+	*data = malloc(*data_len + 1);
+	if (*data == NULL) {
+		ERR(sh, "Out of memory!");
+		status = -1;
+		goto cleanup;
+	}
+	(*data)[*data_len] = '\0';
+
+	/* Read into the buffer. */
+	while((size_t)nread != *data_len) {
+		nread = read(fd, *data + nread, *data_len - nread);
+		if (nread < 0) {
+			ERR(sh, "Failed to read the file");
+			status = -1;
+			goto cleanup;
+		}
+	}
+
+	/* Try to bunzip. */
+	fp = fmemopen(*data, *data_len, "r");
+	if (fp == NULL) {
+		ERR(sh, "Failed to open file for reading");
+		status = -1;
+		goto cleanup;
+	}
+
+	nread = bunzip(sh, fp, &data_tmp);
+	if (nread > 0) {
+		free(*data);
+		*data = data_tmp;
+		*data_len = (size_t)nread;
+	}
+
+cleanup:
+	if (status != 0) {
+		free(*data);
+		*data = NULL;
+		*data_len = 0;
+	}
+
+	if (fp != NULL) fclose(fp);
+
+	return status;
+}
+
+int semanage_compile_hll(semanage_handle_t *sh,
+			 const semanage_module_info_t *modinfo)
+{
+	int status = 0;
+	int ret = 0;
+
+	char hll_path[PATH_MAX];
+	char cil_path[PATH_MAX];
+	char ver_path[PATH_MAX];
+	char log_path[PATH_MAX];
+
+	char tmp[] = "/tmp/libsemanage-XXXXXX";
+	int tmp_fd = -1;
+	ssize_t nwrite = 0;
+
+	int io[4];
+	int io_len = 4;
+
+	const semanage_lang_conf_t *conf = NULL;
+
+	int i;
+
+	char **argv = NULL;
+
+	char *data = NULL;
+	size_t data_len = 0;
+
+	/* determine paths and setup io:
+	 *
+	 * 0	hll
+	 * 1	cil
+	 * 2	log
+	 * 3	version
+	 */
+
+	/* 0	hll */
+	ret = semanage_module_get_path(sh,
+				       modinfo,
+				       SEMANAGE_MODULE_PATH_HLL,
+				       hll_path,
+				       sizeof(hll_path));
+	if (ret != 0) {
+		status = -1;
+		goto cleanup;
+	}
+
+	/* open hll, read in (which will bunzip if necessary) */
+	tmp_fd = open(hll_path, O_RDONLY);
+	if (tmp_fd < 0) {
+		ERR(sh, "Failed to open %s", hll_path);
+		status = -1;
+		goto cleanup;
+	}
+
+	ret = semanage_fd_to_data(sh, tmp_fd, &data, &data_len);
+	if (ret != 0) {
+		ERR(sh, "Failed to read %s", hll_path);
+		status = -1;
+		goto cleanup;
+	}
+
+	close(tmp_fd);
+	tmp_fd = mkstemp(tmp);
+	if (tmp_fd < 0) {
+		ERR(sh,
+		    "Failed to create tmp file for module %s.",
+		    modinfo->name);
+		status = -1;
+		goto cleanup;
+	}
+
+	while((size_t)nwrite != data_len) {
+		nwrite = write(tmp_fd, data + nwrite, data_len - nwrite);
+		if (nwrite < 0) {
+			ERR(sh,
+			    "Failed to write data to tmp file for module %s.",
+			    modinfo->name);
+			status = -1;
+			goto cleanup;
+		}
+	}
+
+	ret = fsync(tmp_fd);
+	if (ret != 0) {
+		ERR(sh,
+		    "Failed to write data to tmp file for module %s.",
+		    modinfo->name);
+		status = -1;
+		goto cleanup;
+	}
+	close(tmp_fd);
+	tmp_fd = -1;
+
+	io[0] = open(tmp, O_RDONLY);
+	if (io[0] < 0) {
+		ERR(sh, "Failed to open tmp file %s", tmp);
+		status = -1;
+		goto cleanup;
+	}
+
+	/* 1	cil */
+	ret = semanage_module_get_path(sh,
+				       modinfo,
+				       SEMANAGE_MODULE_PATH_CIL,
+				       cil_path,
+				       sizeof(cil_path));
+	if (ret != 0) {
+		status = -1;
+		goto cleanup;
+	}
+
+	io[1] = creat(cil_path, S_IRUSR | S_IWUSR);
+	if (io[1] < 0) {
+		ERR(sh, "Failed to create %s", cil_path);
+		status = -1;
+		goto cleanup;
+	}
+
+	/* 2	log */
+	ret = semanage_module_get_path(sh,
+				       modinfo,
+				       SEMANAGE_MODULE_PATH_LOG,
+				       log_path,
+				       sizeof(log_path));
+	if (ret != 0) {
+		status = -1;
+		goto cleanup;
+	}
+
+	io[2] = creat(log_path, S_IRUSR | S_IWUSR);
+	if (io[2] < 0) {
+		ERR(sh, "Failed to create %s", log_path);
+		status = -1;
+		goto cleanup;
+	}
+
+	/* 3	version */
+	ret = semanage_module_get_path(sh,
+				       modinfo,
+				       SEMANAGE_MODULE_PATH_VERSION,
+				       ver_path,
+				       sizeof(ver_path));
+	if (ret != 0) {
+		status = -1;
+		goto cleanup;
+	}
+
+	io[3] = creat(ver_path, S_IRUSR | S_IWUSR);
+	if (io[3] < 0) {
+		ERR(sh, "Failed to create %s", ver_path);
+		status = -1;
+		goto cleanup;
+	}
+
+	/* get the lang conf for this language */
+	conf = semanage_get_lang_conf(sh, modinfo->lang_ext);
+	if (conf == NULL) {
+		status = -1;
+		goto cleanup;
+	}
+
+	/* setup argv */
+	argv = split_args(conf->compiler, conf->flags, "", "");
+	if (argv == NULL) {
+		ERR(sh, "Out of memory!");
+		status = -1;
+		goto cleanup;
+	}
+
+	/* exec the hll compiler */
+	status = semanage_exec(sh, conf->compiler, argv, io, io_len);
+	if (status > 0) {
+		ret = fsync(io[2]);
+		if (ret != 0) {
+			WARN(sh, "Failed to sync log to disk!");
+		}
+		close(io[2]);
+
+		io[2] = open(log_path, O_RDONLY);
+		if (io[2] < 0) {
+			ERR(sh, "Failed to open log file.");
+			goto cleanup;
+		}
+
+		ret = semanage_fd_to_data(sh, io[2], &data, &data_len);
+		if (ret != 0) {
+			ERR(sh, "Failed to read log.");
+			goto cleanup;
+		}
+
+		ERR(sh, "%s\n", data);
+	}
+
+cleanup:
+	free(data);
+
+	free_argv(argv);
+
+	for (i = 0; i < io_len; i++) {
+		if (io[i] >= 0) close(io[i]);
+	}
+
+	if (tmp_fd >= 0) close(tmp_fd);
+	unlink(tmp);
+
+	return status;
+}
+
diff --git a/libsemanage/src/semanage_store.h b/libsemanage/src/semanage_store.h
index 4ad0b21..f1b9675 100644
--- a/libsemanage/src/semanage_store.h
+++ b/libsemanage/src/semanage_store.h
@@ -160,4 +160,33 @@ int semanage_base_path(semanage_handle_t *sh,
 		       char *path,
 		       size_t len);
 
+/* Copy @fd into a the buffer @data with size @data_len.
+ * On call @data will be set to NULL and @data_len to 0.
+ * If @fd is bzip compressed, it will be uncompressed.
+ *
+ * fstat is called on @fd and hence only file based @fd's
+ * are supported (i.e., pipes will not work).
+ *
+ * Caller should free *data.
+ *
+ * Returns:
+ * 	 0	success
+ * 	-1	failure, out of memory
+ * 	-2	failure, invalid @fd
+ */
+int semanage_fd_to_data(semanage_handle_t *sh,
+			int fd,
+			char **data,
+			size_t *data_len);
+
+/* Compiles the modules HLL source into the CIL.
+ *
+ * Returns:
+ * 	 0	success
+ * 	-1	failure, error outside HLL compiler
+ * 	+N	failure, HLL compiler exit status N
+ */
+int semanage_compile_hll(semanage_handle_t *sh,
+			 const semanage_module_info_t *modinfo);
+
 #endif
-- 
1.6.3.3


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 07/15] [src-policy] libsemanage: compile common intermediary language
  2010-01-26 22:08           ` [PATCH 06/15] [src-policy] libsemanage: compile hll module Caleb Case
@ 2010-01-26 22:08             ` Caleb Case
  2010-01-26 22:08               ` [PATCH 08/15] [src-policy] libsemanage: remove binary interfaces Caleb Case
  2010-01-27 20:18             ` [PATCH 06/15] [src-policy] libsemanage: compile hll module Stephen Smalley
  1 sibling, 1 reply; 34+ messages in thread
From: Caleb Case @ 2010-01-26 22:08 UTC (permalink / raw)
  To: selinux; +Cc: csellers, kmacmillan, jwcart2, jbrindle, sds, Caleb Case

During the commit process semanage_compile_cil is called to create the
binary base module from the installed active refpol modules. The
intermediate language compiler is called with each refpol module as an
argument. The compiler is expected to output the binary base module on
stdout and compilation messages to stderr. The compilation messages are
stored in /var/lib/selinux/.../modules/log.
---
 libsemanage/src/direct_api.c     |   15 +-
 libsemanage/src/semanage_store.c |  520 ++++++++++++++++----------------------
 libsemanage/src/semanage_store.h |   28 +--
 3 files changed, 241 insertions(+), 322 deletions(-)

diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index 61e5b92..0623497 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -800,9 +800,11 @@ static int semanage_direct_commit(semanage_handle_t * sh)
 		retval = semanage_verify_modules(sh, mod_filenames, num_modfiles);
 		if (retval < 0)
 			goto cleanup;
-		retval = semanage_link_sandbox(sh, &base);
-		if (retval < 0)
+		retval = semanage_compile_cil(sh, &base);
+		if (retval != 0) {
+			retval = -1;
 			goto cleanup;
+		}
 
 		/* write the linked base if we want to save or we have a
 		 * verification program that wants it. */
@@ -938,9 +940,11 @@ static int semanage_direct_commit(semanage_handle_t * sh)
 			goto cleanup;
 		
 		if (seusers_modified || users_extra_modified) {
-			retval = semanage_link_base(sh, &base);
-			if (retval < 0)
+			retval = semanage_compile_cil(sh, &base);
+			if (retval != 0) {
+				retval = -1;
 				goto cleanup;
+			}
 
 			if (seusers_modified) {
 				retval = semanage_direct_update_seuser(sh, base );
@@ -2166,7 +2170,8 @@ cleanup:
 static int semanage_priorities_filename_select(const struct dirent *d)
 {
 	if (d->d_name[0] == '.' ||
-	    strcmp(d->d_name, "disabled") == 0)
+	    strcmp(d->d_name, "disabled") == 0 ||
+	    strcmp(d->d_name, "log") == 0)
 		return 0;
 	return 1;
 }
diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
index dd96a75..a714d1e 100644
--- a/libsemanage/src/semanage_store.c
+++ b/libsemanage/src/semanage_store.c
@@ -110,6 +110,7 @@ static const char *semanage_sandbox_paths[SEMANAGE_STORE_NUM_PATHS] = {
 	"/users_extra",
 	"/disable_dontaudit",
 	"/modules/disabled",
+	"/modules/log",
 };
 
 static char const * const semanage_final_prefix[SEMANAGE_FINAL_NUM] = {
@@ -501,65 +502,13 @@ const char *semanage_lang_conf_path(void)
 	return "/etc/selinux/language.d";
 }
 
-/* Locates the highest priority enabled base module
- * and fills @path in with that value. @path must be
- * pre-allocated with size @len.
- *
- * Returns 0 on success and -1 on error.
+/* Return a fully-qualified path + filename to the cil compiler. The
+ * caller must not alter the string returned (and hence why this
+ * function return type is const).
  */
-int semanage_base_path(semanage_handle_t *sh,
-		       char *path,
-		       size_t len)
+static const char *semanage_cil_path(void)
 {
-	assert(sh);
-	assert(path);
-
-	int status = 0;
-	int ret = 0;
-
-	semanage_module_info_t *base = NULL;
-
-	/* set key for getting base module */
-	semanage_module_key_t modkey;
-	ret = semanage_module_key_init(sh, &modkey);
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	ret = semanage_module_key_set_name(sh, &modkey, "_base");
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	/* get highest priority base module */
-	ret = semanage_module_get_module_info(sh, &modkey, &base);
-	if (ret != 0) {
-		/* no base module found */
-		status = -1;
-		goto cleanup;
-	}
-
-	/* get the highest priority base module path */
-	ret = semanage_module_get_path(
-			sh,
-			base,
-			SEMANAGE_MODULE_PATH_HLL,
-			path,
-			len);
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-cleanup:
-	semanage_module_key_destroy(sh, &modkey);
-
-	semanage_module_info_destroy(sh, base);
-	free(base);
-
-	return status;
+	return "/usr/bin/refpol_ilc";
 }
 
 /**************** functions that create module store ***************/
@@ -998,29 +947,6 @@ cleanup:
 	return status;
 }
 
-/* qsort comparison function for semanage_get_modules_names. */
-static int semanage_get_modules_names_cmp(const void *a, const void *b)
-{
-	const char *aa = *(const char **)a;
-	const char *bb = *(const char **)b;
-
-	/* copy into a buffer since basename/dirname can modify */
-	char ap[PATH_MAX];
-	char bp[PATH_MAX];
-
-	strncpy(ap, aa, sizeof(ap));
-	ap[PATH_MAX - 1] = '\0';
-
-	strncpy(bp, bb, sizeof(bp));
-	bp[PATH_MAX - 1] = '\0';
-
-	/* compare the module dir names */
-	const char *an = basename(dirname((char *)ap));
-	const char *bn = basename(dirname((char *)bp));
-
-	return strverscmp(an, bn);
-}
-
 /* Scans the modules directory for the current semanage handler.  This
  * might be the active directory or sandbox, depending upon if the
  * handler has a transaction lock.  Allocates and fills in *filenames
@@ -1038,27 +964,20 @@ int semanage_get_modules_names(semanage_handle_t * sh, char ***filenames,
 	int status = 0;
 	int ret = 0;
 
-	int i = 0;
-	int j = 0;
-
-	semanage_list_t *list = NULL;
-	semanage_list_t *found = NULL;
-
 	semanage_module_info_t *modinfos = NULL;
 	int modinfos_len = 0;
 
+	int i;
 	char path[PATH_MAX];
 
-	void *tmp = NULL;
-
 	/* get all modules */
-	ret = semanage_module_list_all(sh, &modinfos, &modinfos_len);
+	ret = semanage_module_list(sh, &modinfos, &modinfos_len);
 	if (ret != 0) {
 		status = -1;
 		goto cleanup;
 	}
 
-	/* allocate enough for worst case */
+	/* allocate space */
 	(*filenames) = calloc(modinfos_len, sizeof(char *));
 	if ((*filenames) == NULL) {
 		ERR(sh, "Error allocating space for filenames.");
@@ -1068,29 +987,7 @@ int semanage_get_modules_names(semanage_handle_t * sh, char ***filenames,
 
 	*len = modinfos_len;
 
-	/* for each highest priority, non-base, enabled module get its path */
-	semanage_list_destroy(&list);
-	j = 0;
 	for (i = 0; i < modinfos_len; i++) {
-		/* check if base */
-		ret = strcmp(modinfos[i].name, "_base");
-		if (ret == 0) continue;
-
-		/* check if enabled */
-		if (modinfos[i].enabled != 1) continue;
-
-		/* check if we've seen this before (i.e. highest priority) */
-		found = semanage_list_find(list, modinfos[i].name);
-		if (found == NULL) {
-			ret = semanage_list_push(&list, modinfos[i].name);
-			if (ret != 0) {
-				ERR(sh, "Failed to add module name to list of known names.");
-				status = -1;
-				goto cleanup;
-			}
-		}
-		else continue;
-
 		ret = semanage_module_get_path(
 				sh,
 				&modinfos[i],
@@ -1102,47 +999,26 @@ int semanage_get_modules_names(semanage_handle_t * sh, char ***filenames,
 			goto cleanup;
 		}
 
-		(*filenames)[j] = strdup(path);
-		if ((*filenames)[j] == NULL) {
+		(*filenames)[i] = strdup(path);
+		if ((*filenames)[i] == NULL) {
 			status = -1;
 			goto cleanup;
 		}
-
-		j += 1;
 	}
 
-	/* realloc the array to its min size */
-	tmp = realloc(*filenames, j * sizeof(char *));
-	if (tmp == NULL) {
-		ERR(sh, "Error allocating space for filenames.");
-		status = -1;
-		goto cleanup;
-	}
-	*filenames = tmp;
-	*len = j;
-
-	/* sort array on module name */
-	qsort(*filenames,
-	      *len,
-	      sizeof(char *),
-	      semanage_get_modules_names_cmp);
-
 cleanup:
-	semanage_list_destroy(&list);
-
-	for (i = 0; i < modinfos_len; i++) {
-		semanage_module_info_destroy(sh, &modinfos[i]);
-	}
-	free(modinfos);
-
 	if (status != 0) {
-		for (i = 0; i < j; j++) {
+		for (i = 0; i < *len; i++) {
 			free((*filenames)[i]);
 		}
-
 		free(*filenames);
 	}
 
+	for (i = 0; i < modinfos_len; i++) {
+		semanage_module_info_destroy(sh, &modinfos[i]);
+	}
+	free(modinfos);
+
 	return status;
 }
 
@@ -1921,166 +1797,6 @@ int semanage_direct_get_serial(semanage_handle_t * sh)
 
 /* HIGHER LEVEL COMMIT FUNCTIONS */
 
-/* Loads a module (or a base) from a fully-qualified 'filename' into a
- * newly allocated sepol_module_package_t structure and returns it in
- * '*package'.	Caller is responsible for destroying it afterwards via
- * sepol_module_package_destroy().  Returns 0 on success, -1 on error.
- */
-static int semanage_load_module(semanage_handle_t * sh, const char *filename,
-				sepol_module_package_t ** package)
-{
-	int retval = 0;
-	FILE *fp;
-	struct sepol_policy_file *pf = NULL;
-
-	*package = NULL;
-	if (sepol_module_package_create(package) == -1) {
-		ERR(sh, "Out of memory!");
-		return -1;
-	}
-
-	if (sepol_policy_file_create(&pf)) {
-		ERR(sh, "Out of memory!");
-		goto cleanup;
-	}
-
-	if ((fp = fopen(filename, "rb")) == NULL) {
-		ERR(sh, "Could not open module file %s for reading.", filename);
-		goto cleanup;
-	}
-	ssize_t size;
-	char *data = NULL;
-
-	if ((size = bunzip(sh, fp, &data)) > 0) {
-		fclose(fp);
-		fp = fmemopen(data, size, "rb");
-		if (!fp) {
-			ERR(sh, "Out of memory!");
-			goto cleanup;
-		}
-	}
-	rewind(fp);
-	__fsetlocking(fp, FSETLOCKING_BYCALLER);
-	sepol_policy_file_set_fp(pf, fp);
-	sepol_policy_file_set_handle(pf, sh->sepolh);
-	if (sepol_module_package_read(*package, pf, 0) == -1) {
-		ERR(sh, "Error while reading from module file %s.", filename);
-		fclose(fp);
-		free(data);
-		goto cleanup;
-	}
-	sepol_policy_file_free(pf);
-	fclose(fp);
-	free(data);
-	return retval;
-
-      cleanup:
-	sepol_module_package_free(*package);
-	*package = NULL;
-	sepol_policy_file_free(pf);
-	return -1;
-}
-
-/* Links all of the modules within the sandbox into the base module.
- * '*base' will point to the module package that contains everything
- * linked together (caller must call sepol_module_package_destroy() on
- * it afterwards).  '*mods' will be a list of module packages and
- * '*num_modules' will be the number of elements within '*mods'
- * (caller must destroy each element as well as the pointer itself.)
- * Both '*base' and '*mods' will be set to NULL upon entering this
- * function.  Returns 0 on success, -1 on error.
- */
-int semanage_link_sandbox(semanage_handle_t * sh,
-			  sepol_module_package_t ** base)
-{
-	char base_filename[PATH_MAX];
-	char **module_filenames = NULL;
-	int retval = -1, i;
-	int num_modules = 0;
-	sepol_module_package_t **mods = NULL;
-
-	*base = NULL;
-
-	/* first make sure that base module is readable */
-	if (semanage_base_path(sh, base_filename, sizeof(base_filename)) != 0) {
-		goto cleanup;
-	}
-	if (access(base_filename, R_OK) == -1) {
-		ERR(sh, "Could not access sandbox base file %s.",
-		    base_filename);
-		goto cleanup;
-	}
-
-	/* get list of modules and load them */
-	if (semanage_get_modules_names(sh, &module_filenames, &num_modules) ==
-	    -1 || semanage_load_module(sh, base_filename, base) == -1) {
-		goto cleanup;
-	}
-	if ((mods = calloc(num_modules, sizeof(*mods))) == NULL) {
-		ERR(sh, "Out of memory!");
-		num_modules = 0;
-		goto cleanup;
-	}
-	for (i = 0; i < num_modules; i++) {
-		if (semanage_load_module(sh, module_filenames[i], mods + i) ==
-		    -1) {
-			goto cleanup;
-		}
-	}
-
-	if (sepol_link_packages(sh->sepolh, *base, mods, num_modules, 0) != 0) {
-		ERR(sh, "Link packages failed");
-		goto cleanup;
-	}
-
-	retval = 0;
-
-      cleanup:
-	for (i = 0; module_filenames != NULL && i < num_modules; i++) {
-		free(module_filenames[i]);
-	}
-	free(module_filenames);
-	for (i = 0; mods != NULL && i < num_modules; i++) {
-		sepol_module_package_free(mods[i]);
-	}
-	free(mods);
-	return retval;
-}
-
-/* Links only the base module within the sandbox into the base module.
- * '*base' will point to the module package that contains everything
- * linked together (caller must call sepol_module_package_destroy() on
- * it afterwards).  '*base' will be set to NULL upon entering this
- * function.  Returns 0 on success, -1 on error.
- */
-int semanage_link_base(semanage_handle_t * sh,
-			  sepol_module_package_t ** base)
-{
-	char base_filename[PATH_MAX];
-	int retval = -1;
-
-	*base = NULL;
-
-	/* first make sure that base module is readable */
-	if (semanage_base_path(sh, base_filename, sizeof(base_filename)) != 0) {
-		goto cleanup;
-	}
-	if (access(base_filename, R_OK) == -1) {
-		ERR(sh, "Could not access sandbox base file %s.",
-		    base_filename);
-		goto cleanup;
-	}
-
-	if (semanage_load_module(sh, base_filename, base) == -1) {
-		goto cleanup;
-	}
-
-	retval = 0;
-
-      cleanup:
-	return retval;
-}
-
 /* 
  * Expands the policy contained within *base 
  */
@@ -3388,3 +3104,205 @@ cleanup:
 	return status;
 }
 
+/* Compiles all active modules into a base module.  This function
+ * assumes that the HLL has been compiled to the CIL during module
+ * install/upgrade. *base must be NULL.
+ *
+ * Returns:
+ *	 0	success
+ *	-1	failure, error outside CIL compiler
+ *	+N	failure, CIL compiler exit status
+ */
+int semanage_compile_cil(semanage_handle_t *sh, sepol_module_package_t **base)
+{
+	assert(sh != NULL);
+	assert(base != NULL);
+	assert(*base == NULL);
+
+	int status = 0;
+	int ret = 0;
+
+	int io[3];
+	int io_len = 3;
+
+	int i = 0;
+	char path[PATH_MAX];
+	semanage_module_info_t *modinfos = NULL;
+	int modinfos_len = 0;
+
+	char **argv = NULL;
+
+	char tmp[] = "/tmp/libsemanage-XXXXXX";
+	FILE *fp = NULL;
+	struct sepol_policy_file *pf = NULL;
+
+	const char *cilc = semanage_cil_path();
+	const char *log = semanage_path(SEMANAGE_TMP, SEMANAGE_CIL_LOG);
+
+	char *data = NULL;
+	size_t data_len = 0;
+
+	/* setup io */
+
+	/* no stdin */
+	io[0] = -1;
+
+	/* stdout to temp (base module) */
+	io[1] = mkstemp(tmp);
+	if (io[1] < 0) {
+		ERR(sh, "Failed to create tmp file for base module %s.", tmp);
+		unlink(tmp);
+		status = -1;
+		goto cleanup;
+	}
+	unlink(tmp);
+
+	/* stderr to cil log */
+	io[2] = creat(log, S_IRUSR | S_IWUSR);
+	if (io[2] < 0) {
+		ERR(sh, "Failed to create log file %s", log);
+		status = -1;
+		goto cleanup;
+	}
+
+	/* get modinfos */
+	ret = semanage_module_list_all(sh, &modinfos, &modinfos_len);
+	if (ret != 0) {
+		status = -1;
+		goto cleanup;
+	}
+
+	/* argv for module paths */
+	argv = calloc(modinfos_len + 2, sizeof(char *));
+	if (argv == NULL) {
+		ERR(sh, "Out of memory!");
+		status = -1;
+		goto cleanup;
+	}
+
+	/* for each module */
+	for (i = 0; i < modinfos_len; i++) {
+		/* add module cil path to argv */
+		ret = semanage_module_get_path(sh,
+					       &modinfos[i],
+					       SEMANAGE_MODULE_PATH_CIL,
+					       path,
+					       sizeof(path));
+		if (ret != 0) {
+			status = -1;
+			goto cleanup;
+		}
+
+		/* if the module is disabled pass with -d */
+		if (modinfos[i].enabled == 1) {
+			argv[i + 1] = strdup(path);
+		}
+		else {
+			ret = asprintf(&argv[i + 1], "-d%s", path);
+			if (ret < 0) argv[i + 1] = NULL;
+		}
+
+		if (argv[i + 1] == NULL) {
+			ERR(sh, "Out of memory!");
+			status = -1;
+			goto cleanup;
+		}
+	}
+
+	argv[0] = strdup(cilc);
+	if (argv[0] == NULL) {
+		ERR(sh, "Out of memory!");
+		status = -1;
+		goto cleanup;
+	}
+
+	/* exec cil compiler */
+	ret = semanage_exec(sh, cilc, argv, io, io_len);
+	if (ret != 0) {
+		status = ret;
+		if (status > 0) {
+			ret = fsync(io[2]);
+			if (ret != 0) {
+				WARN(sh, "Failed to sync log to disk!");
+			}
+			close(io[2]);
+
+			io[2] = open(log, O_RDONLY);
+			if (io[2] < 0) {
+				ERR(sh, "Failed to open log file.");
+				goto cleanup;
+			}
+
+			ret = semanage_fd_to_data(sh, io[2], &data, &data_len);
+			if (ret != 0) {
+				ERR(sh, "Failed to read log.");
+				goto cleanup;
+			}
+
+			ERR(sh, "%s\n", data);
+		}
+
+		goto cleanup;
+	}
+
+	/* load base module */
+	ret = sepol_module_package_create(base);
+	if (ret != 0) {
+		ERR(sh, "Out of memory!");
+		status = -1;
+		goto cleanup;
+	}
+
+	ret = sepol_policy_file_create(&pf);
+	if (ret != 0) {
+		ERR(sh, "Out of memory!");
+		status = -1;
+		goto cleanup;
+	}
+
+	fp = fdopen(io[1], "r");
+	if (fp == NULL) {
+		ERR(sh, "Failed to open tmp file for base module %s.", tmp);
+		status = -1;
+		goto cleanup;
+	}
+
+	rewind(fp);
+
+	sepol_policy_file_set_fp(pf, fp);
+	sepol_policy_file_set_handle(pf, sh->sepolh);
+
+	ret = sepol_module_package_read(*base, pf, 0);
+	if (ret != 0) {
+		status = -1;
+		goto cleanup;
+	}
+
+cleanup:
+	if (status != 0) {
+		sepol_module_package_free(*base);
+		*base = NULL;
+	}
+
+	sepol_policy_file_free(pf);
+	if (fp != NULL) {
+		fclose(fp);
+		io[1] = -1;
+	}
+
+	free_argv(argv);
+
+	for (i = 0; i < modinfos_len; i++) {
+		semanage_module_info_destroy(sh, &modinfos[i]);
+	}
+	free(modinfos);
+
+	free(data);
+
+	for (i = 0; i < io_len; i++) {
+		if (io[i] >= 0) close(io[i]);
+	}
+
+	return status;
+}
+
diff --git a/libsemanage/src/semanage_store.h b/libsemanage/src/semanage_store.h
index f1b9675..c59bc69 100644
--- a/libsemanage/src/semanage_store.h
+++ b/libsemanage/src/semanage_store.h
@@ -53,6 +53,7 @@ enum semanage_sandbox_defs {
 	SEMANAGE_USERS_EXTRA,
 	SEMANAGE_DISABLE_DONTAUDIT,
 	SEMANAGE_MODULES_DISABLED,
+	SEMANAGE_CIL_LOG,
 	SEMANAGE_STORE_NUM_PATHS
 };
 
@@ -113,12 +114,6 @@ void semanage_release_trans_lock(semanage_handle_t * sh);
 void semanage_release_active_lock(semanage_handle_t * sh);
 int semanage_direct_get_serial(semanage_handle_t * sh);
 
-int semanage_link_sandbox(semanage_handle_t * sh,
-			  sepol_module_package_t ** base);
-
-int semanage_link_base(semanage_handle_t * sh,
-		       sepol_module_package_t ** base);
-
 int semanage_expand_sandbox(semanage_handle_t * sh,
 			    sepol_module_package_t * base,
 			    sepol_policydb_t ** policydb);
@@ -150,16 +145,6 @@ int semanage_nc_sort(semanage_handle_t * sh,
 		     size_t buf_len,
 		     char **sorted_buf, size_t * sorted_buf_len);
 
-/* Locates the highest priority enabled base module
- * and fills @path in with that value. @path must be
- * pre-allocated with size @len.
- *
- * Returns 0 on success and -1 on error.
- */
-int semanage_base_path(semanage_handle_t *sh,
-		       char *path,
-		       size_t len);
-
 /* Copy @fd into a the buffer @data with size @data_len.
  * On call @data will be set to NULL and @data_len to 0.
  * If @fd is bzip compressed, it will be uncompressed.
@@ -189,4 +174,15 @@ int semanage_fd_to_data(semanage_handle_t *sh,
 int semanage_compile_hll(semanage_handle_t *sh,
 			 const semanage_module_info_t *modinfo);
 
+/* Compiles all active modules into a base module.  This function
+ * assumes that the HLL has been compiled to the CIL during module
+ * install/upgrade. *base must be NULL.
+ *
+ * Returns:
+ *	 0	success
+ *	-1	failure, error outside CIL compiler
+ *	+N	failure, CIL compiler exit status
+ */
+int semanage_compile_cil(semanage_handle_t *sh, sepol_module_package_t **base);
+
 #endif
-- 
1.6.3.3


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 08/15] [src-policy] libsemanage: remove binary interfaces
  2010-01-26 22:08             ` [PATCH 07/15] [src-policy] libsemanage: compile common intermediary language Caleb Case
@ 2010-01-26 22:08               ` Caleb Case
  2010-01-26 22:08                 ` [PATCH 09/15] [src-policy] semodule: remove base module support Caleb Case
  2010-01-29 20:32                 ` [PATCH 08/15] [src-policy] libsemanage: remove binary interfaces James Carter
  0 siblings, 2 replies; 34+ messages in thread
From: Caleb Case @ 2010-01-26 22:08 UTC (permalink / raw)
  To: selinux; +Cc: csellers, kmacmillan, jwcart2, jbrindle, sds, Caleb Case

Supporting both binary policy packages and source modules is difficult
and leads to problems that are unacceptable. For instance, the binary
modules would lack relevant information for recompilation such as the
interface definition (which would lead to unexpected behavior if a
source module interface changes, but those changes don't appear in the
binary modules).  Consequently, we completely removed support for binary
modules, leaving only support for source modules. Also, because we are
now creating the base module automatically from the source modules, the
base module interfaces are removed as well.

This patch deprecates the following:

   semanage_module_install
   semanage_module_upgrade
   semanage_module_install_base
   semanage_module_intall_base_file

and removes their direct_api implementations.

For the sake of rendering meaningful error messages, the callbacks for
these functions have been initialized to NULL. This will result in an
error message indicating that the function is not implemented for the
given connection type. At a future time these functions would be removed
entirely.

The file related functions are updated to expect source modules:

   semanage_module_install_file
   semanage_module_upgrade_file
---
 libsemanage/include/semanage/modules.h |   14 +-
 libsemanage/src/direct_api.c           |  751 +++++++++++++-------------------
 2 files changed, 302 insertions(+), 463 deletions(-)

diff --git a/libsemanage/include/semanage/modules.h b/libsemanage/include/semanage/modules.h
index e169279..8a26e6c 100644
--- a/libsemanage/include/semanage/modules.h
+++ b/libsemanage/include/semanage/modules.h
@@ -1,7 +1,7 @@
 /* Authors: Joshua Brindle  <jbrindle@tresys.com>
  *	    Jason Tang	    <jtang@tresys.com>
  *
- * Copyright (C) 2005 Tresys Technology, LLC
+ * Copyright (C) 2005,2010 Tresys Technology, LLC
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -29,17 +29,21 @@
  */
 
 int semanage_module_install(semanage_handle_t *,
-			    char *module_data, size_t data_len);
+			    char *module_data, size_t data_len)
+			    __attribute__ ((deprecated));
 int semanage_module_install_file(semanage_handle_t *,
 				 const char *module_name);
 int semanage_module_upgrade(semanage_handle_t *,
-			    char *module_data, size_t data_len);
+			    char *module_data, size_t data_len)
+			    __attribute__ ((deprecated));
 int semanage_module_upgrade_file(semanage_handle_t *,
 				 const char *module_name);
 int semanage_module_install_base(semanage_handle_t *,
-				 char *module_data, size_t data_len);
+				 char *module_data, size_t data_len)
+				 __attribute__ ((deprecated));
 int semanage_module_install_base_file(semanage_handle_t *,
-				      const char *module_name);
+				      const char *module_name)
+				      __attribute__ ((deprecated));
 int semanage_module_remove(semanage_handle_t *, char *module_name);
 
 /* semanage_module_info is for getting information on installed
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index 0623497..6f7cf63 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -58,15 +58,8 @@ static void semanage_direct_destroy(semanage_handle_t * sh);
 static int semanage_direct_disconnect(semanage_handle_t * sh);
 static int semanage_direct_begintrans(semanage_handle_t * sh);
 static int semanage_direct_commit(semanage_handle_t * sh);
-static int semanage_direct_install(semanage_handle_t * sh, char *data,
-				   size_t data_len);
 static int semanage_direct_install_file(semanage_handle_t * sh, const char *module_name);
-static int semanage_direct_upgrade(semanage_handle_t * sh, char *data,
-				   size_t data_len);
 static int semanage_direct_upgrade_file(semanage_handle_t * sh, const char *module_name);
-static int semanage_direct_install_base(semanage_handle_t * sh, char *base_data,
-					size_t data_len);
-static int semanage_direct_install_base_file(semanage_handle_t * sh, const char *module_name);
 static int semanage_direct_remove(semanage_handle_t * sh, char *module_name);
 static int semanage_direct_list(semanage_handle_t * sh,
 				semanage_module_info_t ** modinfo,
@@ -105,12 +98,12 @@ static struct semanage_policy_table direct_funcs = {
 	.disconnect = semanage_direct_disconnect,
 	.begin_trans = semanage_direct_begintrans,
 	.commit = semanage_direct_commit,
-	.install = semanage_direct_install,
 	.install_file = semanage_direct_install_file,
-	.upgrade = semanage_direct_upgrade,
 	.upgrade_file = semanage_direct_upgrade_file,
-	.install_base = semanage_direct_install_base,
-	.install_base_file = semanage_direct_install_base_file,
+	.install = NULL,
+	.upgrade = NULL,
+	.install_base = NULL,
+	.install_base_file = NULL,
 	.remove = semanage_direct_remove,
 	.list = semanage_direct_list,
 	.get_enabled = semanage_direct_get_enabled,
@@ -373,87 +366,6 @@ static int semanage_direct_begintrans(semanage_handle_t * sh)
 
 /********************* utility functions *********************/
 
-/* Takes a module stored in 'module_data' and parses its headers.
- * Sets reference variables 'module_name' to module's name, and
- * 'version' to module's version.  The caller is responsible for
- * free()ing 'module_name', and 'version'; they will be
- * set to NULL upon entering this function.  Returns 0 on success, -1
- * if out of memory, or -2 if data did not represent a module.
- */
-static int parse_module_headers(semanage_handle_t * sh, char *module_data,
-				size_t data_len, char **module_name,
-				char **version)
-{
-	struct sepol_policy_file *pf;
-	int file_type;
-	*module_name = *version = NULL;
-
-	if (sepol_policy_file_create(&pf)) {
-		ERR(sh, "Out of memory!");
-		return -1;
-	}
-	sepol_policy_file_set_mem(pf, module_data, data_len);
-	sepol_policy_file_set_handle(pf, sh->sepolh);
-	if (module_data == NULL ||
-	    data_len == 0 ||
-	    sepol_module_package_info(pf, &file_type, module_name,
-				      version) == -1) {
-		sepol_policy_file_free(pf);
-		ERR(sh, "Could not parse module data.");
-		return -2;
-	}
-	sepol_policy_file_free(pf);
-	if (file_type != SEPOL_POLICY_MOD) {
-		if (file_type == SEPOL_POLICY_BASE)
-			ERR(sh,
-			    "Received a base module, expected a non-base module.");
-		else
-			ERR(sh, "Data did not represent a module.");
-		return -2;
-	}
-
-	return 0;
-}
-
-/* Takes a base module stored in 'module_data' and parse its headers.
- * Returns 0 on success, -1 if out of memory, or -2 if data did not
- * represent a module.
- */
-static int parse_base_headers(semanage_handle_t * sh,
-			      char *module_data, size_t data_len)
-{
-	struct sepol_policy_file *pf;
-	char *module_name = NULL, *version = NULL;
-	int file_type;
-
-	if (sepol_policy_file_create(&pf)) {
-		ERR(sh, "Out of memory!");
-		return -1;
-	}
-	sepol_policy_file_set_mem(pf, module_data, data_len);
-	sepol_policy_file_set_handle(pf, sh->sepolh);
-	if (module_data == NULL ||
-	    data_len == 0 ||
-	    sepol_module_package_info(pf, &file_type,
-				      &module_name, &version) == -1) {
-		sepol_policy_file_free(pf);
-		ERR(sh, "Could not parse base module data.");
-		return -2;
-	}
-	sepol_policy_file_free(pf);
-	free(module_name);
-	free(version);
-	if (file_type != SEPOL_POLICY_BASE) {
-		if (file_type == SEPOL_POLICY_MOD)
-			ERR(sh,
-			    "Received a non-base module, expected a base module.");
-		else
-			ERR(sh, "Data did not represent a module.");
-		return -2;
-	}
-	return 0;
-}
-
 #include <stdlib.h>
 #include <bzlib.h>
 #include <string.h>
@@ -564,41 +476,6 @@ ssize_t bunzip(semanage_handle_t *sh, FILE *f, char **data)
 	return  total;
 }
 
-/* mmap() a file to '*data',
- *  If the file is bzip compressed map_file will uncompress 
- * the file into '*data'.
- * Returns the total number of bytes in memory .
- * Returns -1 if file could not be opened or mapped. */
-static ssize_t map_file(semanage_handle_t *sh, int fd, char **data,
-			int *compressed)
-{
-	ssize_t size = -1;
-	char *uncompress;
-	if ((size = bunzip(sh, fdopen(fd, "r"), &uncompress)) > 0) {
-		*data = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
-		if (*data == MAP_FAILED) {
-			free(uncompress);
-			return -1;
-		} else {
-			memcpy(*data, uncompress, size);
-		}
-		free(uncompress);
-		*compressed = 1;
-	} else {
-		struct stat sb;
-		if (fstat(fd, &sb) == -1 ||
-		    (*data = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) ==
-		    MAP_FAILED) {
-			size = -1;
-		} else {
-			size = sb.st_size;
-		}
-		*compressed = 0;
-	} 
-
-	return size;
-}
-
 /* Writes a block of data to a file.  Returns 0 on success, -1 on
  * error. */
 static int write_file(semanage_handle_t * sh,
@@ -706,6 +583,169 @@ static int semanage_direct_update_seuser(semanage_handle_t * sh, sepol_module_pa
 	return retval;
 }
 
+/* Reads the source module pointed to by @path into a memory buffer
+ * @data of length @data_len. @modinfo is constructed with gleaned from
+ * the module path and defaults as follows:
+ *
+ * priority	default from handle
+ * name		basename(path) sans extension
+ * version	empty string (gets overridden by hll compiler)
+ * lang_ext	basename(path) sans name and '.'
+ * enabled	default of -1 (don't change status)
+ * 
+ * On call @modinfo and @data will be set to NULL. @data_len will be set
+ * to 0.
+ *
+ * Caller should destroy and free @modinfo and free @data.
+ *
+ * Returns:
+ *
+ * 	 0	success
+ * 	-1	failure, out of memory
+ * 	-2	failure, invalid @path
+ */
+static int semanage_path_to_info(semanage_handle_t *sh,
+				 const char *path,
+				 semanage_module_info_t **modinfo,
+				 char **data,
+				 size_t *data_len)
+{
+	assert(sh);
+	assert(path);
+	assert(modinfo);
+	assert(data);
+	assert(data_len);
+
+	int status = 0;
+	int ret = 0;
+
+	int fd = -1;
+	char *path_tmp = NULL;
+	char *name = NULL;
+	int i;
+	char *ext = NULL;
+
+	*modinfo = NULL;
+
+	/* Open the module. */
+	fd = open(path, O_RDONLY);
+	if (fd < 0) {
+		ERR(sh, "Failed to open file %s.", path);
+		status = -2;
+		goto cleanup;
+	}
+
+	/* Convert to buffer. */
+	ret = semanage_fd_to_data(sh, fd, data, data_len);
+	if (ret != 0) {
+		status = ret;
+		goto cleanup;
+	}
+
+	/* Get the name and ext from the path.
+	 * name will be the first part of the string.
+	 * ext will be the last part.
+	 * Note that neither should be free'd.
+	 * strduping here since basename can modify.
+	 */
+	path_tmp = strdup(path);
+	if (path_tmp == NULL) {
+		status = -1;
+		goto cleanup;
+	}
+
+	name = basename(path_tmp);
+	for (i = strlen(name) - 1; i >= 1; i--) {
+		if (name[i] == '.') {
+			name[i] = '\0';
+			ext = &name[i] + 1;
+			break;
+		}
+	}
+
+	/* Failed to find an ext or name begins with '.'. */
+	if (i == 0) {
+		status = -2;
+		goto cleanup;
+	}
+
+	/* Create and initialize a modinfo. */
+	ret = semanage_module_info_create(sh, modinfo);
+	if (ret != 0) {
+		status = -1;
+		goto cleanup;
+	}
+
+	ret = semanage_module_info_set_priority(
+			sh,
+			*modinfo,
+			sh->priority);
+	if (ret != 0) {
+		status = -1;
+		goto cleanup;
+	}
+
+	ret = semanage_module_info_set_name(
+			sh,
+			*modinfo,
+			name);
+	if (ret != 0) {
+		status = -1;
+		goto cleanup;
+	}
+
+	/* Initialize version to 0.
+	 * The module version will changed later by the hll compiler.
+	 */
+	ret = semanage_module_info_set_version(
+			sh,
+			*modinfo,
+			"0");
+	if (ret != 0) {
+		status = -1;
+		goto cleanup;
+	}
+
+	ret = semanage_module_info_set_lang_ext(
+			sh,
+			*modinfo,
+			ext);
+	if (ret != 0) {
+		status = -1;
+		goto cleanup;
+	}
+
+	/* Set enabled to the default -1 value. This means that
+	 * installing the module will not modify the enabled/disabled
+	 * status.
+	 */
+	ret = semanage_module_info_set_enabled(
+			sh,
+			*modinfo,
+			-1);
+	if (ret != 0) {
+		status = -1;
+		goto cleanup;
+	}
+
+cleanup:
+	if (status != 0) {
+		semanage_module_info_destroy(sh, *modinfo);
+		free(*modinfo);
+		*modinfo = NULL;
+
+		free(*data);
+		*data = NULL;
+		*data_len = 0;
+	}
+
+	free(path_tmp);
+
+	close(fd);
+
+	return status;
+}
+
 /********************* direct API functions ********************/
 
 /* Commits all changes in sandbox to the actual kernel policy.
@@ -1055,72 +1095,6 @@ static int semanage_direct_commit(semanage_handle_t * sh)
 	return retval;
 }
 
-/* Writes a module to the sandbox's module directory, overwriting any
- * previous module stored within.  Note that module data are not
- * free()d by this function; caller is responsible for deallocating it
- * if necessary.  Returns 0 on success, -1 if out of memory, -2 if the
- * data does not represent a valid module file, -3 if error while
- * writing file. */
-static int semanage_direct_install(semanage_handle_t * sh,
-				   char *data, size_t data_len)
-{
-	int status = 0;
-	int ret = 0;
-
-	char *module_name = NULL, *version = NULL;
-	if ((status = parse_module_headers(sh, data, data_len,
-					   &module_name, &version)) != 0) {
-		goto cleanup;
-	}
-
-	semanage_module_info_t modinfo;
-	ret = semanage_module_info_init(sh, &modinfo);
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	ret = semanage_module_info_set_priority(sh, &modinfo, sh->priority);
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	ret = semanage_module_info_set_name(sh, &modinfo, module_name);
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	ret = semanage_module_info_set_version(sh, &modinfo, version);
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	ret = semanage_module_info_set_lang_ext(sh, &modinfo, "pp");
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	ret = semanage_module_info_set_enabled(sh, &modinfo, -1);
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	status = semanage_direct_install_info(sh, &modinfo, data, data_len);
-
-cleanup:
-	free(version);
-	free(module_name);
-
-	semanage_module_info_destroy(sh, &modinfo);
-
-	return status;
-}
-
 /* Attempts to link a module to the sandbox's module directory, unlinking any
  * previous module stored within.  Returns 0 on success, -1 if out of memory, -2 if the
  * data does not represent a valid module file, -3 if error while
@@ -1129,97 +1103,31 @@ cleanup:
 static int semanage_direct_install_file(semanage_handle_t * sh,
 					const char *install_filename)
 {
+	int status = 0;
 
-	int retval = -1;
+	semanage_module_info_t *modinfo = NULL;
 	char *data = NULL;
-	ssize_t data_len = 0;
-	int compressed = 0;
-	int in_fd = -1;
-
-	if ((in_fd = open(install_filename, O_RDONLY)) == -1) {
-		return -1;
-	}
-
-	if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) {
-		goto cleanup;
-	}
-		
-	retval = semanage_direct_install(sh, data, data_len);
-
-      cleanup:
-	close(in_fd);
-	if (data_len > 0) munmap(data, data_len);
-
-	return retval;
-}
+	size_t data_len = 0;
 
-/* Similar to semanage_direct_install(), except that it checks that
- * there already exists a module with the same name and that the
- * module is an older version then the one in 'data'.  Returns 0 on
- * success, -1 if out of memory, -2 if the data does not represent a
- * valid module file, -3 if error while writing file or reading
- * modules directory, -4 if the previous module is same or newer than 'data', 
- * -5 if there does not exist an older module.
- */
-static int semanage_direct_upgrade(semanage_handle_t * sh,
-				   char *data, size_t data_len)
-{
-	int status = 0;
-	int ret = 0;
+	status = semanage_path_to_info(
+			sh,
+			install_filename,
+			&modinfo,
+			&data,
+			&data_len);
+	if (status != 0) goto cleanup;
 
-	char *module_name = NULL, *version = NULL;
-	status = parse_module_headers(
+	status = semanage_module_install_info(
 			sh,
+			modinfo,
 			data,
-			data_len,
-			&module_name,
-			&version);
-	if (status != 0) {
-		goto cleanup;
-	}
-
-	semanage_module_info_t modinfo;
-	ret = semanage_module_info_init(sh, &modinfo);
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	ret = semanage_module_info_set_priority(sh, &modinfo, sh->priority);
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	ret = semanage_module_info_set_name(sh, &modinfo, module_name);
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	ret = semanage_module_info_set_version(sh, &modinfo, version);
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	ret = semanage_module_info_set_lang_ext(sh, &modinfo, "pp");
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	ret = semanage_module_info_set_enabled(sh, &modinfo, -1);
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	status = semanage_direct_upgrade_info(sh, &modinfo, data, data_len);
+			data_len);
 
 cleanup:
-	free(module_name);
-	free(version);
+	semanage_module_info_destroy(sh, modinfo);
+	free(modinfo);
+
+	free(data);
 
 	return status;
 }
@@ -1233,125 +1141,33 @@ cleanup:
 static int semanage_direct_upgrade_file(semanage_handle_t * sh,
 					const char *module_filename)
 {
-	int retval = -1;
-	char *data = NULL;
-	ssize_t data_len = 0;
-	int compressed = 0;
-	int in_fd = -1;
-
-	if ((in_fd = open(module_filename, O_RDONLY)) == -1) {
-		return -1;
-	}
-
-	if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) {
-		goto cleanup;
-	}
-
-	retval = semanage_direct_upgrade(sh, data, data_len);
-
-      cleanup:
-	close(in_fd);
-	if (data_len > 0) munmap(data, data_len);
-
-	return retval;
-}
-
-/* Writes a base module into a sandbox, overwriting any previous base
- * module.  Note that 'module_data' is not free()d by this function;
- * caller is responsible for deallocating it if necessary.  Returns 0
- * on success, -1 if out of memory, -2 if the data does not represent
- * a valid base module file, -3 if error while writing file.
- */
-static int semanage_direct_install_base(semanage_handle_t * sh,
-					char *base_data, size_t data_len)
-{
 	int status = 0;
-	int ret = 0;
-
-	ret = parse_base_headers(sh, base_data, data_len);
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	semanage_module_info_t modinfo;
-	ret = semanage_module_info_init(sh, &modinfo);
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	ret = semanage_module_info_set_priority(sh, &modinfo, sh->priority);
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	ret = semanage_module_info_set_name(sh, &modinfo, "_base");
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	ret = semanage_module_info_set_version(sh, &modinfo, "1.0.0");
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
-
-	ret = semanage_module_info_set_lang_ext(sh, &modinfo, "pp");
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
 
-	ret = semanage_module_info_set_enabled(sh, &modinfo, 1);
-	if (ret != 0) {
-		status = -1;
-		goto cleanup;
-	}
+	semanage_module_info_t *modinfo = NULL;
+	char *data = NULL;
+	size_t data_len = 0;
 
-	status = semanage_direct_install_info(
+	status = semanage_path_to_info(
 			sh,
+			module_filename,
 			&modinfo,
-			base_data,
+			&data,
+			&data_len);
+	if (status != 0) goto cleanup;
+
+	status = semanage_module_upgrade_info(
+			sh,
+			modinfo,
+			data,
 			data_len);
 
 cleanup:
-	semanage_module_info_destroy(sh, &modinfo);
-
-	return status;
-}
-
-/* Writes a base module into a sandbox, overwriting any previous base
- * module.  
- * Returns 0 on success, -1 if out of memory, -2 if the data does not represent
- * a valid base module file, -3 if error while writing file.
- */
-static int semanage_direct_install_base_file(semanage_handle_t * sh,
-					     const char *install_filename)
-{
-	int retval = -1;
-	char *data = NULL;
-	ssize_t data_len = 0;
-	int compressed = 0;
-	int in_fd;
-
-	if ((in_fd = open(install_filename, O_RDONLY)) == -1) {
-		return -1;
-	}
-
-	if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) {
-		goto cleanup;
-	}
-		
-	retval = semanage_direct_install_base(sh, data, data_len);
+	semanage_module_info_destroy(sh, modinfo);
+	free(modinfo);
 
-      cleanup:
-	close(in_fd);
-	if (data_len > 0) munmap(data, data_len);
+	free(data);
 
-	return retval;
+	return status;
 }
 
 /* Removes a module from the sandbox.  Returns 0 on success, -1 if out
@@ -1386,6 +1202,14 @@ cleanup:
 	return status;
 }
 
+/* qsort comparison function for semanage_direct_list. */
+static int semanage_direct_list_cmp(const void *a, const void *b)
+{
+	semanage_module_info_t *ma = (semanage_module_info_t *)a;
+	semanage_module_info_t *mb = (semanage_module_info_t *)b;
+	return strverscmp(ma->name, mb->name);
+}
+
 /* Allocate an array of module_info structures for each readable
  * module within the store.  Note that if the calling program has
  * already begun a transaction then this function will get a list of
@@ -1393,97 +1217,108 @@ cleanup:
  * semanage_module_info_datum_destroy() on each element of the array
  * as well as free()ing the entire list.
  */
-static int semanage_direct_list(semanage_handle_t * sh,
-				semanage_module_info_t ** modinfo,
-				int *num_modules)
+static int semanage_direct_list(semanage_handle_t *sh,
+				semanage_module_info_t **modinfos,
+				int *modinfos_len)
 {
-	struct sepol_policy_file *pf = NULL;
-	int i, retval = -1;
-	char **module_filenames = NULL;
-	int num_mod_files;
-	*modinfo = NULL;
-	*num_modules = 0;
+	assert(sh);
+	assert(modinfos);
+	assert(modinfos_len);
 
-	/* get the read lock when reading from the active
-	   (non-transaction) directory */
-	if (!sh->is_in_transaction)
-		if (semanage_get_active_lock(sh) < 0)
-			return -1;
+	int status = 0;
+	int ret = 0;
 
-	if (semanage_get_modules_names(sh, &module_filenames, &num_mod_files) ==
-	    -1) {
-		goto cleanup;
-	}
-	if (num_mod_files == 0) {
-		retval = semanage_direct_get_serial(sh);
-		goto cleanup;
-	}
+	int i = 0;
+	int j = 0;
 
-	if (sepol_policy_file_create(&pf)) {
-		ERR(sh, "Out of memory!");
+	semanage_list_t *list = NULL;
+	semanage_list_t *found = NULL;
+
+	semanage_module_info_t *all_modinfos = NULL;
+	int all_modinfos_len = 0;
+
+	void *tmp = NULL;
+
+	/* get all modules */
+	ret = semanage_module_list_all(sh, &all_modinfos, &all_modinfos_len);
+	if (ret != 0) {
+		status = -1;
 		goto cleanup;
 	}
-	sepol_policy_file_set_handle(pf, sh->sepolh);
 
-	if ((*modinfo = calloc(num_mod_files, sizeof(**modinfo))) == NULL) {
-		ERR(sh, "Out of memory!");
+	/* allocate enough for worst case */
+	(*modinfos) = calloc(all_modinfos_len, sizeof(semanage_module_info_t));
+	if ((*modinfos) == NULL) {
+		ERR(sh, "Error allocating space for module info array.");
+		status = -1;
 		goto cleanup;
 	}
 
-	for (i = 0; i < num_mod_files; i++) {
-		FILE *fp;
-		char *name = NULL, *version = NULL;
-		int type;
-		if ((fp = fopen(module_filenames[i], "rb")) == NULL) {
-			/* could not open this module file, so don't
-			 * report it */
-			continue;
-		}
-		ssize_t size;
-		char *data = NULL;
-
-		if ((size = bunzip(sh, fp, &data)) > 0) {
-			fclose(fp);
-			fp = fmemopen(data, size, "rb");
-			if (!fp) {
-				ERR(sh, "Out of memory!");
+	*modinfos_len = all_modinfos_len;
+
+	/* for each highest priority, enabled module clone */
+	semanage_list_destroy(&list);
+	for (i = 0, j = 0; i < all_modinfos_len; i++) {
+		/* check if enabled */
+		if (all_modinfos[i].enabled != 1) continue;
+
+		/* check if we've seen this before (i.e. highest priority) */
+		found = semanage_list_find(list, all_modinfos[i].name);
+		if (found == NULL) {
+			ret = semanage_list_push(&list, all_modinfos[i].name);
+			if (ret != 0) {
+				ERR(sh, "Failed to add module name to list of known names.");
+				status = -1;
 				goto cleanup;
 			}
 		}
-		rewind(fp);
-		__fsetlocking(fp, FSETLOCKING_BYCALLER);
-		sepol_policy_file_set_fp(pf, fp);
-		if (sepol_module_package_info(pf, &type, &name, &version)) {
-			fclose(fp);
-			free(data);
-			free(name);
-			free(version);
-			continue;
-		}
-		fclose(fp);
-		free(data);
-		if (type == SEPOL_POLICY_MOD) {
-			(*modinfo)[*num_modules].name = name;
-			(*modinfo)[*num_modules].version = version;
-			(*num_modules)++;
-		} else {
-			/* file was not a module, so don't report it */
-			free(name);
-			free(version);
+		else continue;
+
+		ret = semanage_module_info_clone(
+				sh,
+				&all_modinfos[i],
+				&(*modinfos)[j]);
+		if (ret != 0) {
+			ERR(sh, "Failed to clone module into array.");
+			status = -1;
+			goto cleanup;
 		}
+
+		j += 1;
 	}
-	retval = semanage_direct_get_serial(sh);
 
-      cleanup:
-	sepol_policy_file_free(pf);
-	for (i = 0; module_filenames != NULL && i < num_mod_files; i++) {
-		free(module_filenames[i]);
+	/* realloc the array to its min size */
+	tmp = realloc(*modinfos, j * sizeof(semanage_module_info_t));
+	if (tmp == NULL) {
+		ERR(sh, "Error allocating space for module info array.");
+		status = -1;
+		goto cleanup;
 	}
-	free(module_filenames);
-	if (!sh->is_in_transaction) {
-		semanage_release_active_lock(sh);
+	*modinfos = tmp;
+	*modinfos_len = j;
+
+	/* sort array on module name */
+	qsort(*modinfos,
+	      *modinfos_len,
+	      sizeof(semanage_module_info_t),
+	      semanage_direct_list_cmp);
+
+cleanup:
+	semanage_list_destroy(&list);
+
+	for (i = 0; i < all_modinfos_len; i++) {
+		semanage_module_info_destroy(sh, &all_modinfos[i]);
 	}
-	return retval;
+	free(all_modinfos);
+
+	if (status != 0) {
+		for (i = 0; i < *modinfos_len; i++) {
+			semanage_module_info_destroy(sh, &(*modinfos)[i]);
+		}
+		free(*modinfos);
+	}
+
+	return status;
 }
 
 static int semanage_direct_get_enabled(semanage_handle_t *sh,
-- 
1.6.3.3


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 09/15] [src-policy] semodule: remove base module support
  2010-01-26 22:08               ` [PATCH 08/15] [src-policy] libsemanage: remove binary interfaces Caleb Case
@ 2010-01-26 22:08                 ` Caleb Case
  2010-01-26 22:08                   ` [PATCH 10/15] [src-policy] libsemanage: get source module Caleb Case
  2010-01-29 20:32                 ` [PATCH 08/15] [src-policy] libsemanage: remove binary interfaces James Carter
  1 sibling, 1 reply; 34+ messages in thread
From: Caleb Case @ 2010-01-26 22:08 UTC (permalink / raw)
  To: selinux; +Cc: csellers, kmacmillan, jwcart2, jbrindle, sds, Caleb Case

This patch removes the base module flag from semodule, updates the man
page to reflect this, and has semodule output an error message if -b is
used.
---
 policycoreutils/semodule/semodule.8 |    3 ---
 policycoreutils/semodule/semodule.c |    8 ++++----
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/policycoreutils/semodule/semodule.8 b/policycoreutils/semodule/semodule.8
index 4b52a63..5fc10b3 100644
--- a/policycoreutils/semodule/semodule.8
+++ b/policycoreutils/semodule/semodule.8
@@ -32,9 +32,6 @@ install/replace a module package
 .B  \-u,\-\-upgrade=MODULE_PKG
 upgrade an existing module package, or install if the module does not exist
 .TP
-.B  \-b,\-\-base=MODULE_PKG   
-install/replace base module package
-.TP
 .B  \-r,\-\-remove=MODULE_NAME
 remove existing module
 .TP
diff --git a/policycoreutils/semodule/semodule.c b/policycoreutils/semodule/semodule.c
index 569b808..c6b0d3c 100644
--- a/policycoreutils/semodule/semodule.c
+++ b/policycoreutils/semodule/semodule.c
@@ -1,8 +1,9 @@
 /* Authors: Karl MacMillan <kmacmillan@tresys.com>
  *          Joshua Brindle <jbrindle@tresys.com>
  *          Jason Tang <jtang@tresys.com>
+ *          Caleb Case <ccase@tresys.com>
  *
- * Copyright (C) 2004-2005 Tresys Technology, LLC
+ * Copyright (C) 2004-2005,2010 Tresys Technology, LLC
  *      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, version 2.
@@ -109,7 +110,6 @@ static void usage(char *progname)
 	printf("  -B, --build		    build and reload policy\n");
 	printf("  -i,--install=MODULE_PKG   install a new module\n");
 	printf("  -u,--upgrade=MODULE_PKG   upgrades or install module to a newer version\n");
-	printf("  -b,--base=MODULE_PKG      install new base module\n");
 	printf("  -r,--remove=MODULE_NAME   remove existing module\n");
 	printf("  -l,--list-modules=[KIND]  display list of installed modules\n");
 	printf("     KIND:  standard  list highest priority, enabled, non-base modules\n");
@@ -378,8 +378,8 @@ int main(int argc, char *argv[])
 					    ("Attempting to install base module '%s':\n",
 					     mode_arg);
 				}
-				result =
-				    semanage_module_install_base_file(sh, mode_arg);
+				fprintf(stderr, "Error: attempting to install deprecated base module.\n");
+				result = -1;
 				break;
 			}
 		case REMOVE_M:{
-- 
1.6.3.3


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 10/15] [src-policy] libsemanage: get source module
  2010-01-26 22:08                 ` [PATCH 09/15] [src-policy] semodule: remove base module support Caleb Case
@ 2010-01-26 22:08                   ` Caleb Case
  2010-01-26 22:08                     ` [PATCH 11/15] [src-policy] semodule: get module source Caleb Case
  0 siblings, 1 reply; 34+ messages in thread
From: Caleb Case @ 2010-01-26 22:08 UTC (permalink / raw)
  To: selinux; +Cc: csellers, kmacmillan, jwcart2, jbrindle, sds, Caleb Case

This provides the semanage_module_get and semanage_module_get_cil
interfaces for retrieving the original source module and the
intermediate compilation result. These functions are exported in the
private API so that they can be used by semodule.
---
 libsemanage/include/semanage/private/modules.h |   28 +++++-
 libsemanage/src/direct_api.c                   |  150 ++++++++++++++++++++++++
 libsemanage/src/libsemanage.map                |    2 +
 libsemanage/src/modules.c                      |   34 ++++++
 libsemanage/src/policy.h                       |   15 +++-
 5 files changed, 227 insertions(+), 2 deletions(-)

diff --git a/libsemanage/include/semanage/private/modules.h b/libsemanage/include/semanage/private/modules.h
index 2ffaa5b..8a2ed99 100644
--- a/libsemanage/include/semanage/private/modules.h
+++ b/libsemanage/include/semanage/private/modules.h
@@ -1,6 +1,6 @@
 /* Authors:	Caleb Case	<ccase@tresys.com>
  *
- * Copyright (C) 2009 Tresys Technology, LLC
+ * Copyright (C) 2009-2010 Tresys Technology, LLC
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -278,4 +278,30 @@ int semanage_module_upgrade_info(semanage_handle_t *sh,
 int semanage_module_remove_key(semanage_handle_t *sh,
 			       const semanage_module_key_t *modkey);
 
+/* Get the source for the module specified @modkey.
+ * @modkey must have key values filled in.
+ *
+ * Returns:
+ *	 0	success
+ *	-1	failure, out of memory
+ *	-2	failure, @modkey not found
+ */
+int semanage_module_get(semanage_handle_t *sh,
+			const semanage_module_key_t *modkey,
+			char **data,
+			size_t *data_len);
+
+/* Get the cil for the module specified @modkey.
+ * @modkey must have key values filled in.
+ *
+ * Returns:
+ *	 0	success
+ *	-1	failure, out of memory
+ *	-2	failure, @modkey not found
+ */
+int semanage_module_get_cil(semanage_handle_t *sh,
+			    const semanage_module_key_t *modkey,
+			    char **data,
+			    size_t *data_len);
+
 #endif
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index 6f7cf63..ee6f70f 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -92,6 +92,16 @@ static int semanage_direct_upgrade_info(semanage_handle_t *sh,
 static int semanage_direct_remove_key(semanage_handle_t *sh,
 				      const semanage_module_key_t *modkey);
 
+static int semanage_direct_get(semanage_handle_t *sh,
+			       const semanage_module_key_t *modkey,
+			       char **data,
+			       size_t *data_len);
+
+static int semanage_direct_get_cil(semanage_handle_t *sh,
+				   const semanage_module_key_t *modkey,
+				   char **data,
+				   size_t *data_len);
+
 static struct semanage_policy_table direct_funcs = {
 	.get_serial = semanage_direct_get_serial,
 	.destroy = semanage_direct_destroy,
@@ -113,6 +123,8 @@ static struct semanage_policy_table direct_funcs = {
 	.install_info = semanage_direct_install_info,
 	.upgrade_info = semanage_direct_upgrade_info,
 	.remove_key = semanage_direct_remove_key,
+	.get = semanage_direct_get,
+	.get_cil = semanage_direct_get_cil,
 };
 
 int semanage_direct_is_managed(semanage_handle_t * sh)
@@ -2498,3 +2510,141 @@ cleanup:
 	return status;
 }
 
+static int semanage_direct_get(semanage_handle_t *sh,
+			       const semanage_module_key_t *modkey,
+			       char **data,
+			       size_t *data_len)
+{
+	assert(sh);
+	assert(modkey);
+	assert(data);
+	assert(data_len);
+
+	int status = 0;
+	int ret = 0;
+
+	semanage_module_info_t *modinfo = NULL;
+	char path[PATH_MAX];
+	int fd = -1;
+
+	/* Get module info. */
+	ret = semanage_module_get_module_info(
+			sh,
+			modkey,
+			&modinfo);
+	if (ret != 0) {
+		status = -1;
+		goto cleanup;
+	}
+
+	/* Get module path source path. */
+	ret = semanage_module_get_path(
+			sh,
+			modinfo,
+			SEMANAGE_MODULE_PATH_HLL,
+			path,
+			sizeof(path));
+	if (ret != 0) {
+		status = -1;
+		goto cleanup;
+	}
+
+	/* Open file. */
+	fd = open(path, O_RDONLY);
+	if (fd < 0) {
+		ERR(sh, "Failed to open file %s.", path);
+		status = -2;
+		goto cleanup;
+	}
+
+	/* Read file into buffer. */
+	ret = semanage_fd_to_data(sh, fd, data, data_len);
+	if (ret != 0) {
+		status = ret;
+		goto cleanup;
+	}
+
+cleanup:
+	if (status != 0) {
+		free(*data);
+		*data = NULL;
+		*data_len = 0;
+	}
+
+	if (fd >= 0) close(fd);
+
+	semanage_module_info_destroy(sh, modinfo);
+	free(modinfo);
+
+	return status;
+}
+
+static int semanage_direct_get_cil(semanage_handle_t *sh,
+				   const semanage_module_key_t *modkey,
+				   char **data,
+				   size_t *data_len)
+{
+	assert(sh);
+	assert(modkey);
+	assert(data);
+	assert(data_len);
+
+	int status = 0;
+	int ret = 0;
+
+	semanage_module_info_t *modinfo = NULL;
+	char path[PATH_MAX];
+	int fd = -1;
+
+	/* Get module info. */
+	ret = semanage_module_get_module_info(
+			sh,
+			modkey,
+			&modinfo);
+	if (ret != 0) {
+		status = -1;
+		goto cleanup;
+	}
+
+	/* Get module path source path. */
+	ret = semanage_module_get_path(
+			sh,
+			modinfo,
+			SEMANAGE_MODULE_PATH_CIL,
+			path,
+			sizeof(path));
+	if (ret != 0) {
+		status = -1;
+		goto cleanup;
+	}
+
+	/* Open file. */
+	fd = open(path, O_RDONLY);
+	if (fd < 0) {
+		ERR(sh, "Failed to open file %s.", path);
+		status = -2;
+		goto cleanup;
+	}
+
+	/* Read file into buffer. */
+	ret = semanage_fd_to_data(sh, fd, data, data_len);
+	if (ret != 0) {
+		status = ret;
+		goto cleanup;
+	}
+
+cleanup:
+	if (status != 0) {
+		free(*data);
+		*data = NULL;
+		*data_len = 0;
+	}
+
+	if (fd >= 0) close(fd);
+
+	semanage_module_info_destroy(sh, modinfo);
+	free(modinfo);
+
+	return status;
+}
+
diff --git a/libsemanage/src/libsemanage.map b/libsemanage/src/libsemanage.map
index 1414ce5..64577a2 100644
--- a/libsemanage/src/libsemanage.map
+++ b/libsemanage/src/libsemanage.map
@@ -44,5 +44,7 @@ LIBSEMANAGE_1.0 {
 	  semanage_module_install_info;
 	  semanage_module_upgrade_info;
 	  semanage_module_remove_key;
+	  semanage_module_get;
+	  semanage_module_get_cil;
   local: *;
 };
diff --git a/libsemanage/src/modules.c b/libsemanage/src/modules.c
index be30517..85d4e99 100644
--- a/libsemanage/src/modules.c
+++ b/libsemanage/src/modules.c
@@ -1215,3 +1215,37 @@ int semanage_module_remove_key(semanage_handle_t *sh,
 	return sh->funcs->remove_key(sh, modkey);
 }
 
+int semanage_module_get(semanage_handle_t *sh,
+			const semanage_module_key_t *modkey,
+			char **data,
+			size_t *data_len)
+{
+	if (sh->funcs->get == NULL) {
+		ERR(sh,
+		    "No get function defined for this connection type.");
+		return -1;
+	} else if (!sh->is_connected) {
+		ERR(sh, "Not connected.");
+		return -1;
+	}
+
+	return sh->funcs->get(sh, modkey, data, data_len);
+}
+
+int semanage_module_get_cil(semanage_handle_t *sh,
+			    const semanage_module_key_t *modkey,
+			    char **data,
+			    size_t *data_len)
+{
+	if (sh->funcs->get_cil == NULL) {
+		ERR(sh,
+		    "No get cil function defined for this connection type.");
+		return -1;
+	} else if (!sh->is_connected) {
+		ERR(sh, "Not connected.");
+		return -1;
+	}
+
+	return sh->funcs->get_cil(sh, modkey, data, data_len);
+}
+
diff --git a/libsemanage/src/policy.h b/libsemanage/src/policy.h
index 397863f..d7047a3 100644
--- a/libsemanage/src/policy.h
+++ b/libsemanage/src/policy.h
@@ -1,7 +1,7 @@
 /* Author: Joshua Brindle <jbrindle@tresys.com>
  *         Jason Tang     <jtang@tresys.com>
  *
- * Copyright (C) 2005 Tresys Technology, LLC
+ * Copyright (C) 2005,2010 Tresys Technology, LLC
  * Copyright (C) 2005 Red Hat Inc.
  *
  *  This library is free software; you can redistribute it and/or
@@ -106,6 +106,19 @@ struct semanage_policy_table {
 	/* Remove via module key */
 	int (*remove_key) (struct semanage_handle *,
 			   const semanage_module_key_t *);
+
+	/* Get module source */
+	int (*get) (semanage_handle_t *,
+		    const semanage_module_key_t *,
+		    char **,
+		    size_t *);
+
+	/* Get module cil */
+	int (*get_cil) (semanage_handle_t *,
+			const semanage_module_key_t *,
+			char **,
+			size_t *);
+
 };
 
 /* Should be backend independent */
-- 
1.6.3.3


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 11/15] [src-policy] semodule: get module source
  2010-01-26 22:08                   ` [PATCH 10/15] [src-policy] libsemanage: get source module Caleb Case
@ 2010-01-26 22:08                     ` Caleb Case
  2010-01-26 22:08                       ` [PATCH 12/15] [src-policy] semodule: edit module Caleb Case
  2010-01-28 20:52                       ` [PATCH 11/15] [src-policy] semodule: get module source James Carter
  0 siblings, 2 replies; 34+ messages in thread
From: Caleb Case @ 2010-01-26 22:08 UTC (permalink / raw)
  To: selinux; +Cc: csellers, kmacmillan, jwcart2, jbrindle, sds, Caleb Case

This adds the ability to retrieve the module source using semodule.

  -g,--get=MODULE_NAME [-o FILE] [-c] get module source

* More than one -g is allowed per command invocation.

* If output_name is “-“ then output is sent to standard out.

* If output is specified multiple times with oufile_name "-", then
  append to stdout.

* If -o is not specified then the module is output to
  <module name>.<language ext> in the current directory.

* If there is an existing file with the output file name (with or
  without -o), then emit error and exit.

* -c will output the CIL instead of the source format.

Example:

# semodule -g alsa

This will retrieve the high level language source for the alsa module
and save it to alsa.ref in the current directory.
---
 policycoreutils/semodule/semodule.8 |    3 +
 policycoreutils/semodule/semodule.c |  227 ++++++++++++++++++++++++++++++++++-
 2 files changed, 228 insertions(+), 2 deletions(-)

diff --git a/policycoreutils/semodule/semodule.8 b/policycoreutils/semodule/semodule.8
index 5fc10b3..bb6ae49 100644
--- a/policycoreutils/semodule/semodule.8
+++ b/policycoreutils/semodule/semodule.8
@@ -55,6 +55,9 @@ enable module
 .B  \-d,\-\-disable=MODULE_NAME
 disable module
 .TP
+.B  \-g,\-\-get=MODULE_NAME [-o,--output=FILE] [-c,--cil]
+Outputs module source to MODULE_NAME.ref. If output is set to '-' outputs on stdout, otherwise, outputs to the specified FILE. If cil is specified, then outputs the cil source instead of the original source.
+.TP
 .B  \-s,\-\-store	   
 name of the store to operate on
 .TP
diff --git a/policycoreutils/semodule/semodule.c b/policycoreutils/semodule/semodule.c
index c6b0d3c..0e3cc76 100644
--- a/policycoreutils/semodule/semodule.c
+++ b/policycoreutils/semodule/semodule.c
@@ -20,6 +20,7 @@
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <limits.h>
 
 #include <semanage/modules.h>
 
@@ -27,17 +28,22 @@
 
 enum client_modes {
 	NO_MODE, INSTALL_M, UPGRADE_M, BASE_M, REMOVE_M,
-	LIST_M, RELOAD, PRIORITY_M, ENABLE_M, DISABLE_M
+	LIST_M, RELOAD, PRIORITY_M, ENABLE_M, DISABLE_M,
+	GET_M,
 };
+
 /* list of modes in which one ought to commit afterwards */
 static const int do_commit[] = {
 	0, 1, 1, 1, 1,
 	0, 0, 0, 1, 1,
+	0,
 };
 
 struct command {
 	enum client_modes mode;
 	char *arg;
+	char *output;
+	int cil;
 };
 static struct command *commands = NULL;
 static int num_commands = 0;
@@ -61,6 +67,7 @@ static void cleanup(void)
 {
 	while (--num_commands >= 0) {
 		free(commands[num_commands].arg);
+		free(commands[num_commands].output);
 	}
 	free(commands);
 }
@@ -117,6 +124,7 @@ static void usage(char *progname)
 	printf("  -p,--priority=PRIORITY    set priority for following operations (1-999)\n");
 	printf("  -e,--enable=MODULE_NAME   enable module\n");
 	printf("  -d,--disable=MODULE_NAME  disable module\n");
+	printf("  -g,--get=MODULE_NAME [-o FILE] [-c] get module source\n");
 	printf("Other options:\n");
 	printf("  -s,--store	   name of the store to operate on\n");
 	printf("  -n,--noreload	   do not reload policy after commit\n");
@@ -139,6 +147,8 @@ static void set_mode(enum client_modes new_mode, char *arg)
 	commands = c;
 	commands[num_commands].mode = new_mode;
 	commands[num_commands].arg = NULL;
+	commands[num_commands].output = NULL;
+	commands[num_commands].cil = 0;
 	num_commands++;
 	if (arg != NULL) {
 		if ((s = strdup(arg)) == NULL) {
@@ -169,6 +179,9 @@ static void parse_command_line(int argc, char **argv)
 		{"priority", required_argument, NULL, 'p'},
 		{"enable", required_argument, NULL, 'e'},
 		{"disable", required_argument, NULL, 'd'},
+		{"get", required_argument, NULL, 'g'},
+		{"output", required_argument, NULL, 'o'},
+		{"cil", 0, NULL, 'c'},
 		{NULL, 0, NULL, 0}
 	};
 	int i;
@@ -178,7 +191,7 @@ static void parse_command_line(int argc, char **argv)
 	create_store = 0;
 	priority = 400;
 	while ((i =
-		getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnBDp:e:d:", opts,
+		getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnBDp:e:d:g:o:c", opts,
 			    NULL)) != -1) {
 		switch (i) {
 		case 'b':
@@ -227,6 +240,53 @@ static void parse_command_line(int argc, char **argv)
 		case 'd':
 			set_mode(DISABLE_M, optarg);
 			break;
+		case 'g':
+			set_mode(GET_M, optarg);
+			break;
+		case 'o':{
+			/* no mode specified?? */
+			if (num_commands == 0) {
+				usage(argv[0]);
+				exit(1);
+			}
+
+			struct command *last = &commands[num_commands - 1];
+
+			/* only GET_M mode valid with -o */
+			if (last->mode != GET_M) {
+				usage(argv[0]);
+				exit(1);
+			}
+
+			last->output = strdup(optarg);
+			if (last->output == NULL) {
+				fprintf(stderr,
+					"%s: Out of memory!\n",
+					argv[0]);
+				exit(1);
+			}
+
+			break;
+			}
+		case 'c':{
+			/* no mode specified?? */
+			if (num_commands == 0) {
+				usage(argv[0]);
+				exit(1);
+			}
+
+			struct command *last = &commands[num_commands - 1];
+
+			/* only GET_M mode valid with -c */
+			if (last->mode != GET_M) {
+				usage(argv[0]);
+				exit(1);
+			}
+
+			last->cil = 1;
+
+			break;
+			}
 		case '?':
 		default:{
 				usage(argv[0]);
@@ -350,6 +410,8 @@ int main(int argc, char *argv[])
 	for (i = 0; i < num_commands; i++) {
 		enum client_modes mode = commands[i].mode;
 		char *mode_arg = commands[i].arg;
+		char *mode_output = commands[i].output;
+		int mode_cil = commands[i].cil;
 
 		switch (mode) {
 		case INSTALL_M:{
@@ -582,6 +644,167 @@ cleanup_disable:
 
 				break;
 			}
+		case GET_M:{
+				if (verbose) {
+					printf("Attempting to get module '%s':\n", mode_arg);
+				}
+
+				semanage_module_key_t *modkey = NULL;
+				semanage_module_info_t *modinfo = NULL;
+				const char *lang_ext = NULL;
+				char *data = NULL;
+				size_t data_len = 0;
+
+				int fd = -1;
+				FILE *out = NULL;
+				size_t nwrite = 0;
+
+				result = semanage_module_key_create(sh,
+								    &modkey);
+				if (result != 0) goto cleanup_get;
+
+				result = semanage_module_key_set_priority(
+						sh,
+						modkey,
+						priority);
+				if (result != 0) goto cleanup_get;
+
+				result = semanage_module_key_set_name(
+						sh,
+						modkey,
+						mode_arg);
+				if (result != 0) goto cleanup_get;
+
+				if (mode_cil == 0) {
+					result = semanage_module_get(
+							sh,
+							modkey,
+							&data,
+							&data_len);
+				}
+				else {
+					result = semanage_module_get_cil(
+							sh,
+							modkey,
+							&data,
+							&data_len);
+				}
+				if (result != 0) goto cleanup_get;
+
+				/* get language extension */
+				result = semanage_module_get_module_info(
+						sh,
+						modkey,
+						&modinfo);
+				if (result != 0) goto cleanup_get;
+
+				if (mode_cil == 0) {
+					result = semanage_module_info_get_lang_ext(
+							sh,
+							modinfo,
+							&lang_ext);
+					if (result != 0) goto cleanup_get;
+				}
+				else {
+					/* current cil is refpol */
+					lang_ext = "ref";
+				}
+
+				if (mode_output == NULL ||
+				    strcmp(mode_output, "-") != 0) {
+					char path[PATH_MAX];
+
+					if (mode_output == NULL) {
+						/* by default write out to <name>.<lang> */
+						/* compose path */
+
+						result = snprintf(path,
+								  sizeof(path) - 1,
+								  "%s.%s",
+								  mode_arg,
+								  lang_ext);
+						if (result < 0 ||
+						    result >= (int)sizeof(path)) {
+							fprintf(stderr,
+								"%s: Unable to compose path for output file.\n",
+								argv[0]);
+							result = -1;
+							goto cleanup_get;
+						}
+						result = 0;
+					}
+					else {
+						if (strlen(mode_output) > sizeof(path) - 1) {
+							fprintf(stderr,
+								"%s: Path too long (%d > %d): '%s'\n",
+								argv[0],
+								strlen(mode_output),
+								sizeof(path) - 1,
+								mode_output);
+							result = -1;
+							goto cleanup_get;
+						}
+						strcpy(path, mode_output);
+					}
+
+					/* open file iff it doesn't exist */
+					fd = open(path,
+						  O_WRONLY | O_CREAT | O_EXCL,
+						  S_IRUSR | S_IWUSR);
+					if (fd < 0) {
+						fprintf(stderr,
+							"%s: Unable to open output '%s'. (%s)\n",
+							argv[0],
+							path,
+							strerror(errno));
+						result = -1;
+						goto cleanup_get;
+					}
+
+					out = fdopen(fd, "w");
+					if (out == NULL) {
+						fprintf(stderr,
+							"%s: Unable to open output '%s'. (%s)\n",
+							argv[0],
+							path,
+							strerror(errno));
+						result = -1;
+						goto cleanup_get;
+					}
+				}
+				else {
+					/* otherwise we must be special '-' */
+					out = stdout;
+				}
+
+				nwrite = fwrite(data,
+						data_len,
+						1,
+						out);
+				if (nwrite != 1) {
+					fprintf(stderr,
+						"%s: Failed to write module to output.\n",
+						argv[0]);
+					result = -1;
+					goto cleanup_get;
+				}
+
+cleanup_get:
+				if (out != NULL && out != stdout) {
+					fclose(out);
+					fd = -1;
+				}
+				if (fd >= 0) close(fd);
+				free(data);
+
+				semanage_module_info_destroy(sh, modinfo);
+				free(modinfo);
+
+				semanage_module_key_destroy(sh, modkey);
+				free(modkey);
+
+				break;
+			}
 		default:{
 				fprintf(stderr,
 					"%s:  Unknown mode specified.\n",
-- 
1.6.3.3


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 12/15] [src-policy] semodule: edit module
  2010-01-26 22:08                     ` [PATCH 11/15] [src-policy] semodule: get module source Caleb Case
@ 2010-01-26 22:08                       ` Caleb Case
  2010-01-26 22:08                         ` [PATCH 13/15] [src-policy] libsemanage: ChangeLog support Caleb Case
  2010-01-27 20:21                         ` [PATCH 12/15] [src-policy] semodule: edit module Stephen Smalley
  2010-01-28 20:52                       ` [PATCH 11/15] [src-policy] semodule: get module source James Carter
  1 sibling, 2 replies; 34+ messages in thread
From: Caleb Case @ 2010-01-26 22:08 UTC (permalink / raw)
  To: selinux; +Cc: csellers, kmacmillan, jwcart2, jbrindle, sds, Caleb Case

In order to ease the process of modifying an installed module, this
provides the -E,--edit option to semodule. It will retrieve the
specified module, open it in the default editor, and then reinstall the
module if editing completes successfully.

* Editor to be executed is discovered from the EDITOR environment
  variable.

* Transaction locks are held for the duration of the editing.

* If -E is specified multiple times, then the editor will be
  called on each one, consecutively (editing stops on a particular
  module when the editor exits).

* If the editor exits with a non-zero status, then the transaction
  will be aborted.

* If the editor exits without making any changes to the file (as
  determined from the time stamp), then the transaction will be not be
  committed unless another action requires it to be.

* The editor will be executed in the users SELinux context (as
  determined by getprevcon)

Example:

# export EDITOR=vim
# semodule -E alsa
<edit alsa module>
<after quiting editor module is installed>
---
 policycoreutils/semodule/semodule.8 |   18 +++
 policycoreutils/semodule/semodule.c |  289 ++++++++++++++++++++++++++++++++++-
 2 files changed, 304 insertions(+), 3 deletions(-)

diff --git a/policycoreutils/semodule/semodule.8 b/policycoreutils/semodule/semodule.8
index bb6ae49..8baad8b 100644
--- a/policycoreutils/semodule/semodule.8
+++ b/policycoreutils/semodule/semodule.8
@@ -58,6 +58,24 @@ disable module
 .B  \-g,\-\-get=MODULE_NAME [-o,--output=FILE] [-c,--cil]
 Outputs module source to MODULE_NAME.ref. If output is set to '-' outputs on stdout, otherwise, outputs to the specified FILE. If cil is specified, then outputs the cil source instead of the original source.
 .TP
+.B  \-E,\-\-edit=MODULE_NAME
+Retrieves the specified module, open it in the default editor, and then reinstall the module if editing completes successfully.
+.TP
+.RS
+.IP \[bu]
+Editor to be executed is discovered from the EDITOR environment variable.
+.IP \[bu]
+Transaction locks are held for the duration of the editing.
+.IP \[bu]
+If -E is specified multiple times, then the editor will be called on each one, consecutively (editing stops on a particular module when the editor exits).
+.IP \[bu]
+If the editor exits with a non-zero status, then the transaction will be aborted.
+.IP \[bu]
+If the editor exits without making any changes to the file (as determined from the time stamp), then the transaction will be not be committed unless another action requires it to be.
+.IP \[bu]
+The editor will be executed in the users SELinux context (as determined by getprevcon).
+.RE
+.TP
 .B  \-s,\-\-store	   
 name of the store to operate on
 .TP
diff --git a/policycoreutils/semodule/semodule.c b/policycoreutils/semodule/semodule.c
index 0e3cc76..3536253 100644
--- a/policycoreutils/semodule/semodule.c
+++ b/policycoreutils/semodule/semodule.c
@@ -21,6 +21,8 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <limits.h>
+#include <sys/wait.h>
+#include <selinux/selinux.h>
 
 #include <semanage/modules.h>
 
@@ -29,14 +31,14 @@
 enum client_modes {
 	NO_MODE, INSTALL_M, UPGRADE_M, BASE_M, REMOVE_M,
 	LIST_M, RELOAD, PRIORITY_M, ENABLE_M, DISABLE_M,
-	GET_M,
+	GET_M, EDIT_M,
 };
 
 /* list of modes in which one ought to commit afterwards */
 static const int do_commit[] = {
 	0, 1, 1, 1, 1,
 	0, 0, 0, 1, 1,
-	0,
+	0, 1,
 };
 
 struct command {
@@ -125,6 +127,7 @@ static void usage(char *progname)
 	printf("  -e,--enable=MODULE_NAME   enable module\n");
 	printf("  -d,--disable=MODULE_NAME  disable module\n");
 	printf("  -g,--get=MODULE_NAME [-o FILE] [-c] get module source\n");
+	printf("  -E,--edit=MODULE_NAME     open the module in the users EDITOR\n");
 	printf("Other options:\n");
 	printf("  -s,--store	   name of the store to operate on\n");
 	printf("  -n,--noreload	   do not reload policy after commit\n");
@@ -182,6 +185,7 @@ static void parse_command_line(int argc, char **argv)
 		{"get", required_argument, NULL, 'g'},
 		{"output", required_argument, NULL, 'o'},
 		{"cil", 0, NULL, 'c'},
+		{"edit", required_argument, NULL, 'E'},
 		{NULL, 0, NULL, 0}
 	};
 	int i;
@@ -191,7 +195,7 @@ static void parse_command_line(int argc, char **argv)
 	create_store = 0;
 	priority = 400;
 	while ((i =
-		getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnBDp:e:d:g:o:c", opts,
+		getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnBDp:e:d:g:o:cE:", opts,
 			    NULL)) != -1) {
 		switch (i) {
 		case 'b':
@@ -287,6 +291,9 @@ static void parse_command_line(int argc, char **argv)
 
 			break;
 			}
+		case 'E':
+			set_mode(EDIT_M, optarg);
+			break;
 		case '?':
 		default:{
 				usage(argv[0]);
@@ -805,6 +812,282 @@ cleanup_get:
 
 				break;
 			}
+		case EDIT_M:{
+				if (verbose) {
+					printf("Attempting to edit module '%s':\n", mode_arg);
+				}
+
+				semanage_module_key_t *modkey = NULL;
+				semanage_module_info_t *modinfo = NULL;
+				char *data = NULL;
+				size_t data_len = 0;
+
+				int fd = -1;
+				ssize_t nwrite = 0;
+				ssize_t nread = 0;
+
+				char tmp[] = "/tmp/semodule-XXXXXX";
+
+				pid_t pid;
+
+				struct stat sb;
+				time_t mtime;
+
+				/* get module source */
+				result = semanage_module_key_create(sh,
+								    &modkey);
+				if (result != 0) goto cleanup_edit;
+
+				result = semanage_module_key_set_priority(
+						sh,
+						modkey,
+						priority);
+				if (result != 0) goto cleanup_edit;
+
+				result = semanage_module_key_set_name(
+						sh,
+						modkey,
+						mode_arg);
+				if (result != 0) goto cleanup_edit;
+
+				result = semanage_module_get_module_info(
+						sh,
+						modkey,
+						&modinfo);
+				if (result != 0) goto cleanup_edit;
+
+				result = semanage_module_get(
+						sh,
+						modkey,
+						&data,
+						&data_len);
+				if (result != 0) goto cleanup_edit;
+
+				fd = mkstemp(tmp);
+				if (fd < 0) {
+					fprintf(stderr,
+						"%s: Unable to make temp file '%s'. (%s)\n",
+						argv[0],
+						tmp,
+						strerror(errno));
+					result = -1;
+					goto cleanup_get;
+				}
+
+				/* write out to temporary file */
+				while((size_t)nwrite != data_len) {
+					nwrite = write(fd,
+						       data + nwrite,
+						       data_len - nwrite);
+					if (nwrite < 0) {
+						fprintf(stderr,
+							"%s: Failed to write module to %s. (%s)\n",
+							argv[0],
+							tmp,
+							strerror(errno));
+						result = -1;
+						goto cleanup_edit;
+					}
+				}
+
+				result = fsync(fd);
+				if (result != 0) {
+					fprintf(stderr,
+						"%s: Failed to sync module to %s. (%s)\n",
+						argv[0],
+						tmp,
+						strerror(errno));
+					result = -1;
+					goto cleanup_edit;
+				}
+
+				/* get mod time for change detection */
+				result = fstat(fd, &sb);
+				if (result != 0) {
+					fprintf(stderr,
+						"%s: Failed to stat tmp file '%s'. (%s)\n",
+						argv[0],
+						tmp,
+						strerror(errno));
+					result = -1;
+					goto cleanup_edit;
+				}
+				mtime = sb.st_mtime;
+
+				close(fd);
+				fd = -1;
+
+				/* fork and execute editor */
+				pid = fork();
+				if (pid < 0) {
+					fprintf(stderr,
+						"%s: Failed to fork. (%s)\n",
+						argv[0],
+						strerror(errno));
+					result = -1;
+					goto cleanup_edit;
+				}
+
+				if (pid == 0) {		/* child */
+					char *cmd = getenv("EDITOR");
+					if (cmd == NULL) {
+						fprintf(stderr,
+							"%s: EDITOR not set!\n",
+							argv[0]);
+						exit(EXIT_FAILURE);
+					}
+
+					char **cargv = calloc(3, sizeof(char *));
+
+					cargv[0] = strdup(cmd);
+					if (cargv[0] == NULL) {
+						fprintf(stderr,
+							"%s: Out of memory!\n",
+							argv[0]);
+						exit(EXIT_FAILURE);
+					}
+
+					cargv[1] = strdup(tmp);
+					if (cargv[1] == NULL) {
+						fprintf(stderr,
+							"%s: Out of memory!\n",
+							argv[0]);
+						exit(EXIT_FAILURE);
+					}
+
+					security_context_t prevcon = NULL;
+
+					result = getprevcon(&prevcon);
+					if (result != 0) {
+						fprintf(stderr,
+							"%s: Failed to get previous context.\n",
+							argv[0]);
+						exit(EXIT_FAILURE);
+					}
+
+					result = setexeccon(prevcon);
+					if (result != 0) {
+						fprintf(stderr,
+							"%s: Failed to change context to: %s\n",
+							argv[0],
+							prevcon);
+						exit(EXIT_FAILURE);
+					}
+
+					result = execvp(cmd, cargv);
+					if (result != 0) {
+						fprintf(stderr,
+							"%s: Failed to execute editor '%s'. (%s)\n",
+							argv[0],
+							cmd,
+							strerror(errno));
+						exit(EXIT_FAILURE);
+					}
+				}
+
+				/* parent */
+				/* wait for child process to finish */
+				pid = wait(&result);
+				if (pid < 0) {
+					result = -1;
+					goto cleanup_edit;
+				}
+
+				if (WIFEXITED(result)) {
+					result = 0;
+				}
+				else {
+					result = -1;
+					goto cleanup_edit;
+				}
+
+				/* read the module into a buffer */
+				fd = open(tmp, O_RDONLY);
+				if (fd < 0) {
+					fprintf(stderr,
+						"%s: Failed to reopen tmp file '%s'. (%s)\n",
+						argv[0],
+						tmp,
+						strerror(errno));
+					result = -1;
+					goto cleanup_edit;
+				}
+
+				result = fstat(fd, &sb);
+				if (result != 0) {
+					fprintf(stderr,
+						"%s: Failed to stat tmp file '%s'. (%s)\n",
+						argv[0],
+						tmp,
+						strerror(errno));
+					result = -1;
+					goto cleanup_edit;
+				}
+				data_len = sb.st_size;
+
+				/* if not modified,
+				 * then don't commit or install
+				 */
+				if (mtime == sb.st_mtime) {
+					commit--;
+					goto cleanup_edit;
+				}
+
+				/* allocate a buffer for module */
+				free(data);
+				data = malloc(data_len);
+				if (data == NULL) {
+					fprintf(stderr,
+						"%s: Out of memory!\n",
+						argv[0]);
+					result = -1;
+					goto cleanup_edit;
+				}
+
+				/* read the module into the buffer */
+				while ((size_t)nread != data_len) {
+					nread = read(fd,
+						     data + nread,
+						     data_len - nread);
+					if (nread < 0) {
+						fprintf(stderr,
+							"%s: Failed to read in the tmp file '%s'. (%s)\n",
+							argv[0],
+							tmp,
+							strerror(errno));
+						result = -1;
+						goto cleanup_edit;
+					}
+				}
+
+				/* reinstall the module */
+				result = semanage_module_install_info(
+						sh,
+						modinfo,
+						data,
+						data_len);
+				if (result != 0) {
+					result = -1;
+					goto cleanup_edit;
+				}
+
+cleanup_edit:
+				/* don't commit if there was an error */
+				if (result != 0) commit--;
+
+				unlink(tmp);
+
+				if (fd >= 0) close(fd);
+				free(data);
+
+				semanage_module_info_destroy(sh, modinfo);
+				free(modinfo);
+
+				semanage_module_key_destroy(sh, modkey);
+				free(modkey);
+
+				break;
+			}
 		default:{
 				fprintf(stderr,
 					"%s:  Unknown mode specified.\n",
-- 
1.6.3.3


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 13/15] [src-policy] libsemanage: ChangeLog support
  2010-01-26 22:08                       ` [PATCH 12/15] [src-policy] semodule: edit module Caleb Case
@ 2010-01-26 22:08                         ` Caleb Case
  2010-01-26 22:08                           ` [PATCH 14/15] [src-policy] semodule: user message support Caleb Case
  2010-01-27 20:21                         ` [PATCH 12/15] [src-policy] semodule: edit module Stephen Smalley
  1 sibling, 1 reply; 34+ messages in thread
From: Caleb Case @ 2010-01-26 22:08 UTC (permalink / raw)
  To: selinux; +Cc: csellers, kmacmillan, jwcart2, jbrindle, sds, Caleb Case

In order to facilitate better policy modification accountability, this
adds support to libsemanage for a ChangeLog. The ChangeLog is located at
/var/lib/selinux/.../modules/ChangeLog. Each line of the ChangeLog
contains the version of the store (e.g., the commit number), command
run, username, selinux context, time stamp, and a user specified
message:

VERSION="12" COMMAND="semodule -E alsa" USERNAME="root"
CONTEXT="unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c255" TIME="Tue
Jan 19 01:16:59 2010" MESSAGE="Allow alsa to launch cowsay."

The following functions are exported as part of the private api to
facilitate logging:

	semanage_get_log_message
	semanage_set_log_message
	semanage_get_log_command
	semanage_set_log_command

These allow library users to specify the user message and, if necessary,
the command used. If the command is not set manually, we attempt to
determine it by reading /proc/self/cmdline.

While we have chosen a file format for the ChangLog the long term goal
is to provide a interface to the ChangeLog that is agnostic to its
storage. This will permit integration of the ChangeLog into SCM's such
as git.
---
 libsemanage/include/semanage/private/handle.h |   31 +++-
 libsemanage/src/direct_api.c                  |  242 ++++++++++++++++++++++++-
 libsemanage/src/handle.c                      |   55 ++++++
 libsemanage/src/handle.h                      |    3 +
 libsemanage/src/libsemanage.map               |    4 +
 libsemanage/src/semanage_store.c              |    1 +
 libsemanage/src/semanage_store.h              |    1 +
 7 files changed, 335 insertions(+), 2 deletions(-)

diff --git a/libsemanage/include/semanage/private/handle.h b/libsemanage/include/semanage/private/handle.h
index 6efd664..da8842f 100644
--- a/libsemanage/include/semanage/private/handle.h
+++ b/libsemanage/include/semanage/private/handle.h
@@ -1,6 +1,6 @@
 /* Authors:	Caleb Case	<ccase@tresys.com>
  *
- * Copyright (C) 2009 Tresys Technology, LLC
+ * Copyright (C) 2009-2010 Tresys Technology, LLC
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -28,4 +28,33 @@ uint16_t semanage_get_default_priority(semanage_handle_t *sh);
 /* Set the default priority. */
 int semanage_set_default_priority(semanage_handle_t *sh, uint16_t priority);
 
+/* Sets the message to log for the next commit.
+ * After a successful commit the message is cleared.
+ *
+ * Returns:
+ *	 0	success
+ *	-1	failure, out of memory
+ *	-2	failure, message too long
+ */
+int semanage_set_log_message(semanage_handle_t *sh, const char *msg);
+
+/* Returns the message that will be logged if one was set otherwise NULL. */
+const char *semanage_get_log_message(semanage_handle_t *sh);
+
+/* Sets the command to log for the next commit.
+ * After a successful commit the command is cleared.
+ *
+ * If the command hasn't been set (NULL or empty string)
+ * it will be automatically generated by attempting to
+ * read from /proc/self/cmdline during the commit process.
+ * 
+ * Returns:
+ *	 0	success
+ *	-1	failure, out of memory
+ */
+int semanage_set_log_command(semanage_handle_t *sh, const char *cmd);
+
+/* Returns the command that will be logged if one was set otherwise NULL. */
+const char *semanage_get_log_command(semanage_handle_t *sh);
+
 #endif
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index ee6f70f..b807e16 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -35,6 +35,9 @@
 #include <limits.h>
 #include <errno.h>
 #include <dirent.h>
+#include <pwd.h>
+#include <time.h>
+#include <ctype.h>
 
 #include "user_internal.h"
 #include "seuser_internal.h"
@@ -758,6 +761,238 @@ cleanup:
 	return status;
 }
 
+/* Escape non priteable, ", and \ characters. */
+static int semanage_stresc(semanage_handle_t *sh,
+			   const char *str,
+			   char **escaped)
+{
+	assert(sh);
+	assert(str);
+	assert(escaped);
+
+	int status = 0;
+
+	size_t str_len = strlen(str);
+	size_t unescaped = 0;
+	size_t i, k;
+
+#define SPECIAL(c) (!isprint(c) || c == '\\' || c == '\"')
+
+	/* Find all specials in @str. */
+	for (i = 0; i < str_len; i++) {
+		if (SPECIAL(str[i])) {
+			/* Found special. */
+			unescaped++;
+			break;
+		}
+	}
+
+	/* Any unescaped? If not degrade to strdup. */
+	if (unescaped != 0) {
+		/* Create tmp space for escaped string. */
+		size_t tmp_len = str_len + unescaped + 1;
+		char tmp[tmp_len];
+
+		for (i = 0, k = 0; i < str_len; i++, k++) {
+			if (SPECIAL(str[i])) {
+				/* Found special. Escape it. */
+				tmp[k] = '\\';
+				k++;
+				break;
+			}
+			tmp[k] = str[i];
+		}
+		tmp[tmp_len - 1] = '\0'; /* Null terminate! */
+
+		*escaped = malloc(tmp_len);
+		if (*escaped == NULL) {
+			ERR(sh, "Out of memory!");
+			status = -1;
+			goto cleanup;
+		}
+
+		memcpy(*escaped, tmp, tmp_len);
+	}
+	else {
+		*escaped = malloc(str_len + 1);
+		if (*escaped == NULL) {
+			ERR(sh, "Out of memory!");
+			status = -1;
+			goto cleanup;
+		}
+
+		memcpy(*escaped, str, str_len + 1);
+	}
+
+#undef SPECIAL
+
+cleanup:
+	return status;
+}
+
+/* Update ChangeLog */
+static int semanage_direct_changelog(semanage_handle_t *sh)
+{
+	assert(sh);
+
+	int status = 0;
+	int ret = 0;
+
+	int version = 0;
+	char *command = NULL;
+	char *command_escaped = NULL;
+	char *username = NULL;
+	security_context_t context = NULL;
+	char *timestr = NULL;
+	char *message_escaped = NULL;
+
+	ssize_t size = 0;
+	FILE *cmdline = NULL;
+	struct passwd *pw = NULL;
+	time_t timep;
+	const char *changelog_path = NULL;
+	FILE *changelog = NULL;
+
+	/* calculate version from commit number */
+	ret = semanage_direct_get_serial(sh);
+	if (ret < 0) {
+		status = -1;
+		goto cleanup;
+	}
+	version = ret + 1;
+
+	/* compute command if it wasn't provided */
+	if (sh->log_command == NULL || sh->log_command[0] == '\0') {
+		command = NULL;
+		size_t command_len = 0;
+
+		cmdline = fopen("/proc/self/cmdline", "r");
+		if (cmdline == NULL) {
+			ERR(sh,
+			    "Failed to open command line from /proc/self/cmdline.");
+			status = -1;
+			goto cleanup;
+		}
+
+		size = getline(&command, &command_len, cmdline);
+		if (size < 0) {
+			ERR(sh,
+			    "Failed to read command line from /proc/self/cmdline.");
+			status = -1;
+			goto cleanup;
+		}
+
+		/* change all '\0' to ' ' */
+		int i;
+		for (i = 0; i < size - 1; i++) {
+			if (command[i] == '\0') {
+				command[i] = ' ';
+			}
+		}
+
+		ret = semanage_stresc(sh, command, &command_escaped);
+		if (ret != 0) {
+			status = -1;
+			goto cleanup;
+		}
+
+		fclose(cmdline);
+		cmdline = NULL;
+	}
+	else {
+		ret = semanage_stresc(sh, sh->log_command, &command_escaped);
+		if (ret != 0) {
+			status = -1;
+			goto cleanup;
+		}
+	}
+
+	/* discover username */
+	pw = getpwuid(getuid());
+	if (pw == NULL) {
+		ERR(sh, "Failed to find username for uid %d.", getuid());
+		status = -1;
+		goto cleanup;
+	}
+
+	username = strdup(pw->pw_name);
+	if (username == NULL) {
+		ERR(sh, "Out of Memory!");
+		status = -1;
+		goto cleanup;
+	}
+
+	/* get the previous selinux context */
+	ret = getprevcon(&context);
+	if (ret < 0) {
+		ERR(sh, "Out of Memory!");
+		status = -1;
+		goto cleanup;
+	}
+
+	/* get the current time */
+	ret = time(&timep);
+	if (ret < 0) {
+		ERR(sh, "Failed to get the current time.");
+		status = -1;
+		goto cleanup;
+	}
+
+	timestr = ctime(&timep);
+	if (timestr == NULL) {
+		ERR(sh, "Failed to get the current time.");
+		status = -1;
+		goto cleanup;
+	}
+
+	timestr[strlen(timestr) - 1] = '\0'; /* remove trailing newline */
+
+	/* get the user message */
+	if (sh->log_message != NULL) {
+		ret = semanage_stresc(sh, sh->log_message, &message_escaped);
+		if (ret != 0) {
+			status = -1;
+			goto cleanup;
+		}
+	}
+
+	/* append to changelog */
+	changelog_path = semanage_path(SEMANAGE_TMP, SEMANAGE_CHANGELOG);
+
+	changelog = fopen(changelog_path, "a");
+	if (changelog == NULL) {
+		ERR(sh, "Failed to open ChangeLog '%s'.", changelog_path);
+		status = -1;
+		goto cleanup;
+	}
+
+	ret = fprintf(changelog,
+		      "VERSION=\"%d\" COMMAND=\"%s\" USERNAME=\"%s\" CONTEXT=\"%s\" TIME=\"%s\" MESSAGE=\"%s\"\n",
+		      version,
+		      command_escaped,
+		      username,
+		      context,
+		      timestr,
+		      message_escaped ? message_escaped : "");
+	if (ret < 0) {
+		ERR(sh, "Failed to append to ChangeLog '%s'.", changelog_path);
+		status = -1;
+		goto cleanup;
+	}
+
+cleanup:
+	if (changelog != NULL) fclose(changelog);
+	if (cmdline != NULL) fclose(cmdline);
+
+	free(message_escaped);
+	freecon(context);
+	free(username);
+	free(command_escaped);
+	free(command);
+
+	return status;
+}
+
 /********************* direct API functions ********************/
 
 /* Commits all changes in sandbox to the actual kernel policy.
@@ -1071,6 +1306,10 @@ static int semanage_direct_commit(semanage_handle_t * sh)
 	sepol_policydb_free(out);
 	out = NULL;
 
+	/* update ChangeLog */
+	retval = semanage_direct_changelog(sh);
+	if (retval != 0) goto cleanup;
+
 	if (sh->do_rebuild || modified || 
 	    seusers_modified || fcontexts_modified || users_extra_modified) {
 		retval = semanage_install_sandbox(sh);
@@ -2018,7 +2257,8 @@ static int semanage_priorities_filename_select(const struct dirent *d)
 {
 	if (d->d_name[0] == '.' ||
 	    strcmp(d->d_name, "disabled") == 0 ||
-	    strcmp(d->d_name, "log") == 0)
+	    strcmp(d->d_name, "log") == 0 ||
+	    strcmp(d->d_name, "ChangeLog") == 0)
 		return 0;
 	return 1;
 }
diff --git a/libsemanage/src/handle.c b/libsemanage/src/handle.c
index 71c3165..fbfc522 100644
--- a/libsemanage/src/handle.c
+++ b/libsemanage/src/handle.c
@@ -83,6 +83,10 @@ semanage_handle_t *semanage_handle_create(void)
 	/* By default do not create store */
 	sh->create_store = 0;
 
+	/* By default no message or command set */
+	sh->log_message = NULL;
+	sh->log_command = NULL;
+
 	/* Set timeout: some default value for now, later use config */
 	sh->timeout = SEMANAGE_COMMIT_READ_WAIT;
 
@@ -300,6 +304,9 @@ void semanage_handle_destroy(semanage_handle_t * sh)
 	if (sh->funcs != NULL && sh->funcs->destroy != NULL)
 		sh->funcs->destroy(sh);
 
+	free(sh->log_message);
+	free(sh->log_command);
+
 	semanage_lang_conf_list_t *head = sh->lang_conf_list;
 	semanage_lang_conf_list_t *next = NULL;
 	while (head != NULL) {
@@ -316,6 +323,54 @@ void semanage_handle_destroy(semanage_handle_t * sh)
 
 hidden_def(semanage_handle_destroy)
 
+int semanage_set_log_message(semanage_handle_t *sh, const char *msg)
+{
+	assert(sh);
+	assert(msg);
+
+	int status = 0;
+
+	sh->log_message = strdup(msg);
+	if (sh->log_message == NULL) {
+		ERR(sh, "Out of memory!");
+		status = -1;
+		goto cleanup;
+	}
+
+cleanup:
+	return status;
+}
+
+const char *semanage_get_log_message(semanage_handle_t *sh)
+{
+	assert(sh);
+	return sh->log_message;
+}
+
+int semanage_set_log_command(semanage_handle_t *sh, const char *cmd)
+{
+	assert(sh);
+	assert(cmd);
+
+	int status = 0;
+
+	sh->log_command = strdup(cmd);
+	if (sh->log_command == NULL) {
+		ERR(sh, "Out of memory!");
+		status = -1;
+		goto cleanup;
+	}
+
+cleanup:
+	return status;
+}
+
+const char *semanage_get_log_command(semanage_handle_t *sh)
+{
+	assert(sh);
+	return sh->log_command;
+}
+
 /********************* public transaction functions *********************/
 int semanage_begin_transaction(semanage_handle_t * sh)
 {
diff --git a/libsemanage/src/handle.h b/libsemanage/src/handle.h
index 0f8794a..9ed90a9 100644
--- a/libsemanage/src/handle.h
+++ b/libsemanage/src/handle.h
@@ -69,6 +69,9 @@ struct semanage_handle {
 				 * this will only have an effect on direct connections */
 	int do_check_contexts;	/* whether to run setfiles check the file contexts file */
 
+	char *log_message;
+	char *log_command;
+
 	/* This timeout is used for transactions and waiting for lock
 	   -1 means wait indefinetely
 	   0 means return immediately
diff --git a/libsemanage/src/libsemanage.map b/libsemanage/src/libsemanage.map
index 64577a2..90f7238 100644
--- a/libsemanage/src/libsemanage.map
+++ b/libsemanage/src/libsemanage.map
@@ -46,5 +46,9 @@ LIBSEMANAGE_1.0 {
 	  semanage_module_remove_key;
 	  semanage_module_get;
 	  semanage_module_get_cil;
+	  semanage_get_log_message;
+	  semanage_set_log_message;
+	  semanage_get_log_command;
+	  semanage_set_log_command;
   local: *;
 };
diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
index a714d1e..fedaa86 100644
--- a/libsemanage/src/semanage_store.c
+++ b/libsemanage/src/semanage_store.c
@@ -111,6 +111,7 @@ static const char *semanage_sandbox_paths[SEMANAGE_STORE_NUM_PATHS] = {
 	"/disable_dontaudit",
 	"/modules/disabled",
 	"/modules/log",
+	"/modules/ChangeLog",
 };
 
 static char const * const semanage_final_prefix[SEMANAGE_FINAL_NUM] = {
diff --git a/libsemanage/src/semanage_store.h b/libsemanage/src/semanage_store.h
index c59bc69..eb99a0c 100644
--- a/libsemanage/src/semanage_store.h
+++ b/libsemanage/src/semanage_store.h
@@ -54,6 +54,7 @@ enum semanage_sandbox_defs {
 	SEMANAGE_DISABLE_DONTAUDIT,
 	SEMANAGE_MODULES_DISABLED,
 	SEMANAGE_CIL_LOG,
+	SEMANAGE_CHANGELOG,
 	SEMANAGE_STORE_NUM_PATHS
 };
 
-- 
1.6.3.3


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 14/15] [src-policy] semodule: user message support
  2010-01-26 22:08                         ` [PATCH 13/15] [src-policy] libsemanage: ChangeLog support Caleb Case
@ 2010-01-26 22:08                           ` Caleb Case
  2010-01-26 22:08                             ` [PATCH 15/15] [src-policy] semanage: source permissive module Caleb Case
  2010-02-01 15:11                             ` [PATCH 14/15] [src-policy] semodule: user message support James Carter
  0 siblings, 2 replies; 34+ messages in thread
From: Caleb Case @ 2010-01-26 22:08 UTC (permalink / raw)
  To: selinux; +Cc: csellers, kmacmillan, jwcart2, jbrindle, sds, Caleb Case

This adds the -m,--message option to semodule so that users can specify
a message for the ChangeLog.

  -m,--message=MSG user message for the ChangeLog

Example:

# semodule -E alsa -m "Allow alsa to execute cowsay."
---
 policycoreutils/semodule/semodule.8 |    3 +++
 policycoreutils/semodule/semodule.c |   24 +++++++++++++++++++++++-
 2 files changed, 26 insertions(+), 1 deletions(-)

diff --git a/policycoreutils/semodule/semodule.8 b/policycoreutils/semodule/semodule.8
index 8baad8b..97d31dd 100644
--- a/policycoreutils/semodule/semodule.8
+++ b/policycoreutils/semodule/semodule.8
@@ -87,6 +87,9 @@ prints help message and quit
 .TP
 .B  \-v,\-\-verbose     
 be verbose
+.TP
+.B  \-m,\-\-message=MSG
+user message for the ChangeLog
 
 .SH EXAMPLE
 .nf
diff --git a/policycoreutils/semodule/semodule.c b/policycoreutils/semodule/semodule.c
index 3536253..c8bf986 100644
--- a/policycoreutils/semodule/semodule.c
+++ b/policycoreutils/semodule/semodule.c
@@ -58,6 +58,7 @@ static int create_store;
 static int build;
 static int disable_dontaudit;
 static uint16_t priority;
+static char *message = NULL;
 
 static semanage_handle_t *sh = NULL;
 static char *store;
@@ -72,6 +73,8 @@ static void cleanup(void)
 		free(commands[num_commands].output);
 	}
 	free(commands);
+
+	free(message);
 }
 
 /* Signal handlers. */
@@ -134,6 +137,7 @@ static void usage(char *progname)
 	printf("  -h,--help        print this message and quit\n");
 	printf("  -v,--verbose     be verbose\n");
 	printf("  -D,--disable_dontaudit	Remove dontaudits from policy\n");
+	printf("  -m,--message=MSG user message for the ChangeLog\n");
 }
 
 /* Sets the global mode variable to new_mode, but only if no other
@@ -186,6 +190,7 @@ static void parse_command_line(int argc, char **argv)
 		{"output", required_argument, NULL, 'o'},
 		{"cil", 0, NULL, 'c'},
 		{"edit", required_argument, NULL, 'E'},
+		{"message", required_argument, NULL, 'm'},
 		{NULL, 0, NULL, 0}
 	};
 	int i;
@@ -195,7 +200,7 @@ static void parse_command_line(int argc, char **argv)
 	create_store = 0;
 	priority = 400;
 	while ((i =
-		getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnBDp:e:d:g:o:cE:", opts,
+		getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnBDp:e:d:g:o:cE:m:", opts,
 			    NULL)) != -1) {
 		switch (i) {
 		case 'b':
@@ -294,6 +299,13 @@ static void parse_command_line(int argc, char **argv)
 		case 'E':
 			set_mode(EDIT_M, optarg);
 			break;
+		case 'm':
+			message = strdup(optarg);
+			if (message == NULL) {
+				fprintf(stderr, "Failed to set message (out of memory).");
+				exit(1);
+			}
+			break;
 		case '?':
 		default:{
 				usage(argv[0]);
@@ -414,6 +426,16 @@ int main(int argc, char *argv[])
 		goto cleanup;
 	}
 
+	if (message) {
+		result = semanage_set_log_message(sh, message);
+		if (result != 0) {
+			fprintf(stderr,
+				"%s: Failed to set ChangeLog message.",
+				argv[0]);
+			goto cleanup;
+		}
+	}
+
 	for (i = 0; i < num_commands; i++) {
 		enum client_modes mode = commands[i].mode;
 		char *mode_arg = commands[i].arg;
-- 
1.6.3.3


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 15/15] [src-policy] semanage: source permissive module
  2010-01-26 22:08                           ` [PATCH 14/15] [src-policy] semodule: user message support Caleb Case
@ 2010-01-26 22:08                             ` Caleb Case
  2010-02-01 15:11                             ` [PATCH 14/15] [src-policy] semodule: user message support James Carter
  1 sibling, 0 replies; 34+ messages in thread
From: Caleb Case @ 2010-01-26 22:08 UTC (permalink / raw)
  To: selinux; +Cc: csellers, kmacmillan, jwcart2, jbrindle, sds, Caleb Case

This changes the permissive module generation to create a source refpol
module instead of a policy package.
---
 policycoreutils/semanage/seobject.py |   15 +++++----------
 1 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/policycoreutils/semanage/seobject.py b/policycoreutils/semanage/seobject.py
index 0aa7759..82132f3 100644
--- a/policycoreutils/semanage/seobject.py
+++ b/policycoreutils/semanage/seobject.py
@@ -274,26 +274,21 @@ class permissiveRecords(semanageRecords):
                dirname = tempfile.mkdtemp("-semanage")
                savedir = os.getcwd()
                os.chdir(dirname)
-               filename = "%s.te" % name
+               filename = "%s.ref" % name
                modtxt = """
-module %s 1.0;
+policy_module(%s, 1.0)
 
-require {
+gen_require(`
           type %s;
-}
+')
 
 permissive %s;
 """ % (name, type, type)
                fd = open(filename, 'w')
                fd.write(modtxt)
                fd.close()
-               mc = module.ModuleCompiler()
-               mc.create_module_package(filename, 1)
-               fd = open("permissive_%s.pp" % type)
-               data = fd.read()
-               fd.close()
 
-               rc = semanage_module_install(self.sh, data, len(data));
+               rc = semanage_module_install_file(self.sh, filename)
                if rc >= 0:
                       self.commit()
 
-- 
1.6.3.3


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [PATCH 00/15] RFC Source Policy Support
  2010-01-26 22:08 [PATCH 00/15] RFC Source Policy Support Caleb Case
  2010-01-26 22:08 ` [PATCH 01/15] [src-policy] refpol language and tools Caleb Case
@ 2010-01-26 22:41 ` Xavier Toth
  2010-01-27  1:17   ` Caleb Case
  2010-01-27 20:00 ` Stephen Smalley
  2 siblings, 1 reply; 34+ messages in thread
From: Xavier Toth @ 2010-01-26 22:41 UTC (permalink / raw)
  To: Caleb Case; +Cc: selinux, csellers, kmacmillan, jwcart2, jbrindle, sds

On Tue, Jan 26, 2010 at 4:08 PM, Caleb Case <ccase@tresys.com> wrote:
> Our motivations for this patchset is to enable source modules to be
> stored in the libsemanage store. These changes will allow users and
> administrators to:
>
>   1. Insert human readable and editable source modules into the module
>      store.
>
>   2. Retrieve existing modules in order to view or make changes.
>
>   3. Stop storing and versioning policy source outside of the semanage
>      store for minor local modifications (though it is possible the
>      store could be used for general policy development, it is
>      anticipated that for larger policy development activities an
>      external source store and version control scheme will be used).
>
> Additionally, switching to source modules will bring several other
> long-term benefits:
>
>   1. Reduction in the number of binary formats used in the SELinux
>      toolchain, easing maintenance and development.
>
>   2. Development path to tools that enable larger policy modifications
>      on end systems (e.g., cloning application policies, removing rules
>      from distribution provided policy, etc.).
>
>   3. Development path to multiple high-level policy languages.
>
>   4. Better Dependency Handling - e.g., updating an interface in one
>      module will cause the new interface to be used in other modules
>      without re-compiling those modules externally.
>
>   5. The removal of a special base module, allowing more flexibility in
>      policy construction and easier overriding, disabling, or removing
>      of portions of the core policy.
>
> [Design Considerations]
>
> In creating this design there were several key questions around
> backwards compatibility and user experience. Below are several of the
> most important and potentially controversial design decisions.
>
> No Support for Binary Modules - Many designs were made that included
> support for binary modules including, in several cases, base modules. We
> found that the compromises that each of these designs forced were
> unacceptable and, perhaps more importantly, there was no way to provide
> a user experience that would meet general expectations.  Further, it was
> felt that most users either had the source for all of their modules or
> in the rare cases when source was not available, the modules would be
> trivial and the source could be reasonably extracted using a decompiler.
> The most challenging problems were:
>
>   1. Interface files - Because binary modules do not contain the
>      interfaces created by their modules it would be necessary to
>      locate the corresponding interface files for each binary module to
>      allow source modules to be compiled. This is particularly true in
>      the case of support for base modules. While it might have been
>      possible to hack around this using the interface files in the
>      selinux-policy-devel package, there were many problems with this
>      approach.
>
>   2. Dependencies - Binary modules would not be able to be updated
>      based upon changes to the interfaces in other modules.
>
>   3. Intermediate language - supporting binary modules would make it
>      much more challenging to support compilation to the forthcoming
>      intermediate language without creating a complex conversion tool.
>      It was decided that enabling support for binary modules that would
>      eventually be discontinued was not worth the complexity.
>
> Single Source Files - The initial designs for source modules included
> the possibility of supporting reference policy modules directly by
> combining the three files for each module (.te, .if, and .fc) into a
> tarball. This created a very unfriendly user experience and created many
> corner cases (which tarball layouts were acceptable, how should the
> infrastructure handle 'extra' files in a tarball, etc.).  These
> complications led us to instead use a very simple sectioned text format
> for reference policy modules and, in the future, to remove the need for
> sections through language and compiler features.
>
> Module Ordering - The current reference policy compilation
> infrastructure devotes substantial attention to dealing with ordering
> problems. Some of these problems are fundamental (such as the ordering
> of portcon statements) while others are an artifact of the current
> compiler and M4 (such as the need to separate out interface statements
> in .if files). Rather than devote substantial effort to creating
> mechanisms for specifying or dealing with ordering, it was felt that the
> long term solution to this problem is in the improvements that will come
> from the proposed common intermediate language [1]. Therefore, in the
> short term, several modules will be ordered specially based upon name
> and certain policy statements will only be supported in those specially
> ordered modules (e.g., a module for specifying defines such as
> DISTRO_REDHAT). These hacks can be removed at a later date.
>
> Base Module Removal - The decision to support a special base binary
> module was made to make bootstrapping a module store easier by including
> a module that was required to have a minimal but complete system policy
> and to deal with ordering by only allowing order dependent statements to
> appear in the base (such as object class or portcon). Over time it has
> become clear that the base module limitations outweigh any of the
> intended benefits. This is especially true as support for overriding
> policy modules is included. Therefore, the source semanage store will no
> longer support or require a special base module.  Further, there will be
> no restrictions on the use of policy statements in modules. While this
> will allow some unintentional mistakes (e.g., including a broad portcon
> in a module that gets processed first) it will also allow additional
> freedom (e.g., the use of narrow portcon statements in modules).
>
> [User Experience Overview]
>
> The overall user experience will shift from using external tools to
> compile a policy package (.pp) to working directly with source modules.
>
> Source modules will be a single text file containing all of the policy
> for that module. For the current reference policy that will require
> combining the current interface, type enforcement, and file context
> files into a single text file. The user will then use that text file
> similarly to how the current binary modules are used. Insertion would be
> performed using semodule (the 'ref' extension is for the single file
> reference policy format):
>
> # semodule -i apache.ref
>
> Note that the language for the module will be inferred from the
> extension to avoid the general tools, such as semodule, needing an
> awareness of the format of all source policies. The name would be taken
> from the input filename.
>
> Removing a module would be the same as it is currently:
>
> # semodule -r apache
>
> Listing would be generally the same, though there would be the addition
> of a language field to the full output:
>
> # semodule -lfull
> 400 _access_vectors      2.20091117          ref
> 400 _constraints         2.20091117          ref
> <snip>
> 400 _mls                 2.20091117 disabled ref
> <snip>
> 400 corenetwork          1.13.1              corenet
> <snip>
> 400 zebra                1.10.0     disabled ref
> 400 zosremote            1.1.0      disabled ref
>
> The first large change to user experience is the introduction of a
> command to retrieve a module:
>
> # semodule -g apache
> # ls
> apache.ref
>
> # semodule -g apache -o myapache.ref
> # ls
> myapache.ref
>
> Similarly, there is the addition of an edit command that is similar to
> sudoedit. This is purely a convenience; it will retrieve the module to a
> temporary location and install it after updates are made.
>
> # semodule --edit apache
>
> Finally, semodule now supports adding a user message when making
> changes:
>
> # semodule --edit apache -m "Allow apache to execute cowsay."
>
> [Compilation]
>
> In the interests of supporting multiple high-level languages (such as
> domain specific languages) we provide a two part compilation process.
>
> The first compilation is from a high-level language (HLL) module to a
> common intermediate language (CIL) module. This compilation occurs when
> a module is installed. The compilation is handled by a HLL specific
> compiler conforming the HLL compiler specification.
>
> The second compilation is from CIL modules to binary base module. This
> compilation occurs during the commit process. The compilation is handled
> by the CIL compiler.
>
> In this implementation the CIL refers to a special formulation of the
> refpol language called refpol_ilc and NOT the proposed CIL[1].
>
> [HLL]
>
> We provide an overview of high-level language treatment here. This
> patchset introduces two high-level languages refpol and corenet. Please
> see their respective patches for details on their languages.
>
> [HLL Compiler Specification]
>
> Each high-level language (HLL) has a compiler that converts from the HLL
> to the CIL. The HLL compiler will be a command-line tool that takes the
> HLL source as input on stdin and outputs the compiled CIL on stdout.
> Errors from compilation will be output on stderr and a non-zero exit
> status set. Additionally, the version of the module will be output on
> file descriptor 3.
>
> For example an invocation by hand of the refpol HLL compiler:
>
> # refpolc < apache.ref > apache.cil 3<> apache.version
>
> The compiler name, path, HLL extension, and any flags to the compiler
> are specified in the language configuration file.
>
> [HLL Configuration File]
>
> Each language has a configuration file stored at:
>
> /etc/selinux/language.d/<language>.conf
>
> Where each <language>.conf contains:
>
> NAME=<human readable name>
> COMPILER=<full path to compiler>
> EXTENSION=<file extension without dot>
> FLAGS=<compiler flags>
>
> For example:
>
> NAME="Reference Policy"
> COMPILER="/usr/bin/refpolc"
> EXTENSION="ref"
> FLAGS=""
>
> Language extensions are required to be unique (at least from all other
> languages and preferably globally unique).
>
> [CIL]
>
> Here we discuss the CIL treatment in general. This patchset uses a
> special formulation of the refpol language combined with the traditional
> Reference Policy build infrastructure as the common intermediary
> language (referred to as refpol_ilc). For details on the refpol_ilc
> please see its patch.
>
> [CIL Compiler]
>
> The common intermediate language (CIL) compiler converts from the
> intermediate language to a binary base module. It is a command line tool
> that takes the enabled and disabled modules as parameters. Errors from
> compilation will be output on stderr and an non-zero exit status set.
> The binary base module will be output on stdout. Disabled modules will
> be specified with the -d option.
>
> For example an invocation by hand of the refpol_ilc CIL compiler:
>
> # refpol_ilc `find /var/lib/selinux/targeted/active/modules/400/ -iname cil` > base.pp
>
> [ChangeLog Support]
>
> Every successful commit will produce a log entry. The log entry will
> contain the command run, who ran it, their context, when it occurred,
> and any user specified message.
>
> The log will be stored at:
>
> /var/lib/selinux/<policy type>/ChangeLog
>
> Each line of the log has the following format:
>
> VERSION="<repo version>" COMMAND="<command + options>" USERNAME="<user name>" CONTEXT="<context>" TIME="<time stamp>" MSG="<message>"
>
> All quoted strings have special characters escaped (quotes and anything
> not printable [^:print:]|\").
>
> The origins of the information in the fields is as follows:
>
>   [Field]    [Origin]
>
>   VER        Discovered from the 'SCM', for the time being this will be the
>              commit number.
>
>   CMD        Discovered from /proc/self/cmdline if available. May be set by
>              the library user.
>
>   USERNAME   Discovered from getpwuid(getuid())->pw_name.
>
>   CONTEXT    Discovered from getprevcon.
>
>   TIME       Discovered from ctime(time(&t)).
>
>   MSG        Set by the library user.
>
> [Setup]
>
> The following steps setup a system with source policy support:
>
>   1. Compile & install patched SELinux userland.
>
>      Note: Remember to install the new python wrappers (install-pywrap)
>            if you intend to use semanage.
>
>   2. (On Fedora) Remove /lib/libsemanage.so.1. The default installation
>      location for libsemanage does not overwrite the one shipped with
>      Fedora.
>
>   3. Get Reference Policy:
>
>      # git clone http://oss.tresys.com/git/refpolicy.git
>
>   4. Make the refpol_ilc build directory:
>
>      # mkdir -p /usr/share/selinux/refpol_ilc/
>
>   5. Create and install the refpol_ilc build environment:
>
>      # refpolicy2refpol -b refpolicy /usr/share/selinux/refpol_ilc/build
>
>   6. Convert Reference Policy modules to refpol modules:
>
>      # refpolicy2refpol refpolicy refpol
>
>   7. Copy an existing installed policy such as targeted to a 'test'
>      store:
>
>      # cp -R /etc/selinux/targeted /etc/selinux/test
>
>   8. Create necessary directories for a 'test' store in
>      /var/lib/selinux:
>
>      # mkdir -p /var/lib/selinux/test/active/modules
>
>   9. Install the source modules to the test store:
>
>      # semodule -s test `find refpol -iname \*.ref -or -iname \*.corenet | xargs -I{} echo -i {}`
>
>      Note: The current semanage policy does not allow executing
>            generated files, so you need to change the policy or put
>            semanage in permissive.
>
> [1] CIL RFC: http://marc.info/?l=selinux&m=124759244409438&w=2
>
> Caleb Case (15):
>  [src-policy] refpol language and tools
>  [src-policy] corenet language and tools
>  [src-policy] Reference Policy to refpol conversion tool
>  [src-policy] refpol intermediate language compiler (refpol_ilc)
>  [src-policy] language.d and language.conf parser
>  [src-policy] libsemanage: compile hll module
>  [src-policy] libsemanage: compile common intermediary language
>  [src-policy] libsemanage: remove binary interfaces
>  [src-policy] semodule: remove base module support
>  [src-policy] libsemanage: get source module
>  [src-policy] semodule: get module source
>  [src-policy] semodule: edit module
>  [src-policy] libsemanage: ChangeLog support
>  [src-policy] semodule: user message support
>  [src-policy] semanage: source permissive module
>
>  Makefile                                       |    2 +-
>  corenet/COPYING                                |  504 ++++++++++
>  corenet/Makefile                               |   27 +
>  corenet/corenet.conf                           |    4 +
>  corenet/corenet.py                             |   17 +
>  corenet/corenet/corenet.py                     |  175 ++++
>  corenet/corenet/corenetc.py                    |  129 +++
>  corenet/corenetc.py                            |   17 +
>  corenet/setup.py                               |   13 +
>  libsemanage/include/semanage/modules.h         |   14 +-
>  libsemanage/include/semanage/private/handle.h  |   31 +-
>  libsemanage/include/semanage/private/modules.h |   28 +-
>  libsemanage/src/Makefile                       |   16 +-
>  libsemanage/src/direct_api.c                   | 1165 ++++++++++++++----------
>  libsemanage/src/handle.c                       |   95 ++-
>  libsemanage/src/handle.h                       |   10 +-
>  libsemanage/src/lang-parse.y                   |  271 ++++++
>  libsemanage/src/lang-scan.l                    |   84 ++
>  libsemanage/src/libsemanage.map                |    6 +
>  libsemanage/src/modules.c                      |   41 +-
>  libsemanage/src/modules.h                      |    3 +-
>  libsemanage/src/policy.h                       |   15 +-
>  libsemanage/src/semanage_lang_conf.h           |   39 +
>  libsemanage/src/semanage_store.c               |  884 ++++++++++++------
>  libsemanage/src/semanage_store.h               |   55 +-
>  policycoreutils/semanage/seobject.py           |   15 +-
>  policycoreutils/semodule/semodule.8            |   27 +-
>  policycoreutils/semodule/semodule.c            |  540 +++++++++++-
>  refpol/COPYING                                 |  504 ++++++++++
>  refpol/Makefile                                |   28 +
>  refpol/refpol.conf                             |    4 +
>  refpol/refpol.py                               |   17 +
>  refpol/refpol/refpol.py                        |  176 ++++
>  refpol/refpol/refpolc.py                       |   77 ++
>  refpol/refpol/refpolicy2refpol.py              |  185 ++++
>  refpol/refpolc.py                              |   17 +
>  refpol/refpolicy2refpol.py                     |   17 +
>  refpol/setup.py                                |   13 +
>  refpol_ilc/COPYING                             |  504 ++++++++++
>  refpol_ilc/Makefile                            |   24 +
>  refpol_ilc/refpol_ilc.py                       |   17 +
>  refpol_ilc/refpol_ilc/refpol_ilc.py            |  193 ++++
>  refpol_ilc/setup.py                            |   13 +
>  43 files changed, 5200 insertions(+), 816 deletions(-)
>  create mode 100644 corenet/COPYING
>  create mode 100644 corenet/Makefile
>  create mode 100644 corenet/corenet.conf
>  create mode 100755 corenet/corenet.py
>  create mode 100644 corenet/corenet/__init__.py
>  create mode 100644 corenet/corenet/corenet.py
>  create mode 100644 corenet/corenet/corenetc.py
>  create mode 100755 corenet/corenetc.py
>  create mode 100755 corenet/setup.py
>  create mode 100644 libsemanage/src/lang-parse.y
>  create mode 100644 libsemanage/src/lang-scan.l
>  create mode 100644 libsemanage/src/semanage_lang_conf.h
>  create mode 100644 refpol/COPYING
>  create mode 100644 refpol/Makefile
>  create mode 100644 refpol/refpol.conf
>  create mode 100755 refpol/refpol.py
>  create mode 100644 refpol/refpol/__init__.py
>  create mode 100644 refpol/refpol/refpol.py
>  create mode 100644 refpol/refpol/refpolc.py
>  create mode 100644 refpol/refpol/refpolicy2refpol.py
>  create mode 100755 refpol/refpolc.py
>  create mode 100755 refpol/refpolicy2refpol.py
>  create mode 100755 refpol/setup.py
>  create mode 100644 refpol_ilc/COPYING
>  create mode 100644 refpol_ilc/Makefile
>  create mode 100755 refpol_ilc/refpol_ilc.py
>  create mode 100644 refpol_ilc/refpol_ilc/__init__.py
>  create mode 100644 refpol_ilc/refpol_ilc/refpol_ilc.py
>  create mode 100755 refpol_ilc/setup.py
>
>
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
>

I'm trying to figure out how we will have to work in the future
because currently during our build we compile policy files and deal
with any compilation errors, at times by digging through the files
left in 'tmp'. With this patch we'll do 'semodue -i <modules source
file>' instead of make and in the case of errors what artifacts will
we have? In some cases the compilation error messages are not
sufficient to determine the cause of the problem and that's when the
tmp files become extremely useful.

Ted


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* RE: [PATCH 00/15] RFC Source Policy Support
  2010-01-26 22:41 ` [PATCH 00/15] RFC Source Policy Support Xavier Toth
@ 2010-01-27  1:17   ` Caleb Case
  2010-01-27 15:10     ` Xavier Toth
  0 siblings, 1 reply; 34+ messages in thread
From: Caleb Case @ 2010-01-27  1:17 UTC (permalink / raw)
  To: Xavier Toth
  Cc: selinux, Chad Sellers, Karl MacMillan, jwcart2, Joshua Brindle,
	sds

> -----Original Message-----
> From: Xavier Toth [mailto:txtoth@gmail.com]
> Sent: Tuesday, January 26, 2010 5:42 PM
> To: Caleb Case
> Cc: selinux@tycho.nsa.gov; Chad Sellers; Karl MacMillan;
> jwcart2@tycho.nsa.gov; Joshua Brindle; sds@tycho.nsa.gov
> Subject: Re: [PATCH 00/15] RFC Source Policy Support
> 
> On Tue, Jan 26, 2010 at 4:08 PM, Caleb Case <ccase@tresys.com> wrote:
> > Our motivations for this patchset is to enable source modules to be
> > stored in the libsemanage store. These changes will allow users and
> > administrators to:
> >
> >   1. Insert human readable and editable source modules into the module
> >      store.
> >
> >   2. Retrieve existing modules in order to view or make changes.
> >
> >   3. Stop storing and versioning policy source outside of the semanage
> >      store for minor local modifications (though it is possible the
> >      store could be used for general policy development, it is
> >      anticipated that for larger policy development activities an
> >      external source store and version control scheme will be used).
> >
> > Additionally, switching to source modules will bring several other
> > long-term benefits:
> >
> >   1. Reduction in the number of binary formats used in the SELinux
> >      toolchain, easing maintenance and development.
> >
> >   2. Development path to tools that enable larger policy modifications
> >      on end systems (e.g., cloning application policies, removing rules
> >      from distribution provided policy, etc.).
> >
> >   3. Development path to multiple high-level policy languages.
> >
> >   4. Better Dependency Handling - e.g., updating an interface in one
> >      module will cause the new interface to be used in other modules
> >      without re-compiling those modules externally.
> >
> >   5. The removal of a special base module, allowing more flexibility in
> >      policy construction and easier overriding, disabling, or removing
> >      of portions of the core policy.
> >
> > [Design Considerations]
> >
> > In creating this design there were several key questions around
> > backwards compatibility and user experience. Below are several of the
> > most important and potentially controversial design decisions.
> >
> > No Support for Binary Modules - Many designs were made that included
> > support for binary modules including, in several cases, base modules. We
> > found that the compromises that each of these designs forced were
> > unacceptable and, perhaps more importantly, there was no way to provide
> > a user experience that would meet general expectations.  Further, it was
> > felt that most users either had the source for all of their modules or
> > in the rare cases when source was not available, the modules would be
> > trivial and the source could be reasonably extracted using a decompiler.
> > The most challenging problems were:
> >
> >   1. Interface files - Because binary modules do not contain the
> >      interfaces created by their modules it would be necessary to
> >      locate the corresponding interface files for each binary module to
> >      allow source modules to be compiled. This is particularly true in
> >      the case of support for base modules. While it might have been
> >      possible to hack around this using the interface files in the
> >      selinux-policy-devel package, there were many problems with this
> >      approach.
> >
> >   2. Dependencies - Binary modules would not be able to be updated
> >      based upon changes to the interfaces in other modules.
> >
> >   3. Intermediate language - supporting binary modules would make it
> >      much more challenging to support compilation to the forthcoming
> >      intermediate language without creating a complex conversion tool.
> >      It was decided that enabling support for binary modules that would
> >      eventually be discontinued was not worth the complexity.
> >
> > Single Source Files - The initial designs for source modules included
> > the possibility of supporting reference policy modules directly by
> > combining the three files for each module (.te, .if, and .fc) into a
> > tarball. This created a very unfriendly user experience and created many
> > corner cases (which tarball layouts were acceptable, how should the
> > infrastructure handle 'extra' files in a tarball, etc.).  These
> > complications led us to instead use a very simple sectioned text format
> > for reference policy modules and, in the future, to remove the need for
> > sections through language and compiler features.
> >
> > Module Ordering - The current reference policy compilation
> > infrastructure devotes substantial attention to dealing with ordering
> > problems. Some of these problems are fundamental (such as the ordering
> > of portcon statements) while others are an artifact of the current
> > compiler and M4 (such as the need to separate out interface statements
> > in .if files). Rather than devote substantial effort to creating
> > mechanisms for specifying or dealing with ordering, it was felt that the
> > long term solution to this problem is in the improvements that will come
> > from the proposed common intermediate language [1]. Therefore, in the
> > short term, several modules will be ordered specially based upon name
> > and certain policy statements will only be supported in those specially
> > ordered modules (e.g., a module for specifying defines such as
> > DISTRO_REDHAT). These hacks can be removed at a later date.
> >
> > Base Module Removal - The decision to support a special base binary
> > module was made to make bootstrapping a module store easier by including
> > a module that was required to have a minimal but complete system policy
> > and to deal with ordering by only allowing order dependent statements to
> > appear in the base (such as object class or portcon). Over time it has
> > become clear that the base module limitations outweigh any of the
> > intended benefits. This is especially true as support for overriding
> > policy modules is included. Therefore, the source semanage store will no
> > longer support or require a special base module.  Further, there will be
> > no restrictions on the use of policy statements in modules. While this
> > will allow some unintentional mistakes (e.g., including a broad portcon
> > in a module that gets processed first) it will also allow additional
> > freedom (e.g., the use of narrow portcon statements in modules).
> >
> > [User Experience Overview]
> >
> > The overall user experience will shift from using external tools to
> > compile a policy package (.pp) to working directly with source modules.
> >
> > Source modules will be a single text file containing all of the policy
> > for that module. For the current reference policy that will require
> > combining the current interface, type enforcement, and file context
> > files into a single text file. The user will then use that text file
> > similarly to how the current binary modules are used. Insertion would be
> > performed using semodule (the 'ref' extension is for the single file
> > reference policy format):
> >
> > # semodule -i apache.ref
> >
> > Note that the language for the module will be inferred from the
> > extension to avoid the general tools, such as semodule, needing an
> > awareness of the format of all source policies. The name would be taken
> > from the input filename.
> >
> > Removing a module would be the same as it is currently:
> >
> > # semodule -r apache
> >
> > Listing would be generally the same, though there would be the addition
> > of a language field to the full output:
> >
> > # semodule -lfull
> > 400 _access_vectors      2.20091117          ref
> > 400 _constraints         2.20091117          ref
> > <snip>
> > 400 _mls                 2.20091117 disabled ref
> > <snip>
> > 400 corenetwork          1.13.1              corenet
> > <snip>
> > 400 zebra                1.10.0     disabled ref
> > 400 zosremote            1.1.0      disabled ref
> >
> > The first large change to user experience is the introduction of a
> > command to retrieve a module:
> >
> > # semodule -g apache
> > # ls
> > apache.ref
> >
> > # semodule -g apache -o myapache.ref
> > # ls
> > myapache.ref
> >
> > Similarly, there is the addition of an edit command that is similar to
> > sudoedit. This is purely a convenience; it will retrieve the module to a
> > temporary location and install it after updates are made.
> >
> > # semodule --edit apache
> >
> > Finally, semodule now supports adding a user message when making
> > changes:
> >
> > # semodule --edit apache -m "Allow apache to execute cowsay."
> >
> > [Compilation]
> >
> > In the interests of supporting multiple high-level languages (such as
> > domain specific languages) we provide a two part compilation process.
> >
> > The first compilation is from a high-level language (HLL) module to a
> > common intermediate language (CIL) module. This compilation occurs when
> > a module is installed. The compilation is handled by a HLL specific
> > compiler conforming the HLL compiler specification.
> >
> > The second compilation is from CIL modules to binary base module. This
> > compilation occurs during the commit process. The compilation is handled
> > by the CIL compiler.
> >
> > In this implementation the CIL refers to a special formulation of the
> > refpol language called refpol_ilc and NOT the proposed CIL[1].
> >
> > [HLL]
> >
> > We provide an overview of high-level language treatment here. This
> > patchset introduces two high-level languages refpol and corenet. Please
> > see their respective patches for details on their languages.
> >
> > [HLL Compiler Specification]
> >
> > Each high-level language (HLL) has a compiler that converts from the HLL
> > to the CIL. The HLL compiler will be a command-line tool that takes the
> > HLL source as input on stdin and outputs the compiled CIL on stdout.
> > Errors from compilation will be output on stderr and a non-zero exit
> > status set. Additionally, the version of the module will be output on
> > file descriptor 3.
> >
> > For example an invocation by hand of the refpol HLL compiler:
> >
> > # refpolc < apache.ref > apache.cil 3<> apache.version
> >
> > The compiler name, path, HLL extension, and any flags to the compiler
> > are specified in the language configuration file.
> >
> > [HLL Configuration File]
> >
> > Each language has a configuration file stored at:
> >
> > /etc/selinux/language.d/<language>.conf
> >
> > Where each <language>.conf contains:
> >
> > NAME=<human readable name>
> > COMPILER=<full path to compiler>
> > EXTENSION=<file extension without dot>
> > FLAGS=<compiler flags>
> >
> > For example:
> >
> > NAME="Reference Policy"
> > COMPILER="/usr/bin/refpolc"
> > EXTENSION="ref"
> > FLAGS=""
> >
> > Language extensions are required to be unique (at least from all other
> > languages and preferably globally unique).
> >
> > [CIL]
> >
> > Here we discuss the CIL treatment in general. This patchset uses a
> > special formulation of the refpol language combined with the traditional
> > Reference Policy build infrastructure as the common intermediary
> > language (referred to as refpol_ilc). For details on the refpol_ilc
> > please see its patch.
> >
> > [CIL Compiler]
> >
> > The common intermediate language (CIL) compiler converts from the
> > intermediate language to a binary base module. It is a command line tool
> > that takes the enabled and disabled modules as parameters. Errors from
> > compilation will be output on stderr and an non-zero exit status set.
> > The binary base module will be output on stdout. Disabled modules will
> > be specified with the -d option.
> >
> > For example an invocation by hand of the refpol_ilc CIL compiler:
> >
> > # refpol_ilc `find /var/lib/selinux/targeted/active/modules/400/ -iname
> cil` > base.pp
> >
> > [ChangeLog Support]
> >
> > Every successful commit will produce a log entry. The log entry will
> > contain the command run, who ran it, their context, when it occurred,
> > and any user specified message.
> >
> > The log will be stored at:
> >
> > /var/lib/selinux/<policy type>/ChangeLog
> >
> > Each line of the log has the following format:
> >
> > VERSION="<repo version>" COMMAND="<command + options>" USERNAME="<user
> name>" CONTEXT="<context>" TIME="<time stamp>" MSG="<message>"
> >
> > All quoted strings have special characters escaped (quotes and anything
> > not printable [^:print:]|\").
> >
> > The origins of the information in the fields is as follows:
> >
> >   [Field]    [Origin]
> >
> >   VER        Discovered from the 'SCM', for the time being this will be
> the
> >              commit number.
> >
> >   CMD        Discovered from /proc/self/cmdline if available. May be set
> by
> >              the library user.
> >
> >   USERNAME   Discovered from getpwuid(getuid())->pw_name.
> >
> >   CONTEXT    Discovered from getprevcon.
> >
> >   TIME       Discovered from ctime(time(&t)).
> >
> >   MSG        Set by the library user.
> >
> > [Setup]
> >
> > The following steps setup a system with source policy support:
> >
> >   1. Compile & install patched SELinux userland.
> >
> >      Note: Remember to install the new python wrappers (install-pywrap)
> >            if you intend to use semanage.
> >
> >   2. (On Fedora) Remove /lib/libsemanage.so.1. The default installation
> >      location for libsemanage does not overwrite the one shipped with
> >      Fedora.
> >
> >   3. Get Reference Policy:
> >
> >      # git clone http://oss.tresys.com/git/refpolicy.git
> >
> >   4. Make the refpol_ilc build directory:
> >
> >      # mkdir -p /usr/share/selinux/refpol_ilc/
> >
> >   5. Create and install the refpol_ilc build environment:
> >
> >      # refpolicy2refpol -b refpolicy /usr/share/selinux/refpol_ilc/build
> >
> >   6. Convert Reference Policy modules to refpol modules:
> >
> >      # refpolicy2refpol refpolicy refpol
> >
> >   7. Copy an existing installed policy such as targeted to a 'test'
> >      store:
> >
> >      # cp -R /etc/selinux/targeted /etc/selinux/test
> >
> >   8. Create necessary directories for a 'test' store in
> >      /var/lib/selinux:
> >
> >      # mkdir -p /var/lib/selinux/test/active/modules
> >
> >   9. Install the source modules to the test store:
> >
> >      # semodule -s test `find refpol -iname \*.ref -or -iname \*.corenet
> | xargs -I{} echo -i {}`
> >
> >      Note: The current semanage policy does not allow executing
> >            generated files, so you need to change the policy or put
> >            semanage in permissive.
> >
> > [1] CIL RFC: http://marc.info/?l=selinux&m=124759244409438&w=2
> >
> > Caleb Case (15):
> >  [src-policy] refpol language and tools
> >  [src-policy] corenet language and tools
> >  [src-policy] Reference Policy to refpol conversion tool
> >  [src-policy] refpol intermediate language compiler (refpol_ilc)
> >  [src-policy] language.d and language.conf parser
> >  [src-policy] libsemanage: compile hll module
> >  [src-policy] libsemanage: compile common intermediary language
> >  [src-policy] libsemanage: remove binary interfaces
> >  [src-policy] semodule: remove base module support
> >  [src-policy] libsemanage: get source module
> >  [src-policy] semodule: get module source
> >  [src-policy] semodule: edit module
> >  [src-policy] libsemanage: ChangeLog support
> >  [src-policy] semodule: user message support
> >  [src-policy] semanage: source permissive module
> >
> >  Makefile                                       |    2 +-
> >  corenet/COPYING                                |  504 ++++++++++
> >  corenet/Makefile                               |   27 +
> >  corenet/corenet.conf                           |    4 +
> >  corenet/corenet.py                             |   17 +
> >  corenet/corenet/corenet.py                     |  175 ++++
> >  corenet/corenet/corenetc.py                    |  129 +++
> >  corenet/corenetc.py                            |   17 +
> >  corenet/setup.py                               |   13 +
> >  libsemanage/include/semanage/modules.h         |   14 +-
> >  libsemanage/include/semanage/private/handle.h  |   31 +-
> >  libsemanage/include/semanage/private/modules.h |   28 +-
> >  libsemanage/src/Makefile                       |   16 +-
> >  libsemanage/src/direct_api.c                   | 1165 ++++++++++++++---
> -------
> >  libsemanage/src/handle.c                       |   95 ++-
> >  libsemanage/src/handle.h                       |   10 +-
> >  libsemanage/src/lang-parse.y                   |  271 ++++++
> >  libsemanage/src/lang-scan.l                    |   84 ++
> >  libsemanage/src/libsemanage.map                |    6 +
> >  libsemanage/src/modules.c                      |   41 +-
> >  libsemanage/src/modules.h                      |    3 +-
> >  libsemanage/src/policy.h                       |   15 +-
> >  libsemanage/src/semanage_lang_conf.h           |   39 +
> >  libsemanage/src/semanage_store.c               |  884 ++++++++++++-----
> -
> >  libsemanage/src/semanage_store.h               |   55 +-
> >  policycoreutils/semanage/seobject.py           |   15 +-
> >  policycoreutils/semodule/semodule.8            |   27 +-
> >  policycoreutils/semodule/semodule.c            |  540 +++++++++++-
> >  refpol/COPYING                                 |  504 ++++++++++
> >  refpol/Makefile                                |   28 +
> >  refpol/refpol.conf                             |    4 +
> >  refpol/refpol.py                               |   17 +
> >  refpol/refpol/refpol.py                        |  176 ++++
> >  refpol/refpol/refpolc.py                       |   77 ++
> >  refpol/refpol/refpolicy2refpol.py              |  185 ++++
> >  refpol/refpolc.py                              |   17 +
> >  refpol/refpolicy2refpol.py                     |   17 +
> >  refpol/setup.py                                |   13 +
> >  refpol_ilc/COPYING                             |  504 ++++++++++
> >  refpol_ilc/Makefile                            |   24 +
> >  refpol_ilc/refpol_ilc.py                       |   17 +
> >  refpol_ilc/refpol_ilc/refpol_ilc.py            |  193 ++++
> >  refpol_ilc/setup.py                            |   13 +
> >  43 files changed, 5200 insertions(+), 816 deletions(-)
> >  create mode 100644 corenet/COPYING
> >  create mode 100644 corenet/Makefile
> >  create mode 100644 corenet/corenet.conf
> >  create mode 100755 corenet/corenet.py
> >  create mode 100644 corenet/corenet/__init__.py
> >  create mode 100644 corenet/corenet/corenet.py
> >  create mode 100644 corenet/corenet/corenetc.py
> >  create mode 100755 corenet/corenetc.py
> >  create mode 100755 corenet/setup.py
> >  create mode 100644 libsemanage/src/lang-parse.y
> >  create mode 100644 libsemanage/src/lang-scan.l
> >  create mode 100644 libsemanage/src/semanage_lang_conf.h
> >  create mode 100644 refpol/COPYING
> >  create mode 100644 refpol/Makefile
> >  create mode 100644 refpol/refpol.conf
> >  create mode 100755 refpol/refpol.py
> >  create mode 100644 refpol/refpol/__init__.py
> >  create mode 100644 refpol/refpol/refpol.py
> >  create mode 100644 refpol/refpol/refpolc.py
> >  create mode 100644 refpol/refpol/refpolicy2refpol.py
> >  create mode 100755 refpol/refpolc.py
> >  create mode 100755 refpol/refpolicy2refpol.py
> >  create mode 100755 refpol/setup.py
> >  create mode 100644 refpol_ilc/COPYING
> >  create mode 100644 refpol_ilc/Makefile
> >  create mode 100755 refpol_ilc/refpol_ilc.py
> >  create mode 100644 refpol_ilc/refpol_ilc/__init__.py
> >  create mode 100644 refpol_ilc/refpol_ilc/refpol_ilc.py
> >  create mode 100755 refpol_ilc/setup.py
> >
> >
> > --
> > This message was distributed to subscribers of the selinux mailing list.
> > If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov
> with
> > the words "unsubscribe selinux" without quotes as the message.
> >
> 
> I'm trying to figure out how we will have to work in the future
> because currently during our build we compile policy files and deal
> with any compilation errors, at times by digging through the files
> left in 'tmp'. With this patch we'll do 'semodue -i <modules source
> file>' instead of make and in the case of errors what artifacts will
> we have? In some cases the compilation error messages are not
> sufficient to determine the cause of the problem and that's when the
> tmp files become extremely useful.
> 
> Ted

In general you'll get compilation error messages as you do now if there is an error during compilation with Reference Policy. If you need the result of the tmp files, you can change the defaults in refpol_ilc.py for the cleanup flag and tmp dir location (not an ideal solution though).

This patchset doesn't allow you to set the refpol_ilc flags, but that might be useful so that you could add extra flags like --cleanup=False --tmp=/tmp/last-semanage --force (causing the last run of the build to always be in /tmp/last-semanage). This could be an entry in semanage.conf:

CIL_FLAGS="--cleanup=False --tmp=/tmp/last-semanage --force"

That way if an install failed you could always go to /tmp/last-semanage and examine things more closely.

Here are some examples of failed installs:

I've put some junk text at the top of the alsa module and tried to install it. In this case the error occurs during the HLL->CIL step on install:

[root@fc12 ~]# head alsa.ref 
some garbage

[interface]
## <summary>Ainit ALSA configuration tool</summary>

[root@fc12 ~]# semodule -i alsa.ref 
libsemanage.semanage_exec: Failed to execute /usr/bin/refpolc (exit status 1).
libsemanage.semanage_compile_hll: /usr/bin/refpolc: Error: [interface] section defined, but already found rules in default section (<stdin>:3).


semodule:  Failed on alsa.ref!

Here's an example where there is a policy error that occurs during the commit step CILs->base.pp. I've added a reference to an undefined function to the alsa module.

[root@fc12 ~]# semodule -i alsa.ref 
libsemanage.semanage_exec: Failed to execute /usr/bin/refpol_ilc (exit status 1). (No such file or directory).
<snip>
/usr/bin/checkmodule -M base.conf -o tmp/base.mod
/usr/bin/checkmodule:  loading policy configuration from base.conf
policy/modules/kernel/alsa.te":71:ERROR 'syntax error' at token 'my_undefined_function' on line 32046:
my_undefined_function(alsa_t)

/usr/bin/checkmodule:  error(s) encountered while parsing configuration
make: *** [tmp/base.mod] Error 1
/usr/bin/refpol_ilc: Error: Failed to run make base.pp (2).

 (No such file or directory).
semodule:  Failed!

Caleb


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 00/15] RFC Source Policy Support
  2010-01-27  1:17   ` Caleb Case
@ 2010-01-27 15:10     ` Xavier Toth
  0 siblings, 0 replies; 34+ messages in thread
From: Xavier Toth @ 2010-01-27 15:10 UTC (permalink / raw)
  To: Caleb Case
  Cc: selinux, Chad Sellers, Karl MacMillan, jwcart2, Joshua Brindle,
	sds

On Tue, Jan 26, 2010 at 7:17 PM, Caleb Case <ccase@tresys.com> wrote:
>> -----Original Message-----
>> From: Xavier Toth [mailto:txtoth@gmail.com]
>> Sent: Tuesday, January 26, 2010 5:42 PM
>> To: Caleb Case
>> Cc: selinux@tycho.nsa.gov; Chad Sellers; Karl MacMillan;
>> jwcart2@tycho.nsa.gov; Joshua Brindle; sds@tycho.nsa.gov
>> Subject: Re: [PATCH 00/15] RFC Source Policy Support
>>
>> On Tue, Jan 26, 2010 at 4:08 PM, Caleb Case <ccase@tresys.com> wrote:
>> > Our motivations for this patchset is to enable source modules to be
>> > stored in the libsemanage store. These changes will allow users and
>> > administrators to:
>> >
>> >   1. Insert human readable and editable source modules into the module
>> >      store.
>> >
>> >   2. Retrieve existing modules in order to view or make changes.
>> >
>> >   3. Stop storing and versioning policy source outside of the semanage
>> >      store for minor local modifications (though it is possible the
>> >      store could be used for general policy development, it is
>> >      anticipated that for larger policy development activities an
>> >      external source store and version control scheme will be used).
>> >
>> > Additionally, switching to source modules will bring several other
>> > long-term benefits:
>> >
>> >   1. Reduction in the number of binary formats used in the SELinux
>> >      toolchain, easing maintenance and development.
>> >
>> >   2. Development path to tools that enable larger policy modifications
>> >      on end systems (e.g., cloning application policies, removing rules
>> >      from distribution provided policy, etc.).
>> >
>> >   3. Development path to multiple high-level policy languages.
>> >
>> >   4. Better Dependency Handling - e.g., updating an interface in one
>> >      module will cause the new interface to be used in other modules
>> >      without re-compiling those modules externally.
>> >
>> >   5. The removal of a special base module, allowing more flexibility in
>> >      policy construction and easier overriding, disabling, or removing
>> >      of portions of the core policy.
>> >
>> > [Design Considerations]
>> >
>> > In creating this design there were several key questions around
>> > backwards compatibility and user experience. Below are several of the
>> > most important and potentially controversial design decisions.
>> >
>> > No Support for Binary Modules - Many designs were made that included
>> > support for binary modules including, in several cases, base modules. We
>> > found that the compromises that each of these designs forced were
>> > unacceptable and, perhaps more importantly, there was no way to provide
>> > a user experience that would meet general expectations.  Further, it was
>> > felt that most users either had the source for all of their modules or
>> > in the rare cases when source was not available, the modules would be
>> > trivial and the source could be reasonably extracted using a decompiler.
>> > The most challenging problems were:
>> >
>> >   1. Interface files - Because binary modules do not contain the
>> >      interfaces created by their modules it would be necessary to
>> >      locate the corresponding interface files for each binary module to
>> >      allow source modules to be compiled. This is particularly true in
>> >      the case of support for base modules. While it might have been
>> >      possible to hack around this using the interface files in the
>> >      selinux-policy-devel package, there were many problems with this
>> >      approach.
>> >
>> >   2. Dependencies - Binary modules would not be able to be updated
>> >      based upon changes to the interfaces in other modules.
>> >
>> >   3. Intermediate language - supporting binary modules would make it
>> >      much more challenging to support compilation to the forthcoming
>> >      intermediate language without creating a complex conversion tool.
>> >      It was decided that enabling support for binary modules that would
>> >      eventually be discontinued was not worth the complexity.
>> >
>> > Single Source Files - The initial designs for source modules included
>> > the possibility of supporting reference policy modules directly by
>> > combining the three files for each module (.te, .if, and .fc) into a
>> > tarball. This created a very unfriendly user experience and created many
>> > corner cases (which tarball layouts were acceptable, how should the
>> > infrastructure handle 'extra' files in a tarball, etc.).  These
>> > complications led us to instead use a very simple sectioned text format
>> > for reference policy modules and, in the future, to remove the need for
>> > sections through language and compiler features.
>> >
>> > Module Ordering - The current reference policy compilation
>> > infrastructure devotes substantial attention to dealing with ordering
>> > problems. Some of these problems are fundamental (such as the ordering
>> > of portcon statements) while others are an artifact of the current
>> > compiler and M4 (such as the need to separate out interface statements
>> > in .if files). Rather than devote substantial effort to creating
>> > mechanisms for specifying or dealing with ordering, it was felt that the
>> > long term solution to this problem is in the improvements that will come
>> > from the proposed common intermediate language [1]. Therefore, in the
>> > short term, several modules will be ordered specially based upon name
>> > and certain policy statements will only be supported in those specially
>> > ordered modules (e.g., a module for specifying defines such as
>> > DISTRO_REDHAT). These hacks can be removed at a later date.
>> >
>> > Base Module Removal - The decision to support a special base binary
>> > module was made to make bootstrapping a module store easier by including
>> > a module that was required to have a minimal but complete system policy
>> > and to deal with ordering by only allowing order dependent statements to
>> > appear in the base (such as object class or portcon). Over time it has
>> > become clear that the base module limitations outweigh any of the
>> > intended benefits. This is especially true as support for overriding
>> > policy modules is included. Therefore, the source semanage store will no
>> > longer support or require a special base module.  Further, there will be
>> > no restrictions on the use of policy statements in modules. While this
>> > will allow some unintentional mistakes (e.g., including a broad portcon
>> > in a module that gets processed first) it will also allow additional
>> > freedom (e.g., the use of narrow portcon statements in modules).
>> >
>> > [User Experience Overview]
>> >
>> > The overall user experience will shift from using external tools to
>> > compile a policy package (.pp) to working directly with source modules.
>> >
>> > Source modules will be a single text file containing all of the policy
>> > for that module. For the current reference policy that will require
>> > combining the current interface, type enforcement, and file context
>> > files into a single text file. The user will then use that text file
>> > similarly to how the current binary modules are used. Insertion would be
>> > performed using semodule (the 'ref' extension is for the single file
>> > reference policy format):
>> >
>> > # semodule -i apache.ref
>> >
>> > Note that the language for the module will be inferred from the
>> > extension to avoid the general tools, such as semodule, needing an
>> > awareness of the format of all source policies. The name would be taken
>> > from the input filename.
>> >
>> > Removing a module would be the same as it is currently:
>> >
>> > # semodule -r apache
>> >
>> > Listing would be generally the same, though there would be the addition
>> > of a language field to the full output:
>> >
>> > # semodule -lfull
>> > 400 _access_vectors      2.20091117          ref
>> > 400 _constraints         2.20091117          ref
>> > <snip>
>> > 400 _mls                 2.20091117 disabled ref
>> > <snip>
>> > 400 corenetwork          1.13.1              corenet
>> > <snip>
>> > 400 zebra                1.10.0     disabled ref
>> > 400 zosremote            1.1.0      disabled ref
>> >
>> > The first large change to user experience is the introduction of a
>> > command to retrieve a module:
>> >
>> > # semodule -g apache
>> > # ls
>> > apache.ref
>> >
>> > # semodule -g apache -o myapache.ref
>> > # ls
>> > myapache.ref
>> >
>> > Similarly, there is the addition of an edit command that is similar to
>> > sudoedit. This is purely a convenience; it will retrieve the module to a
>> > temporary location and install it after updates are made.
>> >
>> > # semodule --edit apache
>> >
>> > Finally, semodule now supports adding a user message when making
>> > changes:
>> >
>> > # semodule --edit apache -m "Allow apache to execute cowsay."
>> >
>> > [Compilation]
>> >
>> > In the interests of supporting multiple high-level languages (such as
>> > domain specific languages) we provide a two part compilation process.
>> >
>> > The first compilation is from a high-level language (HLL) module to a
>> > common intermediate language (CIL) module. This compilation occurs when
>> > a module is installed. The compilation is handled by a HLL specific
>> > compiler conforming the HLL compiler specification.
>> >
>> > The second compilation is from CIL modules to binary base module. This
>> > compilation occurs during the commit process. The compilation is handled
>> > by the CIL compiler.
>> >
>> > In this implementation the CIL refers to a special formulation of the
>> > refpol language called refpol_ilc and NOT the proposed CIL[1].
>> >
>> > [HLL]
>> >
>> > We provide an overview of high-level language treatment here. This
>> > patchset introduces two high-level languages refpol and corenet. Please
>> > see their respective patches for details on their languages.
>> >
>> > [HLL Compiler Specification]
>> >
>> > Each high-level language (HLL) has a compiler that converts from the HLL
>> > to the CIL. The HLL compiler will be a command-line tool that takes the
>> > HLL source as input on stdin and outputs the compiled CIL on stdout.
>> > Errors from compilation will be output on stderr and a non-zero exit
>> > status set. Additionally, the version of the module will be output on
>> > file descriptor 3.
>> >
>> > For example an invocation by hand of the refpol HLL compiler:
>> >
>> > # refpolc < apache.ref > apache.cil 3<> apache.version
>> >
>> > The compiler name, path, HLL extension, and any flags to the compiler
>> > are specified in the language configuration file.
>> >
>> > [HLL Configuration File]
>> >
>> > Each language has a configuration file stored at:
>> >
>> > /etc/selinux/language.d/<language>.conf
>> >
>> > Where each <language>.conf contains:
>> >
>> > NAME=<human readable name>
>> > COMPILER=<full path to compiler>
>> > EXTENSION=<file extension without dot>
>> > FLAGS=<compiler flags>
>> >
>> > For example:
>> >
>> > NAME="Reference Policy"
>> > COMPILER="/usr/bin/refpolc"
>> > EXTENSION="ref"
>> > FLAGS=""
>> >
>> > Language extensions are required to be unique (at least from all other
>> > languages and preferably globally unique).
>> >
>> > [CIL]
>> >
>> > Here we discuss the CIL treatment in general. This patchset uses a
>> > special formulation of the refpol language combined with the traditional
>> > Reference Policy build infrastructure as the common intermediary
>> > language (referred to as refpol_ilc). For details on the refpol_ilc
>> > please see its patch.
>> >
>> > [CIL Compiler]
>> >
>> > The common intermediate language (CIL) compiler converts from the
>> > intermediate language to a binary base module. It is a command line tool
>> > that takes the enabled and disabled modules as parameters. Errors from
>> > compilation will be output on stderr and an non-zero exit status set.
>> > The binary base module will be output on stdout. Disabled modules will
>> > be specified with the -d option.
>> >
>> > For example an invocation by hand of the refpol_ilc CIL compiler:
>> >
>> > # refpol_ilc `find /var/lib/selinux/targeted/active/modules/400/ -iname
>> cil` > base.pp
>> >
>> > [ChangeLog Support]
>> >
>> > Every successful commit will produce a log entry. The log entry will
>> > contain the command run, who ran it, their context, when it occurred,
>> > and any user specified message.
>> >
>> > The log will be stored at:
>> >
>> > /var/lib/selinux/<policy type>/ChangeLog
>> >
>> > Each line of the log has the following format:
>> >
>> > VERSION="<repo version>" COMMAND="<command + options>" USERNAME="<user
>> name>" CONTEXT="<context>" TIME="<time stamp>" MSG="<message>"
>> >
>> > All quoted strings have special characters escaped (quotes and anything
>> > not printable [^:print:]|\").
>> >
>> > The origins of the information in the fields is as follows:
>> >
>> >   [Field]    [Origin]
>> >
>> >   VER        Discovered from the 'SCM', for the time being this will be
>> the
>> >              commit number.
>> >
>> >   CMD        Discovered from /proc/self/cmdline if available. May be set
>> by
>> >              the library user.
>> >
>> >   USERNAME   Discovered from getpwuid(getuid())->pw_name.
>> >
>> >   CONTEXT    Discovered from getprevcon.
>> >
>> >   TIME       Discovered from ctime(time(&t)).
>> >
>> >   MSG        Set by the library user.
>> >
>> > [Setup]
>> >
>> > The following steps setup a system with source policy support:
>> >
>> >   1. Compile & install patched SELinux userland.
>> >
>> >      Note: Remember to install the new python wrappers (install-pywrap)
>> >            if you intend to use semanage.
>> >
>> >   2. (On Fedora) Remove /lib/libsemanage.so.1. The default installation
>> >      location for libsemanage does not overwrite the one shipped with
>> >      Fedora.
>> >
>> >   3. Get Reference Policy:
>> >
>> >      # git clone http://oss.tresys.com/git/refpolicy.git
>> >
>> >   4. Make the refpol_ilc build directory:
>> >
>> >      # mkdir -p /usr/share/selinux/refpol_ilc/
>> >
>> >   5. Create and install the refpol_ilc build environment:
>> >
>> >      # refpolicy2refpol -b refpolicy /usr/share/selinux/refpol_ilc/build
>> >
>> >   6. Convert Reference Policy modules to refpol modules:
>> >
>> >      # refpolicy2refpol refpolicy refpol
>> >
>> >   7. Copy an existing installed policy such as targeted to a 'test'
>> >      store:
>> >
>> >      # cp -R /etc/selinux/targeted /etc/selinux/test
>> >
>> >   8. Create necessary directories for a 'test' store in
>> >      /var/lib/selinux:
>> >
>> >      # mkdir -p /var/lib/selinux/test/active/modules
>> >
>> >   9. Install the source modules to the test store:
>> >
>> >      # semodule -s test `find refpol -iname \*.ref -or -iname \*.corenet
>> | xargs -I{} echo -i {}`
>> >
>> >      Note: The current semanage policy does not allow executing
>> >            generated files, so you need to change the policy or put
>> >            semanage in permissive.
>> >
>> > [1] CIL RFC: http://marc.info/?l=selinux&m=124759244409438&w=2
>> >
>> > Caleb Case (15):
>> >  [src-policy] refpol language and tools
>> >  [src-policy] corenet language and tools
>> >  [src-policy] Reference Policy to refpol conversion tool
>> >  [src-policy] refpol intermediate language compiler (refpol_ilc)
>> >  [src-policy] language.d and language.conf parser
>> >  [src-policy] libsemanage: compile hll module
>> >  [src-policy] libsemanage: compile common intermediary language
>> >  [src-policy] libsemanage: remove binary interfaces
>> >  [src-policy] semodule: remove base module support
>> >  [src-policy] libsemanage: get source module
>> >  [src-policy] semodule: get module source
>> >  [src-policy] semodule: edit module
>> >  [src-policy] libsemanage: ChangeLog support
>> >  [src-policy] semodule: user message support
>> >  [src-policy] semanage: source permissive module
>> >
>> >  Makefile                                       |    2 +-
>> >  corenet/COPYING                                |  504 ++++++++++
>> >  corenet/Makefile                               |   27 +
>> >  corenet/corenet.conf                           |    4 +
>> >  corenet/corenet.py                             |   17 +
>> >  corenet/corenet/corenet.py                     |  175 ++++
>> >  corenet/corenet/corenetc.py                    |  129 +++
>> >  corenet/corenetc.py                            |   17 +
>> >  corenet/setup.py                               |   13 +
>> >  libsemanage/include/semanage/modules.h         |   14 +-
>> >  libsemanage/include/semanage/private/handle.h  |   31 +-
>> >  libsemanage/include/semanage/private/modules.h |   28 +-
>> >  libsemanage/src/Makefile                       |   16 +-
>> >  libsemanage/src/direct_api.c                   | 1165 ++++++++++++++---
>> -------
>> >  libsemanage/src/handle.c                       |   95 ++-
>> >  libsemanage/src/handle.h                       |   10 +-
>> >  libsemanage/src/lang-parse.y                   |  271 ++++++
>> >  libsemanage/src/lang-scan.l                    |   84 ++
>> >  libsemanage/src/libsemanage.map                |    6 +
>> >  libsemanage/src/modules.c                      |   41 +-
>> >  libsemanage/src/modules.h                      |    3 +-
>> >  libsemanage/src/policy.h                       |   15 +-
>> >  libsemanage/src/semanage_lang_conf.h           |   39 +
>> >  libsemanage/src/semanage_store.c               |  884 ++++++++++++-----
>> -
>> >  libsemanage/src/semanage_store.h               |   55 +-
>> >  policycoreutils/semanage/seobject.py           |   15 +-
>> >  policycoreutils/semodule/semodule.8            |   27 +-
>> >  policycoreutils/semodule/semodule.c            |  540 +++++++++++-
>> >  refpol/COPYING                                 |  504 ++++++++++
>> >  refpol/Makefile                                |   28 +
>> >  refpol/refpol.conf                             |    4 +
>> >  refpol/refpol.py                               |   17 +
>> >  refpol/refpol/refpol.py                        |  176 ++++
>> >  refpol/refpol/refpolc.py                       |   77 ++
>> >  refpol/refpol/refpolicy2refpol.py              |  185 ++++
>> >  refpol/refpolc.py                              |   17 +
>> >  refpol/refpolicy2refpol.py                     |   17 +
>> >  refpol/setup.py                                |   13 +
>> >  refpol_ilc/COPYING                             |  504 ++++++++++
>> >  refpol_ilc/Makefile                            |   24 +
>> >  refpol_ilc/refpol_ilc.py                       |   17 +
>> >  refpol_ilc/refpol_ilc/refpol_ilc.py            |  193 ++++
>> >  refpol_ilc/setup.py                            |   13 +
>> >  43 files changed, 5200 insertions(+), 816 deletions(-)
>> >  create mode 100644 corenet/COPYING
>> >  create mode 100644 corenet/Makefile
>> >  create mode 100644 corenet/corenet.conf
>> >  create mode 100755 corenet/corenet.py
>> >  create mode 100644 corenet/corenet/__init__.py
>> >  create mode 100644 corenet/corenet/corenet.py
>> >  create mode 100644 corenet/corenet/corenetc.py
>> >  create mode 100755 corenet/corenetc.py
>> >  create mode 100755 corenet/setup.py
>> >  create mode 100644 libsemanage/src/lang-parse.y
>> >  create mode 100644 libsemanage/src/lang-scan.l
>> >  create mode 100644 libsemanage/src/semanage_lang_conf.h
>> >  create mode 100644 refpol/COPYING
>> >  create mode 100644 refpol/Makefile
>> >  create mode 100644 refpol/refpol.conf
>> >  create mode 100755 refpol/refpol.py
>> >  create mode 100644 refpol/refpol/__init__.py
>> >  create mode 100644 refpol/refpol/refpol.py
>> >  create mode 100644 refpol/refpol/refpolc.py
>> >  create mode 100644 refpol/refpol/refpolicy2refpol.py
>> >  create mode 100755 refpol/refpolc.py
>> >  create mode 100755 refpol/refpolicy2refpol.py
>> >  create mode 100755 refpol/setup.py
>> >  create mode 100644 refpol_ilc/COPYING
>> >  create mode 100644 refpol_ilc/Makefile
>> >  create mode 100755 refpol_ilc/refpol_ilc.py
>> >  create mode 100644 refpol_ilc/refpol_ilc/__init__.py
>> >  create mode 100644 refpol_ilc/refpol_ilc/refpol_ilc.py
>> >  create mode 100755 refpol_ilc/setup.py
>> >
>> >
>> > --
>> > This message was distributed to subscribers of the selinux mailing list.
>> > If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov
>> with
>> > the words "unsubscribe selinux" without quotes as the message.
>> >
>>
>> I'm trying to figure out how we will have to work in the future
>> because currently during our build we compile policy files and deal
>> with any compilation errors, at times by digging through the files
>> left in 'tmp'. With this patch we'll do 'semodue -i <modules source
>> file>' instead of make and in the case of errors what artifacts will
>> we have? In some cases the compilation error messages are not
>> sufficient to determine the cause of the problem and that's when the
>> tmp files become extremely useful.
>>
>> Ted
>
> In general you'll get compilation error messages as you do now if there is an error during compilation with Reference Policy. If you need the result of the tmp files, you can change the defaults in refpol_ilc.py for the cleanup flag and tmp dir location (not an ideal solution though).
>
> This patchset doesn't allow you to set the refpol_ilc flags, but that might be useful so that you could add extra flags like --cleanup=False --tmp=/tmp/last-semanage --force (causing the last run of the build to always be in /tmp/last-semanage). This could be an entry in semanage.conf:
>
> CIL_FLAGS="--cleanup=False --tmp=/tmp/last-semanage --force"
>
> That way if an install failed you could always go to /tmp/last-semanage and examine things more closely.

Yes I think it would be useful to be able to configure these options.

>
> Here are some examples of failed installs:
>
> I've put some junk text at the top of the alsa module and tried to install it. In this case the error occurs during the HLL->CIL step on install:
>
> [root@fc12 ~]# head alsa.ref
> some garbage
>
> [interface]
> ## <summary>Ainit ALSA configuration tool</summary>
>
> [root@fc12 ~]# semodule -i alsa.ref
> libsemanage.semanage_exec: Failed to execute /usr/bin/refpolc (exit status 1).
> libsemanage.semanage_compile_hll: /usr/bin/refpolc: Error: [interface] section defined, but already found rules in default section (<stdin>:3).
>
>
> semodule:  Failed on alsa.ref!
>
> Here's an example where there is a policy error that occurs during the commit step CILs->base.pp. I've added a reference to an undefined function to the alsa module.
>
> [root@fc12 ~]# semodule -i alsa.ref
> libsemanage.semanage_exec: Failed to execute /usr/bin/refpol_ilc (exit status 1). (No such file or directory).
> <snip>
> /usr/bin/checkmodule -M base.conf -o tmp/base.mod
> /usr/bin/checkmodule:  loading policy configuration from base.conf
> policy/modules/kernel/alsa.te":71:ERROR 'syntax error' at token 'my_undefined_function' on line 32046:
> my_undefined_function(alsa_t)
>
> /usr/bin/checkmodule:  error(s) encountered while parsing configuration
> make: *** [tmp/base.mod] Error 1
> /usr/bin/refpol_ilc: Error: Failed to run make base.pp (2).
>
>  (No such file or directory).
> semodule:  Failed!
>
> Caleb
>


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 01/15] [src-policy] refpol language and tools
  2010-01-26 22:08 ` [PATCH 01/15] [src-policy] refpol language and tools Caleb Case
  2010-01-26 22:08   ` [PATCH 02/15] [src-policy] corenet " Caleb Case
@ 2010-01-27 19:39   ` Stephen Smalley
  2010-01-27 19:54     ` Caleb Case
  1 sibling, 1 reply; 34+ messages in thread
From: Stephen Smalley @ 2010-01-27 19:39 UTC (permalink / raw)
  To: Caleb Case; +Cc: selinux, csellers, kmacmillan, jwcart2, jbrindle

On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote:
> [refpol Language]
> 
> The refpol language is a simple transformation of a standard Reference
> Policy module consisting of 3 files to a single file format with
> sections. Each Reference Policy file is placed into a refpol section as
> follows:
> 
>    <module>.if   =>   [interface]
>    <module>.te   =>   [policy]
>    <module>.fc   =>   [context]
> 
> * These are the only valid section headers.
> 
> * A section begins with a section marker and ends with the next marker
>   encountered or the end of the file.
> 
> * If a file has at least one section marker and there is text before the
>   first section then this is an error.
> 
> * There can be at most one of each valid section marker in a file.
> 
> * A file without any section markers is assumed to be only policy.
> 
> * The valid contents of each section are the same as for the separate
>   reference policy files.
> 
> * The standard filename extension is '.ref'.
> 
> [refpol Tool]
> 
> The refpol tool can create a refpol module from a Reference Policy
> module.
> 
>    Usage: refpol COMMAND [OPTIONS] MODULE.ref
> 
>    Commands:
>      create		create a new refpol
>      extract		extract .if, .te, and .fc files from a refpol
> 
>    Options:
>      --version             show program's version number and exit
>      -h, --help            show this help message and exit
>      -f, --force           force overwriting existing files
> 
>      Create options:
>        -i FILE, --interface=FILE
>                            interface file
>        -p FILE, --policy=FILE
>                            policy file
>        -c FILE, --context=FILE
>                            context file
> 
> Example:
> 
> # refpol create -i alsa.if -p alsa.te -c alsa.fc alsa.ref
> 
> refpol modules should have the '.ref' extension. The resulting alsa.ref
> looks like this:
> 
>    [interface]
> 
>    policy_module(alsa, 1.8.0)

The policy_module() declaration in existing modules is in their .te
file, not their .if file.

If you are going to move up the declaration, then:
a) What you say earlier about the mapping of the current files and the
valid contents of the sections is not entirely accurate, and
b) Wouldn't it make more sense to move the declaration to the very
beginning before the three sections, as it pertains to all three?

> 
>    ########################################
>    #
>    # Declarations
>    #
>    <snip>
> 
>    [policy]
>    ## <summary>Ainit ALSA configuration tool</summary>
>    <snip>
> 
>    [context]
>    /bin/alsaunmute		--	gen_context(system_u:object_r:alsa_exec_t,s0)
>    <snip>
> 
> [refpol HLL compiler]
> 
> The refpolc high level language (HLL) compiler performs basic formatting
> checks and extracts the policy version from the policy_module statement.
> 
>    Usage: refpolc [OPTIONS] [MODULE]
> 
>    Input is read from stdin unless MODULE is provided.
>    Output is written to stdout unless -o is specified.
> 
>    Options:
>      --version             show program's version number and exit
>      -h, --help            show this help message and exit
>      -f, --force           force overwriting existing files
>      -o FILE, --output=FILE
>                            output file
> 
> Example:
> 
> # refpolc < apache.ref > apache.cil 3<> apache.version

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* RE: [PATCH 01/15] [src-policy] refpol language and tools
  2010-01-27 19:39   ` [PATCH 01/15] [src-policy] refpol language and tools Stephen Smalley
@ 2010-01-27 19:54     ` Caleb Case
  0 siblings, 0 replies; 34+ messages in thread
From: Caleb Case @ 2010-01-27 19:54 UTC (permalink / raw)
  To: Stephen Smalley
  Cc: selinux, Chad Sellers, Karl MacMillan, jwcart2, Joshua Brindle

> -----Original Message-----
> From: Stephen Smalley [mailto:sds@tycho.nsa.gov]
> Sent: Wednesday, January 27, 2010 2:40 PM
> To: Caleb Case
> Cc: selinux@tycho.nsa.gov; Chad Sellers; Karl MacMillan;
> jwcart2@tycho.nsa.gov; Joshua Brindle
> Subject: Re: [PATCH 01/15] [src-policy] refpol language and tools
> 
> On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote:
> > [refpol Language]
> >
> > The refpol language is a simple transformation of a standard
Reference
> > Policy module consisting of 3 files to a single file format with
> > sections. Each Reference Policy file is placed into a refpol section
as
> > follows:
> >
> >    <module>.if   =>   [interface]
> >    <module>.te   =>   [policy]
> >    <module>.fc   =>   [context]
> >
> > * These are the only valid section headers.
> >
> > * A section begins with a section marker and ends with the next
marker
> >   encountered or the end of the file.
> >
> > * If a file has at least one section marker and there is text before
the
> >   first section then this is an error.
> >
> > * There can be at most one of each valid section marker in a file.
> >
> > * A file without any section markers is assumed to be only policy.
> >
> > * The valid contents of each section are the same as for the
separate
> >   reference policy files.
> >
> > * The standard filename extension is '.ref'.
> >
> > [refpol Tool]
> >
> > The refpol tool can create a refpol module from a Reference Policy
> > module.
> >
> >    Usage: refpol COMMAND [OPTIONS] MODULE.ref
> >
> >    Commands:
> >      create		create a new refpol
> >      extract		extract .if, .te, and .fc files from a
refpol
> >
> >    Options:
> >      --version             show program's version number and exit
> >      -h, --help            show this help message and exit
> >      -f, --force           force overwriting existing files
> >
> >      Create options:
> >        -i FILE, --interface=FILE
> >                            interface file
> >        -p FILE, --policy=FILE
> >                            policy file
> >        -c FILE, --context=FILE
> >                            context file
> >
> > Example:
> >
> > # refpol create -i alsa.if -p alsa.te -c alsa.fc alsa.ref
> >
> > refpol modules should have the '.ref' extension. The resulting
alsa.ref
> > looks like this:
> >
> >    [interface]
> >
> >    policy_module(alsa, 1.8.0)
> 
> The policy_module() declaration in existing modules is in their .te
> file, not their .if file.
> 
> If you are going to move up the declaration, then:
> a) What you say earlier about the mapping of the current files and the
> valid contents of the sections is not entirely accurate, and
> b) Wouldn't it make more sense to move the declaration to the very
> beginning before the three sections, as it pertains to all three?

Sorry, this is a typo. I seem to have swapped the [policy] and
[interface] sections. The tool doesn't move the policy_module statement.

> 
> >
> >    ########################################
> >    #
> >    # Declarations
> >    #
> >    <snip>
> >
> >    [policy]
> >    ## <summary>Ainit ALSA configuration tool</summary>
> >    <snip>
> >
> >    [context]
> >    /bin/alsaunmute		--
> 	gen_context(system_u:object_r:alsa_exec_t,s0)
> >    <snip>
> >
> > [refpol HLL compiler]
> >
> > The refpolc high level language (HLL) compiler performs basic
formatting
> > checks and extracts the policy version from the policy_module
statement.
> >
> >    Usage: refpolc [OPTIONS] [MODULE]
> >
> >    Input is read from stdin unless MODULE is provided.
> >    Output is written to stdout unless -o is specified.
> >
> >    Options:
> >      --version             show program's version number and exit
> >      -h, --help            show this help message and exit
> >      -f, --force           force overwriting existing files
> >      -o FILE, --output=FILE
> >                            output file
> >
> > Example:
> >
> > # refpolc < apache.ref > apache.cil 3<> apache.version
> 
> --
> Stephen Smalley
> National Security Agency



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 00/15] RFC Source Policy Support
  2010-01-26 22:08 [PATCH 00/15] RFC Source Policy Support Caleb Case
  2010-01-26 22:08 ` [PATCH 01/15] [src-policy] refpol language and tools Caleb Case
  2010-01-26 22:41 ` [PATCH 00/15] RFC Source Policy Support Xavier Toth
@ 2010-01-27 20:00 ` Stephen Smalley
  2010-01-27 20:18   ` Caleb Case
  2 siblings, 1 reply; 34+ messages in thread
From: Stephen Smalley @ 2010-01-27 20:00 UTC (permalink / raw)
  To: Caleb Case; +Cc: selinux, csellers, kmacmillan, jwcart2, jbrindle

On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote:
<snip>
> Module Ordering - The current reference policy compilation
> infrastructure devotes substantial attention to dealing with ordering
> problems. Some of these problems are fundamental (such as the ordering
> of portcon statements) while others are an artifact of the current
> compiler and M4 (such as the need to separate out interface statements
> in .if files). Rather than devote substantial effort to creating
> mechanisms for specifying or dealing with ordering, it was felt that the
> long term solution to this problem is in the improvements that will come
> from the proposed common intermediate language [1]. Therefore, in the
> short term, several modules will be ordered specially based upon name
> and certain policy statements will only be supported in those specially
> ordered modules (e.g., a module for specifying defines such as
> DISTRO_REDHAT). These hacks can be removed at a later date.

These specially ordered modules and restrictions on policy statements
usable by other modules sound just like the base module today.  Did you
just re-invent the base module under a different name?

> Base Module Removal - The decision to support a special base binary
> module was made to make bootstrapping a module store easier by including
> a module that was required to have a minimal but complete system policy
> and to deal with ordering by only allowing order dependent statements to
> appear in the base (such as object class or portcon). Over time it has
> become clear that the base module limitations outweigh any of the
> intended benefits. This is especially true as support for overriding
> policy modules is included. Therefore, the source semanage store will no
> longer support or require a special base module.  Further, there will be
> no restrictions on the use of policy statements in modules. While this
> will allow some unintentional mistakes (e.g., including a broad portcon
> in a module that gets processed first) it will also allow additional
> freedom (e.g., the use of narrow portcon statements in modules).

I originally assumed you considered portcon statements to be one of the
statements limited to the specially ordered modules above, but evidently
not.  So how then will you ensure proper ordering of them?

Why not just eliminate the ordering dependency altogether from portcons.
Just mandate that more specific entries (e.g. portcon 80) always take
precedence over less specific entries (e.g. portcon 1-1024), and sort
them accordingly in the toolchain before generating the kernel policy.

> [User Experience Overview]
> 
> The overall user experience will shift from using external tools to
> compile a policy package (.pp) to working directly with source modules.
> 
> Source modules will be a single text file containing all of the policy
> for that module. For the current reference policy that will require
> combining the current interface, type enforcement, and file context
> files into a single text file. The user will then use that text file
> similarly to how the current binary modules are used. Insertion would be
> performed using semodule (the 'ref' extension is for the single file
> reference policy format):
> 
> # semodule -i apache.ref
> 
> Note that the language for the module will be inferred from the
> extension to avoid the general tools, such as semodule, needing an
> awareness of the format of all source policies. The name would be taken
> from the input filename.

I assume you mean that you don't want libsemanage to need to be aware of
the format of all source policies, as semodule itself shouldn't ever
peer inside of the module?

If I try to insert two modules with the same prefix but different
suffixes, are they one module or two different ones?

> The first large change to user experience is the introduction of a
> command to retrieve a module:
> 
> # semodule -g apache
> # ls
> apache.ref
>
> # semodule -g apache -o myapache.ref
> # ls
> myapache.ref
> 
> Similarly, there is the addition of an edit command that is similar to
> sudoedit. This is purely a convenience; it will retrieve the module to a
> temporary location and install it after updates are made.
> 
> # semodule --edit apache
> 
> Finally, semodule now supports adding a user message when making
> changes:
> 
> # semodule --edit apache -m "Allow apache to execute cowsay."

Do we really need/want to provide this functionality in
semodule/libsemanage?  Why not just have the user get the module, edit
it as desired, and then insert it?  By the way, this could also be
referred to as checkout and checkin/commit.

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 06/15] [src-policy] libsemanage: compile hll module
  2010-01-26 22:08           ` [PATCH 06/15] [src-policy] libsemanage: compile hll module Caleb Case
  2010-01-26 22:08             ` [PATCH 07/15] [src-policy] libsemanage: compile common intermediary language Caleb Case
@ 2010-01-27 20:18             ` Stephen Smalley
  2010-01-27 20:42               ` Caleb Case
  2010-01-27 20:46               ` Caleb Case
  1 sibling, 2 replies; 34+ messages in thread
From: Stephen Smalley @ 2010-01-27 20:18 UTC (permalink / raw)
  To: Caleb Case; +Cc: selinux, csellers, kmacmillan, jwcart2, jbrindle

On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote:
> This provides the basic compilation function semanage_compile_hll that
> is called during module installation. semanage_exec is a helper function
> which sets up the redirected io for the child process, executes it,
> waits for the child to exit, and then propagates the child's exit
> status. An additional helper function semanage_fd_to_data reads a given
> file descriptor into a buffer (unzipping it if necessary). The
> compilation messages are stored in
> /var/lib/selinux/.../modules/<priority>/<module>/log.

> diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
> index 2bda1e2..dd96a75 100644
> --- a/libsemanage/src/semanage_store.c
> +++ b/libsemanage/src/semanage_store.c
> @@ -3034,3 +3034,357 @@ int semanage_nc_sort(semanage_handle_t * sh, const char *buf, size_t buf_len,
>  
>  	return 0;
>  }
> +
> +/* Execute @cmd with @args and redirect the @io.
> + *
> + * @io is an array of fd's to redirect. Indices correspond to fds. The fds
> + * are not closed. Indices set to -1 are ignored, otherwise they are
> + * dup2'd.
> + *
> + * Returns:
> + * 	 0	success
> + * 	-1	failure, error outside HLL compiler
> + * 	+N	failure, HLL compiler exit status N
> + */
> +static int semanage_exec(semanage_handle_t *sh,
> +			 const char *cmd,
> +			 char *argv[],
> +			 int io[],
> +			 int io_len)

Can this function be unified with the already existing
semanage_exec_prog()?  Likely by making the latter call this one after
splitting args?

> +int semanage_fd_to_data(semanage_handle_t *sh,
> +			int fd,
> +			char **data,
> +			size_t *data_len)
> +{
> +	assert(sh);
> +	assert(data);
> +	assert(data_len);
> +
> +	int status = 0;
> +	int ret = 0;
> +
> +	*data = NULL;
> +	*data_len = 0;
> +
> +	FILE *fp = NULL;
> +	struct stat sb;
> +	sb.st_size = 0;
> +	ssize_t nread = 0;
> +	char *data_tmp = NULL;
> +
> +	/* Find out how big it is. */
> +	ret = fstat(fd, &sb);
> +	if (ret != 0) {
> +		ERR(sh, "Failed to stat file");
> +		status = -2;
> +		goto cleanup;
> +	}
> +	*data_len = sb.st_size;
> +
> +	/* Allocate a buffer for the file. */
> +	*data = malloc(*data_len + 1);
> +	if (*data == NULL) {
> +		ERR(sh, "Out of memory!");
> +		status = -1;
> +		goto cleanup;
> +	}
> +	(*data)[*data_len] = '\0';

Aren't we going to clobber this shortly?

> +
> +	/* Read into the buffer. */
> +	while((size_t)nread != *data_len) {
> +		nread = read(fd, *data + nread, *data_len - nread);
> +		if (nread < 0) {

We should likely handle EINTR more cleanly throughout.

> +			ERR(sh, "Failed to read the file");
> +			status = -1;
> +			goto cleanup;
> +		}
> +	}
> +
> +	/* Try to bunzip. */
> +	fp = fmemopen(*data, *data_len, "r");
> +	if (fp == NULL) {
> +		ERR(sh, "Failed to open file for reading");
> +		status = -1;
> +		goto cleanup;
> +	}

I have a patch to eliminate use of fmemopen() in libsemanage as it
doesn't handle binary files correctly for glibc < 2.9; see the other
discussion.  Maybe this is ok due to only acting on text files?

> +
> +	nread = bunzip(sh, fp, &data_tmp);
> +	if (nread > 0) {
> +		free(*data);
> +		*data = data_tmp;
> +		*data_len = (size_t)nread;
> +	}
> +
> +cleanup:
> +	if (status != 0) {
> +		free(*data);
> +		*data = NULL;
> +		*data_len = 0;
> +	}
> +
> +	if (fp != NULL) fclose(fp);
> +
> +	return status;
> +}
> +
> +int semanage_compile_hll(semanage_handle_t *sh,
> +			 const semanage_module_info_t *modinfo)
> +{
> +	int status = 0;
> +	int ret = 0;
> +
> +	char hll_path[PATH_MAX];
> +	char cil_path[PATH_MAX];
> +	char ver_path[PATH_MAX];
> +	char log_path[PATH_MAX];
> +
> +	char tmp[] = "/tmp/libsemanage-XXXXXX";
> +	int tmp_fd = -1;
> +	ssize_t nwrite = 0;
> +
> +	int io[4];
> +	int io_len = 4;
> +
> +	const semanage_lang_conf_t *conf = NULL;
> +
> +	int i;
> +
> +	char **argv = NULL;
> +
> +	char *data = NULL;
> +	size_t data_len = 0;
> +
> +	/* determine paths and setup io:
> +	 *
> +	 * 0	hll
> +	 * 1	cil
> +	 * 2	log
> +	 * 3	version
> +	 */
> +
> +	/* 0	hll */
> +	ret = semanage_module_get_path(sh,
> +				       modinfo,
> +				       SEMANAGE_MODULE_PATH_HLL,
> +				       hll_path,
> +				       sizeof(hll_path));
> +	if (ret != 0) {
> +		status = -1;
> +		goto cleanup;
> +	}
> +
> +	/* open hll, read in (which will bunzip if necessary) */
> +	tmp_fd = open(hll_path, O_RDONLY);
> +	if (tmp_fd < 0) {
> +		ERR(sh, "Failed to open %s", hll_path);
> +		status = -1;
> +		goto cleanup;
> +	}
> +
> +	ret = semanage_fd_to_data(sh, tmp_fd, &data, &data_len);
> +	if (ret != 0) {
> +		ERR(sh, "Failed to read %s", hll_path);
> +		status = -1;
> +		goto cleanup;
> +	}
> +
> +	close(tmp_fd);
> +	tmp_fd = mkstemp(tmp);
> +	if (tmp_fd < 0) {
> +		ERR(sh,
> +		    "Failed to create tmp file for module %s.",
> +		    modinfo->name);
> +		status = -1;
> +		goto cleanup;
> +	}
> +
> +	while((size_t)nwrite != data_len) {
> +		nwrite = write(tmp_fd, data + nwrite, data_len - nwrite);
> +		if (nwrite < 0) {

EINTR handling.
Need to check that the expected length was written, not just < 0.
>From the man page:
       If  a  write()  is interrupted by a signal handler before any bytes are
       written, then the call fails with the error EINTR; if it is interrupted
       after  at  least  one  byte  has  been  written, the call succeeds, and
       returns the number of bytes written.

> +			ERR(sh,
> +			    "Failed to write data to tmp file for module %s.",
> +			    modinfo->name);
> +			status = -1;
> +			goto cleanup;
> +		}
> +	}
> +
> +	ret = fsync(tmp_fd);

fdatasync(), maybe?

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* RE: [PATCH 00/15] RFC Source Policy Support
  2010-01-27 20:00 ` Stephen Smalley
@ 2010-01-27 20:18   ` Caleb Case
  0 siblings, 0 replies; 34+ messages in thread
From: Caleb Case @ 2010-01-27 20:18 UTC (permalink / raw)
  To: Stephen Smalley
  Cc: selinux, Chad Sellers, Karl MacMillan, jwcart2, Joshua Brindle

> -----Original Message-----
> From: Stephen Smalley [mailto:sds@tycho.nsa.gov]
> Sent: Wednesday, January 27, 2010 3:00 PM
> To: Caleb Case
> Cc: selinux@tycho.nsa.gov; Chad Sellers; Karl MacMillan;
> jwcart2@tycho.nsa.gov; Joshua Brindle
> Subject: Re: [PATCH 00/15] RFC Source Policy Support
> 
> On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote:
> <snip>
> > Module Ordering - The current reference policy compilation
> > infrastructure devotes substantial attention to dealing with
ordering
> > problems. Some of these problems are fundamental (such as the
ordering
> > of portcon statements) while others are an artifact of the current
> > compiler and M4 (such as the need to separate out interface
statements
> > in .if files). Rather than devote substantial effort to creating
> > mechanisms for specifying or dealing with ordering, it was felt that
the
> > long term solution to this problem is in the improvements that will
come
> > from the proposed common intermediate language [1]. Therefore, in
the
> > short term, several modules will be ordered specially based upon
name
> > and certain policy statements will only be supported in those
specially
> > ordered modules (e.g., a module for specifying defines such as
> > DISTRO_REDHAT). These hacks can be removed at a later date.
> 
> These specially ordered modules and restrictions on policy statements
> usable by other modules sound just like the base module today.  Did
you
> just re-invent the base module under a different name?

The special modules are something like a base module that has been
broken out into its individual parts. We broke it out like this so that
it would match more closely with what was in the reference policy build
environment and to promote them being separate files (similar to how we
would expect them to be in the proposed cil). Having the base module
split out like this also has the advantage that you can override just a
small part of 'base' without needing to fork all the rest of it.

> 
> > Base Module Removal - The decision to support a special base binary
> > module was made to make bootstrapping a module store easier by
including
> > a module that was required to have a minimal but complete system
policy
> > and to deal with ordering by only allowing order dependent
statements to
> > appear in the base (such as object class or portcon). Over time it
has
> > become clear that the base module limitations outweigh any of the
> > intended benefits. This is especially true as support for overriding
> > policy modules is included. Therefore, the source semanage store
will no
> > longer support or require a special base module.  Further, there
will be
> > no restrictions on the use of policy statements in modules. While
this
> > will allow some unintentional mistakes (e.g., including a broad
portcon
> > in a module that gets processed first) it will also allow additional
> > freedom (e.g., the use of narrow portcon statements in modules).
> 
> I originally assumed you considered portcon statements to be one of
the
> statements limited to the specially ordered modules above, but
evidently
> not.  So how then will you ensure proper ordering of them?

For the most part they are expected to be part of the special modules.
You could pull out specific portcon statements (simple non-ranged ones)
into the modules if you were certain that no other portcons existed for
those ports.

> 
> Why not just eliminate the ordering dependency altogether from
portcons.
> Just mandate that more specific entries (e.g. portcon 80) always take
> precedence over less specific entries (e.g. portcon 1-1024), and sort
> them accordingly in the toolchain before generating the kernel policy.

How would these be sorted?

portcon 1-3
portcon 3-5
portcon 2-4

I think the long term goal is to use an fcglob style sorting (where the
above would be an error since its ambiguous). That kind of sorting would
be part of the proposed cil. (You are right it makes more sense for them
to be sorted in toolchain, we just haven't gotten to the point where we
can do that yet).

> 
> > [User Experience Overview]
> >
> > The overall user experience will shift from using external tools to
> > compile a policy package (.pp) to working directly with source
modules.
> >
> > Source modules will be a single text file containing all of the
policy
> > for that module. For the current reference policy that will require
> > combining the current interface, type enforcement, and file context
> > files into a single text file. The user will then use that text file
> > similarly to how the current binary modules are used. Insertion
would be
> > performed using semodule (the 'ref' extension is for the single file
> > reference policy format):
> >
> > # semodule -i apache.ref
> >
> > Note that the language for the module will be inferred from the
> > extension to avoid the general tools, such as semodule, needing an
> > awareness of the format of all source policies. The name would be
taken
> > from the input filename.
> 
> I assume you mean that you don't want libsemanage to need to be aware
of
> the format of all source policies, as semodule itself shouldn't ever
> peer inside of the module?

Yes

> 
> If I try to insert two modules with the same prefix but different
> suffixes, are they one module or two different ones?

One

> 
> > The first large change to user experience is the introduction of a
> > command to retrieve a module:
> >
> > # semodule -g apache
> > # ls
> > apache.ref
> >
> > # semodule -g apache -o myapache.ref
> > # ls
> > myapache.ref
> >
> > Similarly, there is the addition of an edit command that is similar
to
> > sudoedit. This is purely a convenience; it will retrieve the module
to a
> > temporary location and install it after updates are made.
> >
> > # semodule --edit apache
> >
> > Finally, semodule now supports adding a user message when making
> > changes:
> >
> > # semodule --edit apache -m "Allow apache to execute cowsay."
> 
> Do we really need/want to provide this functionality in
> semodule/libsemanage?  Why not just have the user get the module, edit
> it as desired, and then insert it?  By the way, this could also be
> referred to as checkout and checkin/commit.

--get is not the same as checkout since someone else could modify the
file while you are editing it. --edit is designed to address that
problem by allowing you to do it within a single transaction lock.

> 
> --
> Stephen Smalley
> National Security Agency



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 12/15] [src-policy] semodule: edit module
  2010-01-26 22:08                       ` [PATCH 12/15] [src-policy] semodule: edit module Caleb Case
  2010-01-26 22:08                         ` [PATCH 13/15] [src-policy] libsemanage: ChangeLog support Caleb Case
@ 2010-01-27 20:21                         ` Stephen Smalley
  1 sibling, 0 replies; 34+ messages in thread
From: Stephen Smalley @ 2010-01-27 20:21 UTC (permalink / raw)
  To: Caleb Case; +Cc: selinux, csellers, kmacmillan, jwcart2, jbrindle

On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote:
> In order to ease the process of modifying an installed module, this
> provides the -E,--edit option to semodule. It will retrieve the
> specified module, open it in the default editor, and then reinstall the
> module if editing completes successfully.
> 
> * Editor to be executed is discovered from the EDITOR environment
>   variable.
> 
> * Transaction locks are held for the duration of the editing.
> 
> * If -E is specified multiple times, then the editor will be
>   called on each one, consecutively (editing stops on a particular
>   module when the editor exits).
> 
> * If the editor exits with a non-zero status, then the transaction
>   will be aborted.
> 
> * If the editor exits without making any changes to the file (as
>   determined from the time stamp), then the transaction will be not be
>   committed unless another action requires it to be.
> 
> * The editor will be executed in the users SELinux context (as
>   determined by getprevcon)
> 
> Example:
> 
> # export EDITOR=vim
> # semodule -E alsa
> <edit alsa module>
> <after quiting editor module is installed>
> ---

I'm concerned that this is over-engineering.  Why not just provide -g
(aka --checkout) and -i (aka --commit or --checkin), and let the editing
happen entirely outside of the infrastructure.  Do we really want to
allow the caller to hold the transaction locks indefinitely?

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* RE: [PATCH 06/15] [src-policy] libsemanage: compile hll module
  2010-01-27 20:18             ` [PATCH 06/15] [src-policy] libsemanage: compile hll module Stephen Smalley
@ 2010-01-27 20:42               ` Caleb Case
  2010-01-27 20:46               ` Caleb Case
  1 sibling, 0 replies; 34+ messages in thread
From: Caleb Case @ 2010-01-27 20:42 UTC (permalink / raw)
  To: Stephen Smalley
  Cc: selinux, Chad Sellers, Karl MacMillan, jwcart2, Joshua Brindle



> -----Original Message-----
> From: Stephen Smalley [mailto:sds@tycho.nsa.gov]
> Sent: Wednesday, January 27, 2010 3:18 PM
> To: Caleb Case
> Cc: selinux@tycho.nsa.gov; Chad Sellers; Karl MacMillan;
> jwcart2@tycho.nsa.gov; Joshua Brindle
> Subject: Re: [PATCH 06/15] [src-policy] libsemanage: compile hll
module
> 
> On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote:
> > This provides the basic compilation function semanage_compile_hll
that
> > is called during module installation. semanage_exec is a helper
function
> > which sets up the redirected io for the child process, executes it,
> > waits for the child to exit, and then propagates the child's exit
> > status. An additional helper function semanage_fd_to_data reads a
given
> > file descriptor into a buffer (unzipping it if necessary). The
> > compilation messages are stored in
> > /var/lib/selinux/.../modules/<priority>/<module>/log.
> 
> > diff --git a/libsemanage/src/semanage_store.c
> b/libsemanage/src/semanage_store.c
> > index 2bda1e2..dd96a75 100644
> > --- a/libsemanage/src/semanage_store.c
> > +++ b/libsemanage/src/semanage_store.c
> > @@ -3034,3 +3034,357 @@ int semanage_nc_sort(semanage_handle_t * sh,
> const char *buf, size_t buf_len,
> >
> >  	return 0;
> >  }
> > +
> > +/* Execute @cmd with @args and redirect the @io.
> > + *
> > + * @io is an array of fd's to redirect. Indices correspond to fds.
The
> fds
> > + * are not closed. Indices set to -1 are ignored, otherwise they
are
> > + * dup2'd.
> > + *
> > + * Returns:
> > + * 	 0	success
> > + * 	-1	failure, error outside HLL compiler
> > + * 	+N	failure, HLL compiler exit status N
> > + */
> > +static int semanage_exec(semanage_handle_t *sh,
> > +			 const char *cmd,
> > +			 char *argv[],
> > +			 int io[],
> > +			 int io_len)
> 
> Can this function be unified with the already existing
> semanage_exec_prog()?  Likely by making the latter call this one after
> splitting args?

Yes, I'll switch it around.

> 
> > +int semanage_fd_to_data(semanage_handle_t *sh,
> > +			int fd,
> > +			char **data,
> > +			size_t *data_len)
> > +{
> > +	assert(sh);
> > +	assert(data);
> > +	assert(data_len);
> > +
> > +	int status = 0;
> > +	int ret = 0;
> > +
> > +	*data = NULL;
> > +	*data_len = 0;
> > +
> > +	FILE *fp = NULL;
> > +	struct stat sb;
> > +	sb.st_size = 0;
> > +	ssize_t nread = 0;
> > +	char *data_tmp = NULL;
> > +
> > +	/* Find out how big it is. */
> > +	ret = fstat(fd, &sb);
> > +	if (ret != 0) {
> > +		ERR(sh, "Failed to stat file");
> > +		status = -2;
> > +		goto cleanup;
> > +	}
> > +	*data_len = sb.st_size;
> > +
> > +	/* Allocate a buffer for the file. */
> > +	*data = malloc(*data_len + 1);
> > +	if (*data == NULL) {
> > +		ERR(sh, "Out of memory!");
> > +		status = -1;
> > +		goto cleanup;
> > +	}
> > +	(*data)[*data_len] = '\0';
> 
> Aren't we going to clobber this shortly?
> 
> > +
> > +	/* Read into the buffer. */
> > +	while((size_t)nread != *data_len) {
> > +		nread = read(fd, *data + nread, *data_len - nread);
> > +		if (nread < 0) {
> 
> We should likely handle EINTR more cleanly throughout.
> 
> > +			ERR(sh, "Failed to read the file");
> > +			status = -1;
> > +			goto cleanup;
> > +		}
> > +	}
> > +
> > +	/* Try to bunzip. */
> > +	fp = fmemopen(*data, *data_len, "r");
> > +	if (fp == NULL) {
> > +		ERR(sh, "Failed to open file for reading");
> > +		status = -1;
> > +		goto cleanup;
> > +	}
> 
> I have a patch to eliminate use of fmemopen() in libsemanage as it
> doesn't handle binary files correctly for glibc < 2.9; see the other
> discussion.  Maybe this is ok due to only acting on text files?

Nope, this is the same problem all over again. I think that the best
option is to switch the interface around to taking a file stream instead
of a file pointer.

> 
> > +
> > +	nread = bunzip(sh, fp, &data_tmp);
> > +	if (nread > 0) {
> > +		free(*data);
> > +		*data = data_tmp;
> > +		*data_len = (size_t)nread;
> > +	}
> > +
> > +cleanup:
> > +	if (status != 0) {
> > +		free(*data);
> > +		*data = NULL;
> > +		*data_len = 0;
> > +	}
> > +
> > +	if (fp != NULL) fclose(fp);
> > +
> > +	return status;
> > +}
> > +
> > +int semanage_compile_hll(semanage_handle_t *sh,
> > +			 const semanage_module_info_t *modinfo)
> > +{
> > +	int status = 0;
> > +	int ret = 0;
> > +
> > +	char hll_path[PATH_MAX];
> > +	char cil_path[PATH_MAX];
> > +	char ver_path[PATH_MAX];
> > +	char log_path[PATH_MAX];
> > +
> > +	char tmp[] = "/tmp/libsemanage-XXXXXX";
> > +	int tmp_fd = -1;
> > +	ssize_t nwrite = 0;
> > +
> > +	int io[4];
> > +	int io_len = 4;
> > +
> > +	const semanage_lang_conf_t *conf = NULL;
> > +
> > +	int i;
> > +
> > +	char **argv = NULL;
> > +
> > +	char *data = NULL;
> > +	size_t data_len = 0;
> > +
> > +	/* determine paths and setup io:
> > +	 *
> > +	 * 0	hll
> > +	 * 1	cil
> > +	 * 2	log
> > +	 * 3	version
> > +	 */
> > +
> > +	/* 0	hll */
> > +	ret = semanage_module_get_path(sh,
> > +				       modinfo,
> > +				       SEMANAGE_MODULE_PATH_HLL,
> > +				       hll_path,
> > +				       sizeof(hll_path));
> > +	if (ret != 0) {
> > +		status = -1;
> > +		goto cleanup;
> > +	}
> > +
> > +	/* open hll, read in (which will bunzip if necessary) */
> > +	tmp_fd = open(hll_path, O_RDONLY);
> > +	if (tmp_fd < 0) {
> > +		ERR(sh, "Failed to open %s", hll_path);
> > +		status = -1;
> > +		goto cleanup;
> > +	}
> > +
> > +	ret = semanage_fd_to_data(sh, tmp_fd, &data, &data_len);
> > +	if (ret != 0) {
> > +		ERR(sh, "Failed to read %s", hll_path);
> > +		status = -1;
> > +		goto cleanup;
> > +	}
> > +
> > +	close(tmp_fd);
> > +	tmp_fd = mkstemp(tmp);
> > +	if (tmp_fd < 0) {
> > +		ERR(sh,
> > +		    "Failed to create tmp file for module %s.",
> > +		    modinfo->name);
> > +		status = -1;
> > +		goto cleanup;
> > +	}
> > +
> > +	while((size_t)nwrite != data_len) {
> > +		nwrite = write(tmp_fd, data + nwrite, data_len -
nwrite);
> > +		if (nwrite < 0) {
> 
> EINTR handling.
> Need to check that the expected length was written, not just < 0.
> >From the man page:
>        If  a  write()  is interrupted by a signal handler before any
bytes
> are
>        written, then the call fails with the error EINTR; if it is
> interrupted
>        after  at  least  one  byte  has  been  written, the call
succeeds,
> and
>        returns the number of bytes written.

Oops, will fix.

> 
> > +			ERR(sh,
> > +			    "Failed to write data to tmp file for module
%s.",
> > +			    modinfo->name);
> > +			status = -1;
> > +			goto cleanup;
> > +		}
> > +	}
> > +
> > +	ret = fsync(tmp_fd);
> 
> fdatasync(), maybe?
> 
> --
> Stephen Smalley
> National Security Agency



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* RE: [PATCH 06/15] [src-policy] libsemanage: compile hll module
  2010-01-27 20:18             ` [PATCH 06/15] [src-policy] libsemanage: compile hll module Stephen Smalley
  2010-01-27 20:42               ` Caleb Case
@ 2010-01-27 20:46               ` Caleb Case
  1 sibling, 0 replies; 34+ messages in thread
From: Caleb Case @ 2010-01-27 20:46 UTC (permalink / raw)
  To: Stephen Smalley
  Cc: selinux, Chad Sellers, Karl MacMillan, jwcart2, Joshua Brindle



> -----Original Message-----
> From: Stephen Smalley [mailto:sds@tycho.nsa.gov]
> Sent: Wednesday, January 27, 2010 3:18 PM
> To: Caleb Case
> Cc: selinux@tycho.nsa.gov; Chad Sellers; Karl MacMillan;
> jwcart2@tycho.nsa.gov; Joshua Brindle
> Subject: Re: [PATCH 06/15] [src-policy] libsemanage: compile hll
module
> 
> On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote:
> > This provides the basic compilation function semanage_compile_hll
that
> > is called during module installation. semanage_exec is a helper
function
> > which sets up the redirected io for the child process, executes it,
> > waits for the child to exit, and then propagates the child's exit
> > status. An additional helper function semanage_fd_to_data reads a
given
> > file descriptor into a buffer (unzipping it if necessary). The
> > compilation messages are stored in
> > /var/lib/selinux/.../modules/<priority>/<module>/log.
> 
> > diff --git a/libsemanage/src/semanage_store.c
> b/libsemanage/src/semanage_store.c
> > index 2bda1e2..dd96a75 100644
> > --- a/libsemanage/src/semanage_store.c
> > +++ b/libsemanage/src/semanage_store.c
> > @@ -3034,3 +3034,357 @@ int semanage_nc_sort(semanage_handle_t * sh,
> const char *buf, size_t buf_len,
> >
> >  	return 0;
> >  }
> > +
> > +/* Execute @cmd with @args and redirect the @io.
> > + *
> > + * @io is an array of fd's to redirect. Indices correspond to fds.
The
> fds
> > + * are not closed. Indices set to -1 are ignored, otherwise they
are
> > + * dup2'd.
> > + *
> > + * Returns:
> > + * 	 0	success
> > + * 	-1	failure, error outside HLL compiler
> > + * 	+N	failure, HLL compiler exit status N
> > + */
> > +static int semanage_exec(semanage_handle_t *sh,
> > +			 const char *cmd,
> > +			 char *argv[],
> > +			 int io[],
> > +			 int io_len)
> 
> Can this function be unified with the already existing
> semanage_exec_prog()?  Likely by making the latter call this one after
> splitting args?
> 
> > +int semanage_fd_to_data(semanage_handle_t *sh,
> > +			int fd,
> > +			char **data,
> > +			size_t *data_len)
> > +{
> > +	assert(sh);
> > +	assert(data);
> > +	assert(data_len);
> > +
> > +	int status = 0;
> > +	int ret = 0;
> > +
> > +	*data = NULL;
> > +	*data_len = 0;
> > +
> > +	FILE *fp = NULL;
> > +	struct stat sb;
> > +	sb.st_size = 0;
> > +	ssize_t nread = 0;
> > +	char *data_tmp = NULL;
> > +
> > +	/* Find out how big it is. */
> > +	ret = fstat(fd, &sb);
> > +	if (ret != 0) {
> > +		ERR(sh, "Failed to stat file");
> > +		status = -2;
> > +		goto cleanup;
> > +	}
> > +	*data_len = sb.st_size;
> > +
> > +	/* Allocate a buffer for the file. */
> > +	*data = malloc(*data_len + 1);
> > +	if (*data == NULL) {
> > +		ERR(sh, "Out of memory!");
> > +		status = -1;
> > +		goto cleanup;
> > +	}
> > +	(*data)[*data_len] = '\0';
> 
> Aren't we going to clobber this shortly?
> 
> > +
> > +	/* Read into the buffer. */
> > +	while((size_t)nread != *data_len) {
> > +		nread = read(fd, *data + nread, *data_len - nread);
> > +		if (nread < 0) {
> 
> We should likely handle EINTR more cleanly throughout.
> 
> > +			ERR(sh, "Failed to read the file");
> > +			status = -1;
> > +			goto cleanup;
> > +		}
> > +	}
> > +
> > +	/* Try to bunzip. */
> > +	fp = fmemopen(*data, *data_len, "r");
> > +	if (fp == NULL) {
> > +		ERR(sh, "Failed to open file for reading");
> > +		status = -1;
> > +		goto cleanup;
> > +	}
> 
> I have a patch to eliminate use of fmemopen() in libsemanage as it
> doesn't handle binary files correctly for glibc < 2.9; see the other
> discussion.  Maybe this is ok due to only acting on text files?
> 
> > +
> > +	nread = bunzip(sh, fp, &data_tmp);
> > +	if (nread > 0) {
> > +		free(*data);
> > +		*data = data_tmp;
> > +		*data_len = (size_t)nread;
> > +	}
> > +
> > +cleanup:
> > +	if (status != 0) {
> > +		free(*data);
> > +		*data = NULL;
> > +		*data_len = 0;
> > +	}
> > +
> > +	if (fp != NULL) fclose(fp);
> > +
> > +	return status;
> > +}
> > +
> > +int semanage_compile_hll(semanage_handle_t *sh,
> > +			 const semanage_module_info_t *modinfo)
> > +{
> > +	int status = 0;
> > +	int ret = 0;
> > +
> > +	char hll_path[PATH_MAX];
> > +	char cil_path[PATH_MAX];
> > +	char ver_path[PATH_MAX];
> > +	char log_path[PATH_MAX];
> > +
> > +	char tmp[] = "/tmp/libsemanage-XXXXXX";
> > +	int tmp_fd = -1;
> > +	ssize_t nwrite = 0;
> > +
> > +	int io[4];
> > +	int io_len = 4;
> > +
> > +	const semanage_lang_conf_t *conf = NULL;
> > +
> > +	int i;
> > +
> > +	char **argv = NULL;
> > +
> > +	char *data = NULL;
> > +	size_t data_len = 0;
> > +
> > +	/* determine paths and setup io:
> > +	 *
> > +	 * 0	hll
> > +	 * 1	cil
> > +	 * 2	log
> > +	 * 3	version
> > +	 */
> > +
> > +	/* 0	hll */
> > +	ret = semanage_module_get_path(sh,
> > +				       modinfo,
> > +				       SEMANAGE_MODULE_PATH_HLL,
> > +				       hll_path,
> > +				       sizeof(hll_path));
> > +	if (ret != 0) {
> > +		status = -1;
> > +		goto cleanup;
> > +	}
> > +
> > +	/* open hll, read in (which will bunzip if necessary) */
> > +	tmp_fd = open(hll_path, O_RDONLY);
> > +	if (tmp_fd < 0) {
> > +		ERR(sh, "Failed to open %s", hll_path);
> > +		status = -1;
> > +		goto cleanup;
> > +	}
> > +
> > +	ret = semanage_fd_to_data(sh, tmp_fd, &data, &data_len);
> > +	if (ret != 0) {
> > +		ERR(sh, "Failed to read %s", hll_path);
> > +		status = -1;
> > +		goto cleanup;
> > +	}
> > +
> > +	close(tmp_fd);
> > +	tmp_fd = mkstemp(tmp);
> > +	if (tmp_fd < 0) {
> > +		ERR(sh,
> > +		    "Failed to create tmp file for module %s.",
> > +		    modinfo->name);
> > +		status = -1;
> > +		goto cleanup;
> > +	}
> > +
> > +	while((size_t)nwrite != data_len) {
> > +		nwrite = write(tmp_fd, data + nwrite, data_len -
nwrite);
> > +		if (nwrite < 0) {
> 
> EINTR handling.
> Need to check that the expected length was written, not just < 0.
> >From the man page:
>        If  a  write()  is interrupted by a signal handler before any
bytes
> are
>        written, then the call fails with the error EINTR; if it is
> interrupted
>        after  at  least  one  byte  has  been  written, the call
succeeds,
> and
>        returns the number of bytes written.
> 
> > +			ERR(sh,
> > +			    "Failed to write data to tmp file for module
%s.",
> > +			    modinfo->name);
> > +			status = -1;
> > +			goto cleanup;
> > +		}
> > +	}
> > +
> > +	ret = fsync(tmp_fd);
> 
> fdatasync(), maybe?

That should work, I'll try it.

> 
> --
> Stephen Smalley
> National Security Agency



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 11/15] [src-policy] semodule: get module source
  2010-01-26 22:08                     ` [PATCH 11/15] [src-policy] semodule: get module source Caleb Case
  2010-01-26 22:08                       ` [PATCH 12/15] [src-policy] semodule: edit module Caleb Case
@ 2010-01-28 20:52                       ` James Carter
  1 sibling, 0 replies; 34+ messages in thread
From: James Carter @ 2010-01-28 20:52 UTC (permalink / raw)
  To: Caleb Case; +Cc: selinux, csellers, kmacmillan, jbrindle, sds

On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote:
> This adds the ability to retrieve the module source using semodule.
> 
>   -g,--get=MODULE_NAME [-o FILE] [-c] get module source
> 
> * More than one -g is allowed per command invocation.
> 
> * If output_name is “-“ then output is sent to standard out.
> 
> * If output is specified multiple times with oufile_name "-", then
>   append to stdout.
> 
> * If -o is not specified then the module is output to
>   <module name>.<language ext> in the current directory.
> 
> * If there is an existing file with the output file name (with or
>   without -o), then emit error and exit.
> 
> * -c will output the CIL instead of the source format.
> 
> Example:
> 
> # semodule -g alsa
> 
> This will retrieve the high level language source for the alsa module
> and save it to alsa.ref in the current directory.
> ---
>  policycoreutils/semodule/semodule.8 |    3 +
>  policycoreutils/semodule/semodule.c |  227 ++++++++++++++++++++++++++++++++++-
>  2 files changed, 228 insertions(+), 2 deletions(-)
> 
> diff --git a/policycoreutils/semodule/semodule.8 b/policycoreutils/semodule/semodule.8
> index 5fc10b3..bb6ae49 100644
> --- a/policycoreutils/semodule/semodule.8
> +++ b/policycoreutils/semodule/semodule.8
> @@ -55,6 +55,9 @@ enable module
>  .B  \-d,\-\-disable=MODULE_NAME
>  disable module
>  .TP
> +.B  \-g,\-\-get=MODULE_NAME [-o,--output=FILE] [-c,--cil]
> +Outputs module source to MODULE_NAME.ref. If output is set to '-' outputs on stdout, otherwise, outputs to the specified FILE. If cil is specified, then outputs the cil source instead of the original source.
> +.TP
>  .B  \-s,\-\-store	   
>  name of the store to operate on
>  .TP
> diff --git a/policycoreutils/semodule/semodule.c b/policycoreutils/semodule/semodule.c
> index c6b0d3c..0e3cc76 100644
> --- a/policycoreutils/semodule/semodule.c
> +++ b/policycoreutils/semodule/semodule.c
> @@ -20,6 +20,7 @@
>  #include <sys/mman.h>
>  #include <sys/stat.h>
>  #include <sys/types.h>
> +#include <limits.h>
>  
>  #include <semanage/modules.h>
>  
> @@ -27,17 +28,22 @@
>  
>  enum client_modes {
>  	NO_MODE, INSTALL_M, UPGRADE_M, BASE_M, REMOVE_M,
> -	LIST_M, RELOAD, PRIORITY_M, ENABLE_M, DISABLE_M
> +	LIST_M, RELOAD, PRIORITY_M, ENABLE_M, DISABLE_M,
> +	GET_M,
>  };
> +
>  /* list of modes in which one ought to commit afterwards */
>  static const int do_commit[] = {
>  	0, 1, 1, 1, 1,
>  	0, 0, 0, 1, 1,
> +	0,
>  };
>  
>  struct command {
>  	enum client_modes mode;
>  	char *arg;
> +	char *output;
> +	int cil;
>  };
>  static struct command *commands = NULL;
>  static int num_commands = 0;
> @@ -61,6 +67,7 @@ static void cleanup(void)
>  {
>  	while (--num_commands >= 0) {
>  		free(commands[num_commands].arg);
> +		free(commands[num_commands].output);
>  	}
>  	free(commands);
>  }
> @@ -117,6 +124,7 @@ static void usage(char *progname)
>  	printf("  -p,--priority=PRIORITY    set priority for following operations (1-999)\n");
>  	printf("  -e,--enable=MODULE_NAME   enable module\n");
>  	printf("  -d,--disable=MODULE_NAME  disable module\n");
> +	printf("  -g,--get=MODULE_NAME [-o FILE] [-c] get module source\n");
>  	printf("Other options:\n");
>  	printf("  -s,--store	   name of the store to operate on\n");
>  	printf("  -n,--noreload	   do not reload policy after commit\n");
> @@ -139,6 +147,8 @@ static void set_mode(enum client_modes new_mode, char *arg)
>  	commands = c;
>  	commands[num_commands].mode = new_mode;
>  	commands[num_commands].arg = NULL;
> +	commands[num_commands].output = NULL;
> +	commands[num_commands].cil = 0;
>  	num_commands++;
>  	if (arg != NULL) {
>  		if ((s = strdup(arg)) == NULL) {
> @@ -169,6 +179,9 @@ static void parse_command_line(int argc, char **argv)
>  		{"priority", required_argument, NULL, 'p'},
>  		{"enable", required_argument, NULL, 'e'},
>  		{"disable", required_argument, NULL, 'd'},
> +		{"get", required_argument, NULL, 'g'},
> +		{"output", required_argument, NULL, 'o'},
> +		{"cil", 0, NULL, 'c'},
>  		{NULL, 0, NULL, 0}
>  	};
>  	int i;
> @@ -178,7 +191,7 @@ static void parse_command_line(int argc, char **argv)
>  	create_store = 0;
>  	priority = 400;
>  	while ((i =
> -		getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnBDp:e:d:", opts,
> +		getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnBDp:e:d:g:o:c", opts,
>  			    NULL)) != -1) {
>  		switch (i) {
>  		case 'b':
> @@ -227,6 +240,53 @@ static void parse_command_line(int argc, char **argv)
>  		case 'd':
>  			set_mode(DISABLE_M, optarg);
>  			break;
> +		case 'g':
> +			set_mode(GET_M, optarg);
> +			break;
> +		case 'o':{
> +			/* no mode specified?? */
> +			if (num_commands == 0) {
> +				usage(argv[0]);
> +				exit(1);
> +			}
> +
> +			struct command *last = &commands[num_commands - 1];
> +
> +			/* only GET_M mode valid with -o */
> +			if (last->mode != GET_M) {
> +				usage(argv[0]);
> +				exit(1);
> +			}
> +
> +			last->output = strdup(optarg);
> +			if (last->output == NULL) {
> +				fprintf(stderr,
> +					"%s: Out of memory!\n",
> +					argv[0]);
> +				exit(1);
> +			}
> +
> +			break;
> +			}
> +		case 'c':{
> +			/* no mode specified?? */
> +			if (num_commands == 0) {
> +				usage(argv[0]);
> +				exit(1);
> +			}
> +
> +			struct command *last = &commands[num_commands - 1];
> +
> +			/* only GET_M mode valid with -c */
> +			if (last->mode != GET_M) {
> +				usage(argv[0]);
> +				exit(1);
> +			}
> +
> +			last->cil = 1;
> +
> +			break;
> +			}
>  		case '?':
>  		default:{
>  				usage(argv[0]);
> @@ -350,6 +410,8 @@ int main(int argc, char *argv[])
>  	for (i = 0; i < num_commands; i++) {
>  		enum client_modes mode = commands[i].mode;
>  		char *mode_arg = commands[i].arg;
> +		char *mode_output = commands[i].output;
> +		int mode_cil = commands[i].cil;
>  
>  		switch (mode) {
>  		case INSTALL_M:{
> @@ -582,6 +644,167 @@ cleanup_disable:
>  
>  				break;
>  			}
> +		case GET_M:{
> +				if (verbose) {
> +					printf("Attempting to get module '%s':\n", mode_arg);
> +				}
> +
> +				semanage_module_key_t *modkey = NULL;
> +				semanage_module_info_t *modinfo = NULL;
> +				const char *lang_ext = NULL;
> +				char *data = NULL;
> +				size_t data_len = 0;
> +
> +				int fd = -1;
> +				FILE *out = NULL;
> +				size_t nwrite = 0;
> +
> +				result = semanage_module_key_create(sh,
> +								    &modkey);
> +				if (result != 0) goto cleanup_get;
> +
> +				result = semanage_module_key_set_priority(
> +						sh,
> +						modkey,
> +						priority);
> +				if (result != 0) goto cleanup_get;
> +
> +				result = semanage_module_key_set_name(
> +						sh,
> +						modkey,
> +						mode_arg);
> +				if (result != 0) goto cleanup_get;
> +
> +				if (mode_cil == 0) {
> +					result = semanage_module_get(
> +							sh,
> +							modkey,
> +							&data,
> +							&data_len);
> +				}
> +				else {
> +					result = semanage_module_get_cil(
> +							sh,
> +							modkey,
> +							&data,
> +							&data_len);
> +				}
> +				if (result != 0) goto cleanup_get;
> +
> +				/* get language extension */
> +				result = semanage_module_get_module_info(
> +						sh,
> +						modkey,
> +						&modinfo);
> +				if (result != 0) goto cleanup_get;
> +
> +				if (mode_cil == 0) {
> +					result = semanage_module_info_get_lang_ext(
> +							sh,
> +							modinfo,
> +							&lang_ext);
> +					if (result != 0) goto cleanup_get;
> +				}
> +				else {
> +					/* current cil is refpol */
> +					lang_ext = "ref";
> +				}
> +
> +				if (mode_output == NULL ||
> +				    strcmp(mode_output, "-") != 0) {
> +					char path[PATH_MAX];
> +
> +					if (mode_output == NULL) {
> +						/* by default write out to <name>.<lang> */
> +						/* compose path */
> +
> +						result = snprintf(path,
> +								  sizeof(path) - 1,
> +								  "%s.%s",
> +								  mode_arg,
> +								  lang_ext);
> +						if (result < 0 ||
> +						    result >= (int)sizeof(path)) {
> +							fprintf(stderr,
> +								"%s: Unable to compose path for output file.\n",
> +								argv[0]);
> +							result = -1;
> +							goto cleanup_get;
> +						}
> +						result = 0;
> +					}
> +					else {
> +						if (strlen(mode_output) > sizeof(path) - 1) {
> +							fprintf(stderr,
> +								"%s: Path too long (%d > %d): '%s'\n",
> +								argv[0],
> +								strlen(mode_output),
> +								sizeof(path) - 1,
> +								mode_output);

I get the following warnings at the fprintf line:

cc -Werror -Wall -W -I/usr/include   -c -o semodule.o semodule.c
cc1: warnings being treated as errors
semodule.c: In function ‘main’:
semodule.c:772: error: format ‘%d’ expects type ‘int’, but argument 4
has type ‘size_t’
semodule.c:772: error: format ‘%d’ expects type ‘int’, but argument 5
has type ‘long unsigned int’
make[2]: *** [semodule.o] Error 1

> +							result = -1;
> +							goto cleanup_get;
> +						}
> +						strcpy(path, mode_output);
> +					}
> +
> +					/* open file iff it doesn't exist */
> +					fd = open(path,
> +						  O_WRONLY | O_CREAT | O_EXCL,
> +						  S_IRUSR | S_IWUSR);
> +					if (fd < 0) {
> +						fprintf(stderr,
> +							"%s: Unable to open output '%s'. (%s)\n",
> +							argv[0],
> +							path,
> +							strerror(errno));
> +						result = -1;
> +						goto cleanup_get;
> +					}
> +
> +					out = fdopen(fd, "w");
> +					if (out == NULL) {
> +						fprintf(stderr,
> +							"%s: Unable to open output '%s'. (%s)\n",
> +							argv[0],
> +							path,
> +							strerror(errno));
> +						result = -1;
> +						goto cleanup_get;
> +					}
> +				}
> +				else {
> +					/* otherwise we must be special '-' */
> +					out = stdout;
> +				}
> +
> +				nwrite = fwrite(data,
> +						data_len,
> +						1,
> +						out);
> +				if (nwrite != 1) {
> +					fprintf(stderr,
> +						"%s: Failed to write module to output.\n",
> +						argv[0]);
> +					result = -1;
> +					goto cleanup_get;
> +				}
> +
> +cleanup_get:
> +				if (out != NULL && out != stdout) {
> +					fclose(out);
> +					fd = -1;
> +				}
> +				if (fd >= 0) close(fd);
> +				free(data);
> +
> +				semanage_module_info_destroy(sh, modinfo);
> +				free(modinfo);
> +
> +				semanage_module_key_destroy(sh, modkey);
> +				free(modkey);
> +
> +				break;
> +			}
>  		default:{
>  				fprintf(stderr,
>  					"%s:  Unknown mode specified.\n",

-- 
James Carter <jwcart2@tycho.nsa.gov>
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 04/15] [src-policy] refpol intermediate language compiler (refpol_ilc)
  2010-01-26 22:08       ` [PATCH 04/15] [src-policy] refpol intermediate language compiler (refpol_ilc) Caleb Case
  2010-01-26 22:08         ` [PATCH 05/15] [src-policy] language.d and language.conf parser Caleb Case
@ 2010-01-28 21:03         ` James Carter
  2010-02-01 17:43           ` Caleb Case
  1 sibling, 1 reply; 34+ messages in thread
From: James Carter @ 2010-01-28 21:03 UTC (permalink / raw)
  To: Caleb Case; +Cc: selinux, csellers, kmacmillan, jbrindle, sds

On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote:
> In the interim, before the completion of the proposed CIL[1], the
> intermediate language will be a specialized version of refpol and the
> Reference Policy build environment.
> 
> [refpol_ilc CIL Compiler]
> 
> The repfol intermediate language compiler (refpol_ilc) builds a binary
> base module from refpol module.  Producing a binary base module allows
> the existing libsemanage framework to continue to operate essentially as
> it does today (load base module, apply database changes, create loadable
> policy).
> 
>    Usage: refpol_ilc [OPTIONS] MODULE MODULE ...
> 
>    Options:
>      --version             show program's version number and exit
>      -h, --help            show this help message and exit
>      -d FILE, --disabled=FILE
>                            indicates module is disabled
>      -f, --force           force overwriting existing files
>      -t DIR, --tmp=DIR     temporary build directory
>      -b DIR, --build-template=DIR
>                            build template directory (Default:
>                            /usr/share/selinux/refpol_ilc/build)
>      -o FILE, --output=FILE
>                            output file
>      -c BOOL, --cleanup=BOOL
>                            cleanup (remove) temporary directory (Default: True)
> 
> Note: The paths passed to the refpol_ilc need to be in the format of the
>       semanage store in /var/lib/selinux. The refpol_ilc extracts the
>       module name from the path. Future CIL will also likely extract the
>       priority of the module from the path.
> 
> Example:
> 
> The compiles the moduless installed in the 'test' store into a base.pp:
> 
> # refpol_ilc `find /var/lib/selinux/test/active/modules/400/ -iname cil` > base.pp
> 
> [Compilation]
> 
> Compilation proceeds as follows:
> 
>   1. Copy build environment to temporary location.
> 
>      Note: refpol_ilc anticipates the build environment being installed
>            to /usr/share/selinux/refpol_ilc/build by default.
> 
>   2. Install modules (see Special Modules and Normal Modules below).
> 
>   3. Create conf files.
> 
>   4. Set all modules to base or off as appropriate in modules.conf.
> 
>   5. Create base module (base.pp).
> 
> [Special Modules]
> 
> A number of modules are considered to be special and are installed into
> special locations in the build environment:
> 
>    [Module Name]         [Reference Policy File]
> 
>    _constraints           policy/constraints
>    _global_booleans       policy/global_booleans
>    _global_tunables       policy/global_tunables
>    _mcs                   policy/mcs
>    _mls                   policy/mls
>    _policy_capabilities   policy/policy_capabilities
>    _rolemap               policy/rolemap
>    _users                 policy/users
>    _access_vectors        policy/flask/access_vectors
>    _initial_sids          policy/flask/initial_sids
>    _security_classes      policy/flask/security_classes
>    _file_patterns         policy/support/file_patterns.spt
>    _ipc_patterns          policy/support/ipc_patterns.spt
>    _loadable_module       policy/support/loadable_module.spt
>    _misc_macros           policy/support/misc_macros.spt
>    _misc_patterns         policy/support/misc_patterns.spt
>    _mls_mcs_macros        policy/support/mls_mcs_macros.spt
>    _obj_perm_sets         policy/support/obj_perm_sets.spt
> 

In the policy store, mcs and mls modules exist along with _mcs and _mls
modules.  But _mcs calls itself "mcs" in the policy_module statement and
_mls calls itself "mls" in the policy_module statement.

mcs:
policy_module(mcs, 1.2.0)

_mcs:
policy_module(mcs, 2.20091117)

mls:
policy_module(mls, 1.8.0)

_mls:
policy_module(mls, 2.20091117)

Is there a reason for this?

> The build.conf file is handled with another special module _defines.
> This module provides some of the variables for the traditional
> build.conf with the remaining variables determined by the build
> environment as follows:
> 
>    OUTPUT_POLICY   =>   Copied from _defines.
>    TYPE            =>   Detect from the presence of the mls/mcs modules.
>                         mls > mcs > none: meaning that if there is an
>                         _mls module, then TYPE = mls, even if there is an
>                         mcs module present.
>    NAME            =>   Copied from _defines.
>    DISTRO          =>   Copied from _defines.
>    UNK_PERMS       =>   Copied from _defines.
>    DIRECT_INITRC   =>   Copied from _defines.
>    MONOLITHIC      =>   Fixed to 'n'.
>    UBAC            =>   Copied from _defines.
>    MLS_SENS        =>   Copied from _defines.
>    MLS_CATS        =>   Copied from _defines.
>    MCS_CATS        =>   Copied from _defines.
>    QUIET           =>   Copied from _defines.
> 
> No other special modules are permitted. All special modules are
> prepended with '_' to distinguish them from normal modules.
> 
> Note: The MLS/MCS/Standard setting of the policy is derived from the
>       presense of the _mls or _mcs modules. It is no longer necessary to
>       specify the policy type explicitly via the TYPE statement. This
>       also allows policy type to be switched simply by enabling/disabled
>       the _mls/_mcs modules.
> 
> [Normal Modules]
> 
> All normal (non-special) modules are copied to policy/modules/kernel/
> and unpacked into the Reference Policy module 3 file format.
> 
> [1] CIL RFC: http://marc.info/?l=selinux&m=124759244409438&w=2
> ---
>  Makefile                            |    2 +-
>  refpol_ilc/COPYING                  |  504 +++++++++++++++++++++++++++++++++++
>  refpol_ilc/Makefile                 |   24 ++
>  refpol_ilc/refpol_ilc.py            |   17 ++
>  refpol_ilc/refpol_ilc/refpol_ilc.py |  193 +++++++++++++
>  refpol_ilc/setup.py                 |   13 +
>  6 files changed, 752 insertions(+), 1 deletions(-)
>  create mode 100644 refpol_ilc/COPYING
>  create mode 100644 refpol_ilc/Makefile
>  create mode 100755 refpol_ilc/refpol_ilc.py
>  create mode 100644 refpol_ilc/refpol_ilc/__init__.py
>  create mode 100644 refpol_ilc/refpol_ilc/refpol_ilc.py
>  create mode 100755 refpol_ilc/setup.py
> 
> diff --git a/Makefile b/Makefile
> index be2a4ec..afb4843 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1,4 +1,4 @@
> -SUBDIRS=libsepol libselinux libsemanage sepolgen checkpolicy policycoreutils refpol corenet # policy
> +SUBDIRS=libsepol libselinux libsemanage sepolgen checkpolicy policycoreutils refpol corenet refpol_ilc # policy
>  PYSUBDIRS=libselinux libsemanage
>  
>  ifeq ($(DEBUG),1)
> diff --git a/refpol_ilc/COPYING b/refpol_ilc/COPYING
> new file mode 100644
> index 0000000..8add30a
> --- /dev/null
> +++ b/refpol_ilc/COPYING
> @@ -0,0 +1,504 @@
> +		  GNU LESSER GENERAL PUBLIC LICENSE
> +		       Version 2.1, February 1999
> +
> + Copyright (C) 1991, 1999 Free Software Foundation, Inc.
> +     51 Franklin St, 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.
> +
> +[This is the first released version of the Lesser GPL.  It also counts
> + as the successor of the GNU Library Public License, version 2, hence
> + the version number 2.1.]
> +
> +			    Preamble
> +
> +  The licenses for most software are designed to take away your
> +freedom to share and change it.  By contrast, the GNU General Public
> +Licenses are intended to guarantee your freedom to share and change
> +free software--to make sure the software is free for all its users.
> +
> +  This license, the Lesser General Public License, applies to some
> +specially designated software packages--typically libraries--of the
> +Free Software Foundation and other authors who decide to use it.  You
> +can use it too, but we suggest you first think carefully about whether
> +this license or the ordinary General Public License is the better
> +strategy to use in any particular case, based on the explanations below.
> +
> +  When we speak of free software, we are referring to freedom of use,
> +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 and use pieces of
> +it in new free programs; and that you are informed that you can do
> +these things.
> +
> +  To protect your rights, we need to make restrictions that forbid
> +distributors to deny you these rights or to ask you to surrender these
> +rights.  These restrictions translate to certain responsibilities for
> +you if you distribute copies of the library or if you modify it.
> +
> +  For example, if you distribute copies of the library, whether gratis
> +or for a fee, you must give the recipients all the rights that we gave
> +you.  You must make sure that they, too, receive or can get the source
> +code.  If you link other code with the library, you must provide
> +complete object files to the recipients, so that they can relink them
> +with the library after making changes to the library and recompiling
> +it.  And you must show them these terms so they know their rights.
> +
> +  We protect your rights with a two-step method: (1) we copyright the
> +library, and (2) we offer you this license, which gives you legal
> +permission to copy, distribute and/or modify the library.
> +
> +  To protect each distributor, we want to make it very clear that
> +there is no warranty for the free library.  Also, if the library is
> +modified by someone else and passed on, the recipients should know
> +that what they have is not the original version, so that the original
> +author's reputation will not be affected by problems that might be
> +introduced by others.
> +\f
> +  Finally, software patents pose a constant threat to the existence of
> +any free program.  We wish to make sure that a company cannot
> +effectively restrict the users of a free program by obtaining a
> +restrictive license from a patent holder.  Therefore, we insist that
> +any patent license obtained for a version of the library must be
> +consistent with the full freedom of use specified in this license.
> +
> +  Most GNU software, including some libraries, is covered by the
> +ordinary GNU General Public License.  This license, the GNU Lesser
> +General Public License, applies to certain designated libraries, and
> +is quite different from the ordinary General Public License.  We use
> +this license for certain libraries in order to permit linking those
> +libraries into non-free programs.
> +
> +  When a program is linked with a library, whether statically or using
> +a shared library, the combination of the two is legally speaking a
> +combined work, a derivative of the original library.  The ordinary
> +General Public License therefore permits such linking only if the
> +entire combination fits its criteria of freedom.  The Lesser General
> +Public License permits more lax criteria for linking other code with
> +the library.
> +
> +  We call this license the "Lesser" General Public License because it
> +does Less to protect the user's freedom than the ordinary General
> +Public License.  It also provides other free software developers Less
> +of an advantage over competing non-free programs.  These disadvantages
> +are the reason we use the ordinary General Public License for many
> +libraries.  However, the Lesser license provides advantages in certain
> +special circumstances.
> +
> +  For example, on rare occasions, there may be a special need to
> +encourage the widest possible use of a certain library, so that it becomes
> +a de-facto standard.  To achieve this, non-free programs must be
> +allowed to use the library.  A more frequent case is that a free
> +library does the same job as widely used non-free libraries.  In this
> +case, there is little to gain by limiting the free library to free
> +software only, so we use the Lesser General Public License.
> +
> +  In other cases, permission to use a particular library in non-free
> +programs enables a greater number of people to use a large body of
> +free software.  For example, permission to use the GNU C Library in
> +non-free programs enables many more people to use the whole GNU
> +operating system, as well as its variant, the GNU/Linux operating
> +system.
> +
> +  Although the Lesser General Public License is Less protective of the
> +users' freedom, it does ensure that the user of a program that is
> +linked with the Library has the freedom and the wherewithal to run
> +that program using a modified version of the Library.
> +
> +  The precise terms and conditions for copying, distribution and
> +modification follow.  Pay close attention to the difference between a
> +"work based on the library" and a "work that uses the library".  The
> +former contains code derived from the library, whereas the latter must
> +be combined with the library in order to run.
> +\f
> +		  GNU LESSER GENERAL PUBLIC LICENSE
> +   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
> +
> +  0. This License Agreement applies to any software library or other
> +program which contains a notice placed by the copyright holder or
> +other authorized party saying it may be distributed under the terms of
> +this Lesser General Public License (also called "this License").
> +Each licensee is addressed as "you".
> +
> +  A "library" means a collection of software functions and/or data
> +prepared so as to be conveniently linked with application programs
> +(which use some of those functions and data) to form executables.
> +
> +  The "Library", below, refers to any such software library or work
> +which has been distributed under these terms.  A "work based on the
> +Library" means either the Library or any derivative work under
> +copyright law: that is to say, a work containing the Library or a
> +portion of it, either verbatim or with modifications and/or translated
> +straightforwardly into another language.  (Hereinafter, translation is
> +included without limitation in the term "modification".)
> +
> +  "Source code" for a work means the preferred form of the work for
> +making modifications to it.  For a library, 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 library.
> +
> +  Activities other than copying, distribution and modification are not
> +covered by this License; they are outside its scope.  The act of
> +running a program using the Library is not restricted, and output from
> +such a program is covered only if its contents constitute a work based
> +on the Library (independent of the use of the Library in a tool for
> +writing it).  Whether that is true depends on what the Library does
> +and what the program that uses the Library does.
> +  
> +  1. You may copy and distribute verbatim copies of the Library's
> +complete 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 distribute a copy of this License along with the
> +Library.
> +
> +  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.
> +\f
> +  2. You may modify your copy or copies of the Library or any portion
> +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
> +
> +    b) You must cause the files modified to carry prominent notices
> +    stating that you changed the files and the date of any change.
> +
> +    c) You must cause the whole of the work to be licensed at no
> +    charge to all third parties under the terms of this License.
> +
> +    d) If a facility in the modified Library refers to a function or a
> +    table of data to be supplied by an application program that uses
> +    the facility, other than as an argument passed when the facility
> +    is invoked, then you must make a good faith effort to ensure that,
> +    in the event an application does not supply such function or
> +    table, the facility still operates, and performs whatever part of
> +    its purpose remains meaningful.
> +
> +    (For example, a function in a library to compute square roots has
> +    a purpose that is entirely well-defined independent of the
> +    application.  Therefore, Subsection 2d requires that any
> +    application-supplied function or table used by this function must
> +    be optional: if the application does not supply it, the square
> +    root function must still compute square roots.)
> +
> +These requirements apply to the modified work as a whole.  If
> +identifiable sections of that work are not derived from the Library,
> +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 Library, 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 Library.
> +
> +In addition, mere aggregation of another work not based on the Library
> +with the Library (or with a work based on the Library) on a volume of
> +a storage or distribution medium does not bring the other work under
> +the scope of this License.
> +
> +  3. You may opt to apply the terms of the ordinary GNU General Public
> +License instead of this License to a given copy of the Library.  To do
> +this, you must alter all the notices that refer to this License, so
> +that they refer to the ordinary GNU General Public License, version 2,
> +instead of to this License.  (If a newer version than version 2 of the
> +ordinary GNU General Public License has appeared, then you can specify
> +that version instead if you wish.)  Do not make any other change in
> +these notices.
> +\f
> +  Once this change is made in a given copy, it is irreversible for
> +that copy, so the ordinary GNU General Public License applies to all
> +subsequent copies and derivative works made from that copy.
> +
> +  This option is useful when you wish to copy part of the code of
> +the Library into a program that is not a library.
> +
> +  4. You may copy and distribute the Library (or a portion or
> +derivative of it, under Section 2) in object code or executable form
> +under the terms of Sections 1 and 2 above provided that you 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.
> +
> +  If distribution of 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 satisfies the requirement to
> +distribute the source code, even though third parties are not
> +compelled to copy the source along with the object code.
> +
> +  5. A program that contains no derivative of any portion of the
> +Library, but is designed to work with the Library by being compiled or
> +linked with it, is called a "work that uses the Library".  Such a
> +work, in isolation, is not a derivative work of the Library, and
> +therefore falls outside the scope of this License.
> +
> +  However, linking a "work that uses the Library" with the Library
> +creates an executable that is a derivative of the Library (because it
> +contains portions of the Library), rather than a "work that uses the
> +library".  The executable is therefore covered by this License.
> +Section 6 states terms for distribution of such executables.
> +
> +  When a "work that uses the Library" uses material from a header file
> +that is part of the Library, the object code for the work may be a
> +derivative work of the Library even though the source code is not.
> +Whether this is true is especially significant if the work can be
> +linked without the Library, or if the work is itself a library.  The
> +threshold for this to be true is not precisely defined by law.
> +
> +  If such an object file uses only numerical parameters, data
> +structure layouts and accessors, and small macros and small inline
> +functions (ten lines or less in length), then the use of the object
> +file is unrestricted, regardless of whether it is legally a derivative
> +work.  (Executables containing this object code plus portions of the
> +Library will still fall under Section 6.)
> +
> +  Otherwise, if the work is a derivative of the Library, you may
> +distribute the object code for the work under the terms of Section 6.
> +Any executables containing that work also fall under Section 6,
> +whether or not they are linked directly with the Library itself.
> +\f
> +  6. As an exception to the Sections above, you may also combine or
> +link a "work that uses the Library" with the Library to produce a
> +work containing portions of the Library, and distribute that work
> +under terms of your choice, provided that the terms permit
> +modification of the work for the customer's own use and reverse
> +engineering for debugging such modifications.
> +
> +  You must give prominent notice with each copy of the work that the
> +Library is used in it and that the Library and its use are covered by
> +this License.  You must supply a copy of this License.  If the work
> +during execution displays copyright notices, you must include the
> +copyright notice for the Library among them, as well as a reference
> +directing the user to the copy of this License.  Also, you must do one
> +of these things:
> +
> +    a) Accompany the work with the complete corresponding
> +    machine-readable source code for the Library including whatever
> +    changes were used in the work (which must be distributed under
> +    Sections 1 and 2 above); and, if the work is an executable linked
> +    with the Library, with the complete machine-readable "work that
> +    uses the Library", as object code and/or source code, so that the
> +    user can modify the Library and then relink to produce a modified
> +    executable containing the modified Library.  (It is understood
> +    that the user who changes the contents of definitions files in the
> +    Library will not necessarily be able to recompile the application
> +    to use the modified definitions.)
> +
> +    b) Use a suitable shared library mechanism for linking with the
> +    Library.  A suitable mechanism is one that (1) uses at run time a
> +    copy of the library already present on the user's computer system,
> +    rather than copying library functions into the executable, and (2)
> +    will operate properly with a modified version of the library, if
> +    the user installs one, as long as the modified version is
> +    interface-compatible with the version that the work was made with.
> +
> +    c) Accompany the work with a written offer, valid for at
> +    least three years, to give the same user the materials
> +    specified in Subsection 6a, above, for a charge no more
> +    than the cost of performing this distribution.
> +
> +    d) If distribution of the work is made by offering access to copy
> +    from a designated place, offer equivalent access to copy the above
> +    specified materials from the same place.
> +
> +    e) Verify that the user has already received a copy of these
> +    materials or that you have already sent this user a copy.
> +
> +  For an executable, the required form of the "work that uses the
> +Library" must include any data and utility programs needed for
> +reproducing the executable from it.  However, as a special exception,
> +the materials to be 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.
> +
> +  It may happen that this requirement contradicts the license
> +restrictions of other proprietary libraries that do not normally
> +accompany the operating system.  Such a contradiction means you cannot
> +use both them and the Library together in an executable that you
> +distribute.
> +\f
> +  7. You may place library facilities that are a work based on the
> +Library side-by-side in a single library together with other library
> +facilities not covered by this License, and distribute such a combined
> +library, provided that the separate distribution of the work based on
> +the Library and of the other library facilities is otherwise
> +permitted, and provided that you do these two things:
> +
> +    a) Accompany the combined library with a copy of the same work
> +    based on the Library, uncombined with any other library
> +    facilities.  This must be distributed under the terms of the
> +    Sections above.
> +
> +    b) Give prominent notice with the combined library of the fact
> +    that part of it is a work based on the Library, and explaining
> +    where to find the accompanying uncombined form of the same work.
> +
> +  8. You may not copy, modify, sublicense, link with, or distribute
> +the Library except as expressly provided under this License.  Any
> +attempt otherwise to copy, modify, sublicense, link with, or
> +distribute the Library 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.
> +
> +  9. 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 Library or its derivative works.  These actions are
> +prohibited by law if you do not accept this License.  Therefore, by
> +modifying or distributing the Library (or any work based on the
> +Library), you indicate your acceptance of this License to do so, and
> +all its terms and conditions for copying, distributing or modifying
> +the Library or works based on it.
> +
> +  10. Each time you redistribute the Library (or any work based on the
> +Library), the recipient automatically receives a license from the
> +original licensor to copy, distribute, link with or modify the Library
> +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 with
> +this License.
> +\f
> +  11. 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 Library at all.  For example, if a patent
> +license would not permit royalty-free redistribution of the Library 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 Library.
> +
> +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.
> +
> +  12. If the distribution and/or use of the Library is restricted in
> +certain countries either by patents or by copyrighted interfaces, the
> +original copyright holder who places the Library 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.
> +
> +  13. The Free Software Foundation may publish revised and/or new
> +versions of the Lesser 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 Library
> +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 Library does not specify a
> +license version number, you may choose any version ever published by
> +the Free Software Foundation.
> +\f
> +  14. If you wish to incorporate parts of the Library into other free
> +programs whose distribution conditions are incompatible with these,
> +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
> +
> +  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
> +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
> +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
> +OTHER PARTIES PROVIDE THE LIBRARY "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
> +LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
> +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
> +
> +  16. 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 LIBRARY 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
> +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
> +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
> +DAMAGES.
> +
> +		     END OF TERMS AND CONDITIONS
> +\f
> +           How to Apply These Terms to Your New Libraries
> +
> +  If you develop a new library, and you want it to be of the greatest
> +possible use to the public, we recommend making it free software that
> +everyone can redistribute and change.  You can do so by permitting
> +redistribution under these terms (or, alternatively, under the terms of the
> +ordinary General Public License).
> +
> +  To apply these terms, attach the following notices to the library.  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.
> +
> +    <one line to give the library's name and a brief idea of what it does.>
> +    Copyright (C) <year>  <name of author>
> +
> +    This library is free software; you can redistribute it and/or
> +    modify it under the terms of the GNU Lesser General Public
> +    License as published by the Free Software Foundation; either
> +    version 2.1 of the License, or (at your option) any later version.
> +
> +    This library 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
> +    Lesser General Public License for more details.
> +
> +    You should have received a copy of the GNU Lesser General Public
> +    License along with this library; if not, write to the Free Software
> +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
> +
> +Also add information on how to contact you by electronic and paper mail.
> +
> +You should also get your employer (if you work as a programmer) or your
> +school, if any, to sign a "copyright disclaimer" for the library, if
> +necessary.  Here is a sample; alter the names:
> +
> +  Yoyodyne, Inc., hereby disclaims all copyright interest in the
> +  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
> +
> +  <signature of Ty Coon>, 1 April 1990
> +  Ty Coon, President of Vice
> +
> +That's all there is to it!
> +
> +
> diff --git a/refpol_ilc/Makefile b/refpol_ilc/Makefile
> new file mode 100644
> index 0000000..f6cdb14
> --- /dev/null
> +++ b/refpol_ilc/Makefile
> @@ -0,0 +1,24 @@
> +PREFIX ?= $(DESTDIR)/usr
> +BINDIR ?= $(PREFIX)/bin
> +
> +PYTHON ?= python
> +
> +ifneq ($(origin DESTDIR), undefined)
> +	PYDESTDIR ?= --root=$(DESTDIR)
> +endif
> +
> +TARGET = refpol_ilc.py
> +
> +all:
> +	$(PYTHON) setup.py build
> +
> +install:
> +	$(PYTHON) setup.py install $(PYDESTDIR)
> +	-mkdir -p $(BINDIR)
> +	install -m 755 $(TARGET) $(BINDIR)/$(TARGET:.py=)
> +
> +clean distclean:
> +	$(PYTHON) setup.py clean
> +	rm -fr build
> +	rm -f refpol_ilc/*.pyc
> +
> diff --git a/refpol_ilc/refpol_ilc.py b/refpol_ilc/refpol_ilc.py
> new file mode 100755
> index 0000000..31021b4
> --- /dev/null
> +++ b/refpol_ilc/refpol_ilc.py
> @@ -0,0 +1,17 @@
> +#!/usr/bin/python
> +
> +# Authors:	Caleb Case <ccase@tresys.com>
> +#
> +# Copyright (C) 2009-2010 Tresys Technology, LLC
> +#      This program is free software; you can redistribute it and/or modify
> +#      it under the terms of the Lesser GNU General Public License as 
> +#      published by the Free Software Foundation, version 2.
> +
> +import refpol_ilc.refpol_ilc
> +import sys
> +
> +try:
> +	refpol_ilc.refpol_ilc.main()
> +except Exception as e:
> +	sys.stderr.write(sys.argv[0] + ": Error: " + str(e) + "\n")
> +	sys.exit(1)
> diff --git a/refpol_ilc/refpol_ilc/__init__.py b/refpol_ilc/refpol_ilc/__init__.py
> new file mode 100644
> index 0000000..e69de29
> diff --git a/refpol_ilc/refpol_ilc/refpol_ilc.py b/refpol_ilc/refpol_ilc/refpol_ilc.py
> new file mode 100644
> index 0000000..7e5430e
> --- /dev/null
> +++ b/refpol_ilc/refpol_ilc/refpol_ilc.py
> @@ -0,0 +1,193 @@
> +#!/usr/bin/python
> +
> +# Authors:	Caleb Case <ccase@tresys.com>
> +#
> +# Copyright (C) 2009-2010 Tresys Technology, LLC
> +#      This program is free software; you can redistribute it and/or modify
> +#      it under the terms of the Lesser GNU General Public License as 
> +#      published by the Free Software Foundation, version 2.
> +
> +from optparse import OptionParser, OptionGroup
> +import os
> +import os.path
> +import tempfile
> +from refpol import refpol
> +from refpol import refpolicy2refpol
> +import shutil
> +import subprocess
> +import sys
> +
> +build_directory = "/usr/share/selinux/refpol_ilc/build"
> +
> +# setup PATH (for gcc) if missing
> +if not "PATH" in os.environ:
> +	os.environ["PATH"] = "/bin:/usr/bin"
> +
> +def to_bool(str):
> +	return 	{
> +			"true"	: True,
> +			"t"	: True,
> +			"1"	: True,
> +			"false"	: False,
> +			"f"	: False,
> +			"0"	: False,
> +		}[str.lower()]
> +
> +usage = "%prog [OPTIONS] MODULE MODULE ..."
> +version = "%prog 1.0"
> +
> +def main():
> +	def disabled(option, opt_str, value, parser, *args, **kwargs):
> +		parser.values.disabled.append(value)
> +
> +	# create cmdline parser
> +	parser = OptionParser(usage = usage, version = version)
> +	parser.add_option("-d", "--disabled", action = "callback", callback = disabled, type = "string", default = [], dest = "disabled", help = "indicates module is disabled", metavar = "FILE")
> +	parser.add_option("-f", "--force", action = "store_true", default = False, dest = "force", help = "force overwriting existing files")
> +	parser.add_option("-t", "--tmp", action = "store", default = None, dest = "tmp", help = "temporary build directory", metavar = "DIR")
> +	parser.add_option("-b", "--build-template", action = "store", default = build_directory, dest = "build_template", help = "build template directory (Default: %s)" % build_directory, metavar = "DIR")
> +	parser.add_option("-o", "--output", action = "store", default = None, dest = "output", help = "output file", metavar = "FILE")
> +	parser.add_option("-c", "--cleanup", action = "store", default = "True", dest = "cleanup", help = "cleanup (remove) temporary directory (Default: True)", metavar = "BOOL")
> +
> +	# parse cmdline
> +	(options, args) = parser.parse_args()
> +	if len(args) <= 0:
> +		parser.error("Invalid number of arguments %d." % len(args))
> +
> +	# save the working directory
> +	saved_cwd = os.getcwd()
> +
> +	force = options.force
> +	refpol.force = options.force
> +	refpolicy2refpol.force = options.force
> +
> +	if options.output is None:
> +		options.output = sys.stdout
> +	else:
> +		refpol.file_exists(options.output)
> +		options.output = open(options.output, "w")
> +
> +	try:
> +		if not options.tmp:
> +			# create tmp build dir if one isn't provided
> +			options.tmp = tempfile.mkdtemp("-refpol_ilc")
> +		else:
> +			shutil.rmtree(options.tmp, ignore_errors = True)
> +			os.mkdir(options.tmp)
> +
> +		# copy build dir template
> +		build_root = options.tmp + "/build"
> +		shutil.copytree(options.build_template, build_root)
> +
> +		# set default policy TYPE
> +		type = "standard"
> +
> +		# copy modules into build dir
> +		special_names = dict(zip(["_" + os.path.basename(i).rsplit('.', 1)[0] for i in refpolicy2refpol.specials("")], refpolicy2refpol.specials(build_root)))
> +		disabled_names = [os.path.basename(os.path.dirname(i)) for i in options.disabled]
> +
> +		all_modules = []
> +		all_modules.extend(args)
> +		all_modules.extend(options.disabled)
> +		for path in all_modules:
> +			module_name = os.path.basename(os.path.dirname(path))
> +
> +			if module_name in special_names and not module_name in disabled_names:
> +				if module_name == "_mls":
> +					type = "mls"
> +				elif module_name == "_mcs" and type != "mls":
> +					type = "mcs"
> +
> +				# copy to special location
> +				with open(path, "r") as input:
> +					with open(special_names[module_name], "w") as output:
> +						for line in input:
> +							# remove policy_module statement
> +							if not line.strip().startswith("policy_module"):
> +								output.write(line)
> +			elif module_name == "_defines":
> +				shutil.copy(path, build_root + "/_defines.ref")
> +			else:
> +				# copy module to policy/kernel/
> +				dest_ref = build_root + "/policy/modules/kernel/" + module_name + ".ref"
> +				dest_name = build_root + "/policy/modules/kernel/" + module_name
> +				shutil.copy(path, dest_ref)
> +				
> +				refpol.ref_to_itf(dest_ref, dest_name + ".if", dest_name + ".te", dest_name + ".fc")
> +
> +		os.chdir(build_root)
> +
> +		# compose build.conf (build.conf.in from _defines.ref)
> +		with open("_defines.ref", "r") as input:
> +			with open("build.conf", "w") as output:
> +				# write out the type
> +				output.write("TYPE = %s\n\n" % type)
> +
> +				# write out monolithic
> +				output.write("MONOLITHIC = n\n\n")
> +
> +				for line in input:
> +					# remove policy_module statement
> +					if not line.strip().startswith("policy_module"):
> +						output.write(line)
> +
> +		# make conf
> +		p = subprocess.Popen("make conf", shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE, close_fds = True)
> +
> +		(stdout, stderr) = p.communicate()
> +		sys.stderr.write(stdout)
> +		sys.stderr.write(stderr)
> +
> +		if p.returncode != 0:
> +			raise Exception("Failed to run make conf (%d)." % p.returncode)
> +
> +		# sed modules.conf to base module if enabled
> +		sed_cmd = "sed -i '1,/^END/{ s/= module/= base/; "
> +		disabled_len = len(options.disabled)
> +		if disabled_len > 0:
> +			sed_cmd = sed_cmd + "s/\\("
> +			i = 0
> +			for d in options.disabled:
> +				i = i + 1
> +				sed_cmd = sed_cmd + os.path.basename(os.path.dirname(d))
> +				if i != disabled_len:
> +					sed_cmd = sed_cmd + "\\|"
> +			sed_cmd = sed_cmd + "\\) = base/\\1 = off/ "
> +		sed_cmd = sed_cmd + "}' policy/modules.conf"
> +
> +		p = subprocess.Popen(sed_cmd, shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE, close_fds = True)
> +
> +		(stdout, stderr) = p.communicate()
> +		sys.stderr.write(stdout)
> +		sys.stderr.write(stderr)
> +
> +		if p.returncode != 0:
> +			raise Exception("Failed to modify modules.conf (%d)." % p.returncode)
> +
> +		# make base module
> +		p = subprocess.Popen("make base.pp", shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE, close_fds = True)
> +
> +		(stdout, stderr) = p.communicate()
> +		sys.stderr.write(stdout)
> +		sys.stderr.write(stderr)
> +
> +		if p.returncode != 0:
> +			raise Exception("Failed to run make base.pp (%d)." % p.returncode)
> +
> +		# output base module
> +		options.output.write(open("base.pp", "r").read())
> +	finally:
> +		if to_bool(options.cleanup):
> +			shutil.rmtree(options.tmp)
> +
> +		options.output.close()
> +
> +		# return the saved directory
> +		os.chdir(saved_cwd)
> +
> +if __name__ == '__main__':
> +	try:
> +		main()
> +	except Exception as e:
> +		sys.stderr.write(sys.argv[0] + ": Error: " + str(e) + "\n")
> +		sys.exit(1)
> diff --git a/refpol_ilc/setup.py b/refpol_ilc/setup.py
> new file mode 100755
> index 0000000..31c3a14
> --- /dev/null
> +++ b/refpol_ilc/setup.py
> @@ -0,0 +1,13 @@
> +#!/usr/bin/python
> +
> +from distutils.core import setup
> +
> +setup(	name		= "refpol_ilc",
> +	version		= "0.1",
> +	description	= "Refpol Intermediate Language Compiler",
> +#	url		= "",
> +	author		= "Caleb Case",
> +	author_email	= "ccase@tresys.com",
> +	license		= "LGPL v2.1",
> +	packages	= ['refpol_ilc'],
> +	)

-- 
James Carter <jwcart2@tycho.nsa.gov>
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 08/15] [src-policy] libsemanage: remove binary interfaces
  2010-01-26 22:08               ` [PATCH 08/15] [src-policy] libsemanage: remove binary interfaces Caleb Case
  2010-01-26 22:08                 ` [PATCH 09/15] [src-policy] semodule: remove base module support Caleb Case
@ 2010-01-29 20:32                 ` James Carter
  1 sibling, 0 replies; 34+ messages in thread
From: James Carter @ 2010-01-29 20:32 UTC (permalink / raw)
  To: Caleb Case; +Cc: selinux, csellers, kmacmillan, jbrindle, sds

On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote:
> Supporting both binary policy packages and source modules is difficult
> and leads to problems that are unacceptable. For instance, the binary
> modules would lack relevant information for recompilation such as the
> interface definition (which would lead to unexpected behavior if a
> source module interface changes, but those changes don't appear in the
> binary modules).  Consequently, we completely removed support for binary
> modules, leaving only support for source modules. Also, because we are
> now creating the base module automatically from the source modules, the
> base module interfaces are removed as well.
> 
> This patch deprecates the following:
> 
>    semanage_module_install
>    semanage_module_upgrade
>    semanage_module_install_base
>    semanage_module_intall_base_file
> 
> and removes their direct_api implementations.
> 
> For the sake of rendering meaningful error messages, the callbacks for
> these functions have been initialized to NULL. This will result in an
> error message indicating that the function is not implemented for the
> given connection type. At a future time these functions would be removed
> entirely.
> 
> The file related functions are updated to expect source modules:
> 
>    semanage_module_install_file
>    semanage_module_upgrade_file
> ---
>  libsemanage/include/semanage/modules.h |   14 +-
>  libsemanage/src/direct_api.c           |  751 +++++++++++++-------------------
>  2 files changed, 302 insertions(+), 463 deletions(-)
> 
> diff --git a/libsemanage/include/semanage/modules.h b/libsemanage/include/semanage/modules.h
> index e169279..8a26e6c 100644
> --- a/libsemanage/include/semanage/modules.h
> +++ b/libsemanage/include/semanage/modules.h
> @@ -1,7 +1,7 @@
>  /* Authors: Joshua Brindle  <jbrindle@tresys.com>
>   *	    Jason Tang	    <jtang@tresys.com>
>   *
> - * Copyright (C) 2005 Tresys Technology, LLC
> + * Copyright (C) 2005,2010 Tresys Technology, LLC
>   *
>   *  This library is free software; you can redistribute it and/or
>   *  modify it under the terms of the GNU Lesser General Public
> @@ -29,17 +29,21 @@
>   */
>  
>  int semanage_module_install(semanage_handle_t *,
> -			    char *module_data, size_t data_len);
> +			    char *module_data, size_t data_len)
> +			    __attribute__ ((deprecated));
>  int semanage_module_install_file(semanage_handle_t *,
>  				 const char *module_name);
>  int semanage_module_upgrade(semanage_handle_t *,
> -			    char *module_data, size_t data_len);
> +			    char *module_data, size_t data_len)
> +			    __attribute__ ((deprecated));
>  int semanage_module_upgrade_file(semanage_handle_t *,
>  				 const char *module_name);
>  int semanage_module_install_base(semanage_handle_t *,
> -				 char *module_data, size_t data_len);
> +				 char *module_data, size_t data_len)
> +				 __attribute__ ((deprecated));
>  int semanage_module_install_base_file(semanage_handle_t *,
> -				      const char *module_name);
> +				      const char *module_name)
> +				      __attribute__ ((deprecated));

swig doesn't seem to like "__attribute__ ((deprecated))". If I comment
out the attribute part, it swigifies.

make[1]: Entering directory `/home/jwcart2/src/tresys/selinux/libsemanage'
make -C src swigify
make[2]: Entering directory `/home/jwcart2/src/tresys/selinux/libsemanage/src'
swig -Wall -python -o semanageswig_wrap.c -outdir ./ semanageswig_python.i
../include/semanage/modules.h:33: Error: Syntax error in input(1).
make[2]: *** [swigify] Error 1
make[2]: Leaving directory `/home/jwcart2/src/tresys/selinux/libsemanage/src'
make[1]: *** [swigify] Error 2
make[1]: Leaving directory `/home/jwcart2/src/tresys/selinux/libsemanage'
make: *** [swigify] Error 1


>  int semanage_module_remove(semanage_handle_t *, char *module_name);
>  
>  /* semanage_module_info is for getting information on installed
> diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
> index 0623497..6f7cf63 100644
> --- a/libsemanage/src/direct_api.c
> +++ b/libsemanage/src/direct_api.c
> @@ -58,15 +58,8 @@ static void semanage_direct_destroy(semanage_handle_t * sh);
>  static int semanage_direct_disconnect(semanage_handle_t * sh);
>  static int semanage_direct_begintrans(semanage_handle_t * sh);
>  static int semanage_direct_commit(semanage_handle_t * sh);
> -static int semanage_direct_install(semanage_handle_t * sh, char *data,
> -				   size_t data_len);
>  static int semanage_direct_install_file(semanage_handle_t * sh, const char *module_name);
> -static int semanage_direct_upgrade(semanage_handle_t * sh, char *data,
> -				   size_t data_len);
>  static int semanage_direct_upgrade_file(semanage_handle_t * sh, const char *module_name);
> -static int semanage_direct_install_base(semanage_handle_t * sh, char *base_data,
> -					size_t data_len);
> -static int semanage_direct_install_base_file(semanage_handle_t * sh, const char *module_name);
>  static int semanage_direct_remove(semanage_handle_t * sh, char *module_name);
>  static int semanage_direct_list(semanage_handle_t * sh,
>  				semanage_module_info_t ** modinfo,
> @@ -105,12 +98,12 @@ static struct semanage_policy_table direct_funcs = {
>  	.disconnect = semanage_direct_disconnect,
>  	.begin_trans = semanage_direct_begintrans,
>  	.commit = semanage_direct_commit,
> -	.install = semanage_direct_install,
>  	.install_file = semanage_direct_install_file,
> -	.upgrade = semanage_direct_upgrade,
>  	.upgrade_file = semanage_direct_upgrade_file,
> -	.install_base = semanage_direct_install_base,
> -	.install_base_file = semanage_direct_install_base_file,
> +	.install = NULL,
> +	.upgrade = NULL,
> +	.install_base = NULL,
> +	.install_base_file = NULL,
>  	.remove = semanage_direct_remove,
>  	.list = semanage_direct_list,
>  	.get_enabled = semanage_direct_get_enabled,
> @@ -373,87 +366,6 @@ static int semanage_direct_begintrans(semanage_handle_t * sh)
>  
>  /********************* utility functions *********************/
>  
> -/* Takes a module stored in 'module_data' and parses its headers.
> - * Sets reference variables 'module_name' to module's name, and
> - * 'version' to module's version.  The caller is responsible for
> - * free()ing 'module_name', and 'version'; they will be
> - * set to NULL upon entering this function.  Returns 0 on success, -1
> - * if out of memory, or -2 if data did not represent a module.
> - */
> -static int parse_module_headers(semanage_handle_t * sh, char *module_data,
> -				size_t data_len, char **module_name,
> -				char **version)
> -{
> -	struct sepol_policy_file *pf;
> -	int file_type;
> -	*module_name = *version = NULL;
> -
> -	if (sepol_policy_file_create(&pf)) {
> -		ERR(sh, "Out of memory!");
> -		return -1;
> -	}
> -	sepol_policy_file_set_mem(pf, module_data, data_len);
> -	sepol_policy_file_set_handle(pf, sh->sepolh);
> -	if (module_data == NULL ||
> -	    data_len == 0 ||
> -	    sepol_module_package_info(pf, &file_type, module_name,
> -				      version) == -1) {
> -		sepol_policy_file_free(pf);
> -		ERR(sh, "Could not parse module data.");
> -		return -2;
> -	}
> -	sepol_policy_file_free(pf);
> -	if (file_type != SEPOL_POLICY_MOD) {
> -		if (file_type == SEPOL_POLICY_BASE)
> -			ERR(sh,
> -			    "Received a base module, expected a non-base module.");
> -		else
> -			ERR(sh, "Data did not represent a module.");
> -		return -2;
> -	}
> -
> -	return 0;
> -}
> -
> -/* Takes a base module stored in 'module_data' and parse its headers.
> - * Returns 0 on success, -1 if out of memory, or -2 if data did not
> - * represent a module.
> - */
> -static int parse_base_headers(semanage_handle_t * sh,
> -			      char *module_data, size_t data_len)
> -{
> -	struct sepol_policy_file *pf;
> -	char *module_name = NULL, *version = NULL;
> -	int file_type;
> -
> -	if (sepol_policy_file_create(&pf)) {
> -		ERR(sh, "Out of memory!");
> -		return -1;
> -	}
> -	sepol_policy_file_set_mem(pf, module_data, data_len);
> -	sepol_policy_file_set_handle(pf, sh->sepolh);
> -	if (module_data == NULL ||
> -	    data_len == 0 ||
> -	    sepol_module_package_info(pf, &file_type,
> -				      &module_name, &version) == -1) {
> -		sepol_policy_file_free(pf);
> -		ERR(sh, "Could not parse base module data.");
> -		return -2;
> -	}
> -	sepol_policy_file_free(pf);
> -	free(module_name);
> -	free(version);
> -	if (file_type != SEPOL_POLICY_BASE) {
> -		if (file_type == SEPOL_POLICY_MOD)
> -			ERR(sh,
> -			    "Received a non-base module, expected a base module.");
> -		else
> -			ERR(sh, "Data did not represent a module.");
> -		return -2;
> -	}
> -	return 0;
> -}
> -
>  #include <stdlib.h>
>  #include <bzlib.h>
>  #include <string.h>
> @@ -564,41 +476,6 @@ ssize_t bunzip(semanage_handle_t *sh, FILE *f, char **data)
>  	return  total;
>  }
>  
> -/* mmap() a file to '*data',
> - *  If the file is bzip compressed map_file will uncompress 
> - * the file into '*data'.
> - * Returns the total number of bytes in memory .
> - * Returns -1 if file could not be opened or mapped. */
> -static ssize_t map_file(semanage_handle_t *sh, int fd, char **data,
> -			int *compressed)
> -{
> -	ssize_t size = -1;
> -	char *uncompress;
> -	if ((size = bunzip(sh, fdopen(fd, "r"), &uncompress)) > 0) {
> -		*data = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
> -		if (*data == MAP_FAILED) {
> -			free(uncompress);
> -			return -1;
> -		} else {
> -			memcpy(*data, uncompress, size);
> -		}
> -		free(uncompress);
> -		*compressed = 1;
> -	} else {
> -		struct stat sb;
> -		if (fstat(fd, &sb) == -1 ||
> -		    (*data = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) ==
> -		    MAP_FAILED) {
> -			size = -1;
> -		} else {
> -			size = sb.st_size;
> -		}
> -		*compressed = 0;
> -	} 
> -
> -	return size;
> -}
> -
>  /* Writes a block of data to a file.  Returns 0 on success, -1 on
>   * error. */
>  static int write_file(semanage_handle_t * sh,
> @@ -706,6 +583,169 @@ static int semanage_direct_update_seuser(semanage_handle_t * sh, sepol_module_pa
>  	return retval;
>  }
>  
> +/* Reads the source module pointed to by @path into a memory buffer
> + * @data of length @data_len. @modinfo is constructed with gleaned from
> + * the module path and defaults as follows:
> + *
> + * priority	default from handle
> + * name		basename(path) sans extension
> + * version	empty string (gets overridden by hll compiler)
> + * lang_ext	basename(path) sans name and '.'
> + * enabled	default of -1 (don't change status)
> + * 
> + * On call @modinfo and @data will be set to NULL. @data_len will be set
> + * to 0.
> + *
> + * Caller should destroy and free @modinfo and free @data.
> + *
> + * Returns:
> + *
> + * 	 0	success
> + * 	-1	failure, out of memory
> + * 	-2	failure, invalid @path
> + */
> +static int semanage_path_to_info(semanage_handle_t *sh,
> +				 const char *path,
> +				 semanage_module_info_t **modinfo,
> +				 char **data,
> +				 size_t *data_len)
> +{
> +	assert(sh);
> +	assert(path);
> +	assert(modinfo);
> +	assert(data);
> +	assert(data_len);
> +
> +	int status = 0;
> +	int ret = 0;
> +
> +	int fd = -1;
> +	char *path_tmp = NULL;
> +	char *name = NULL;
> +	int i;
> +	char *ext = NULL;
> +
> +	*modinfo = NULL;
> +
> +	/* Open the module. */
> +	fd = open(path, O_RDONLY);
> +	if (fd < 0) {
> +		ERR(sh, "Failed to open file %s.", path);
> +		status = -2;
> +		goto cleanup;
> +	}
> +
> +	/* Convert to buffer. */
> +	ret = semanage_fd_to_data(sh, fd, data, data_len);
> +	if (ret != 0) {
> +		status = ret;
> +		goto cleanup;
> +	}
> +
> +	/* Get the name and ext from the path.
> +	 * name will be the first part of the string.
> +	 * ext will be the last part.
> +	 * Note that neither should be free'd.
> +	 * strduping here since basename can modify.
> +	 */
> +	path_tmp = strdup(path);
> +	if (path_tmp == NULL) {
> +		status = -1;
> +		goto cleanup;
> +	}
> +
> +	name = basename(path_tmp);
> +	for (i = strlen(name) - 1; i >= 1; i--) {
> +		if (name[i] == '.') {
> +			name[i] = '\0';
> +			ext = &name[i] + 1;
> +			break;
> +		}
> +	}
> +
> +	/* Failed to find an ext or name begins with '.'. */
> +	if (i == 0) {
> +		status = -2;
> +		goto cleanup;
> +	}
> +
> +	/* Create and initialize a modinfo. */
> +	ret = semanage_module_info_create(sh, modinfo);
> +	if (ret != 0) {
> +		status = -1;
> +		goto cleanup;
> +	}
> +
> +	ret = semanage_module_info_set_priority(
> +			sh,
> +			*modinfo,
> +			sh->priority);
> +	if (ret != 0) {
> +		status = -1;
> +		goto cleanup;
> +	}
> +
> +	ret = semanage_module_info_set_name(
> +			sh,
> +			*modinfo,
> +			name);
> +	if (ret != 0) {
> +		status = -1;
> +		goto cleanup;
> +	}
> +
> +	/* Initialize version to 0.
> +	 * The module version will changed later by the hll compiler.
> +	 */
> +	ret = semanage_module_info_set_version(
> +			sh,
> +			*modinfo,
> +			"0");
> +	if (ret != 0) {
> +		status = -1;
> +		goto cleanup;
> +	}
> +
> +	ret = semanage_module_info_set_lang_ext(
> +			sh,
> +			*modinfo,
> +			ext);
> +	if (ret != 0) {
> +		status = -1;
> +		goto cleanup;
> +	}
> +
> +	/* Set enabled to the default -1 value. This means that
> +	 * installing the module will not modify the enabled/disabled
> +	 * status.
> +	 */
> +	ret = semanage_module_info_set_enabled(
> +			sh,
> +			*modinfo,
> +			-1);
> +	if (ret != 0) {
> +		status = -1;
> +		goto cleanup;
> +	}
> +
> +cleanup:
> +	if (status != 0) {
> +		semanage_module_info_destroy(sh, *modinfo);
> +		free(*modinfo);
> +		*modinfo = NULL;
> +
> +		free(*data);
> +		*data = NULL;
> +		*data_len = 0;
> +	}
> +
> +	free(path_tmp);
> +
> +	close(fd);
> +
> +	return status;
> +}
> +
>  /********************* direct API functions ********************/
>  
>  /* Commits all changes in sandbox to the actual kernel policy.
> @@ -1055,72 +1095,6 @@ static int semanage_direct_commit(semanage_handle_t * sh)
>  	return retval;
>  }
>  
> -/* Writes a module to the sandbox's module directory, overwriting any
> - * previous module stored within.  Note that module data are not
> - * free()d by this function; caller is responsible for deallocating it
> - * if necessary.  Returns 0 on success, -1 if out of memory, -2 if the
> - * data does not represent a valid module file, -3 if error while
> - * writing file. */
> -static int semanage_direct_install(semanage_handle_t * sh,
> -				   char *data, size_t data_len)
> -{
> -	int status = 0;
> -	int ret = 0;
> -
> -	char *module_name = NULL, *version = NULL;
> -	if ((status = parse_module_headers(sh, data, data_len,
> -					   &module_name, &version)) != 0) {
> -		goto cleanup;
> -	}
> -
> -	semanage_module_info_t modinfo;
> -	ret = semanage_module_info_init(sh, &modinfo);
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	ret = semanage_module_info_set_priority(sh, &modinfo, sh->priority);
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	ret = semanage_module_info_set_name(sh, &modinfo, module_name);
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	ret = semanage_module_info_set_version(sh, &modinfo, version);
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	ret = semanage_module_info_set_lang_ext(sh, &modinfo, "pp");
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	ret = semanage_module_info_set_enabled(sh, &modinfo, -1);
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	status = semanage_direct_install_info(sh, &modinfo, data, data_len);
> -
> -cleanup:
> -	free(version);
> -	free(module_name);
> -
> -	semanage_module_info_destroy(sh, &modinfo);
> -
> -	return status;
> -}
> -
>  /* Attempts to link a module to the sandbox's module directory, unlinking any
>   * previous module stored within.  Returns 0 on success, -1 if out of memory, -2 if the
>   * data does not represent a valid module file, -3 if error while
> @@ -1129,97 +1103,31 @@ cleanup:
>  static int semanage_direct_install_file(semanage_handle_t * sh,
>  					const char *install_filename)
>  {
> +	int status = 0;
>  
> -	int retval = -1;
> +	semanage_module_info_t *modinfo = NULL;
>  	char *data = NULL;
> -	ssize_t data_len = 0;
> -	int compressed = 0;
> -	int in_fd = -1;
> -
> -	if ((in_fd = open(install_filename, O_RDONLY)) == -1) {
> -		return -1;
> -	}
> -
> -	if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) {
> -		goto cleanup;
> -	}
> -		
> -	retval = semanage_direct_install(sh, data, data_len);
> -
> -      cleanup:
> -	close(in_fd);
> -	if (data_len > 0) munmap(data, data_len);
> -
> -	return retval;
> -}
> +	size_t data_len = 0;
>  
> -/* Similar to semanage_direct_install(), except that it checks that
> - * there already exists a module with the same name and that the
> - * module is an older version then the one in 'data'.  Returns 0 on
> - * success, -1 if out of memory, -2 if the data does not represent a
> - * valid module file, -3 if error while writing file or reading
> - * modules directory, -4 if the previous module is same or newer than 'data', 
> - * -5 if there does not exist an older module.
> - */
> -static int semanage_direct_upgrade(semanage_handle_t * sh,
> -				   char *data, size_t data_len)
> -{
> -	int status = 0;
> -	int ret = 0;
> +	status = semanage_path_to_info(
> +			sh,
> +			install_filename,
> +			&modinfo,
> +			&data,
> +			&data_len);
> +	if (status != 0) goto cleanup;
>  
> -	char *module_name = NULL, *version = NULL;
> -	status = parse_module_headers(
> +	status = semanage_module_install_info(
>  			sh,
> +			modinfo,
>  			data,
> -			data_len,
> -			&module_name,
> -			&version);
> -	if (status != 0) {
> -		goto cleanup;
> -	}
> -
> -	semanage_module_info_t modinfo;
> -	ret = semanage_module_info_init(sh, &modinfo);
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	ret = semanage_module_info_set_priority(sh, &modinfo, sh->priority);
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	ret = semanage_module_info_set_name(sh, &modinfo, module_name);
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	ret = semanage_module_info_set_version(sh, &modinfo, version);
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	ret = semanage_module_info_set_lang_ext(sh, &modinfo, "pp");
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	ret = semanage_module_info_set_enabled(sh, &modinfo, -1);
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	status = semanage_direct_upgrade_info(sh, &modinfo, data, data_len);
> +			data_len);
>  
>  cleanup:
> -	free(module_name);
> -	free(version);
> +	semanage_module_info_destroy(sh, modinfo);
> +	free(modinfo);
> +
> +	free(data);
>  
>  	return status;
>  }
> @@ -1233,125 +1141,33 @@ cleanup:
>  static int semanage_direct_upgrade_file(semanage_handle_t * sh,
>  					const char *module_filename)
>  {
> -	int retval = -1;
> -	char *data = NULL;
> -	ssize_t data_len = 0;
> -	int compressed = 0;
> -	int in_fd = -1;
> -
> -	if ((in_fd = open(module_filename, O_RDONLY)) == -1) {
> -		return -1;
> -	}
> -
> -	if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) {
> -		goto cleanup;
> -	}
> -
> -	retval = semanage_direct_upgrade(sh, data, data_len);
> -
> -      cleanup:
> -	close(in_fd);
> -	if (data_len > 0) munmap(data, data_len);
> -
> -	return retval;
> -}
> -
> -/* Writes a base module into a sandbox, overwriting any previous base
> - * module.  Note that 'module_data' is not free()d by this function;
> - * caller is responsible for deallocating it if necessary.  Returns 0
> - * on success, -1 if out of memory, -2 if the data does not represent
> - * a valid base module file, -3 if error while writing file.
> - */
> -static int semanage_direct_install_base(semanage_handle_t * sh,
> -					char *base_data, size_t data_len)
> -{
>  	int status = 0;
> -	int ret = 0;
> -
> -	ret = parse_base_headers(sh, base_data, data_len);
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	semanage_module_info_t modinfo;
> -	ret = semanage_module_info_init(sh, &modinfo);
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	ret = semanage_module_info_set_priority(sh, &modinfo, sh->priority);
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	ret = semanage_module_info_set_name(sh, &modinfo, "_base");
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	ret = semanage_module_info_set_version(sh, &modinfo, "1.0.0");
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> -
> -	ret = semanage_module_info_set_lang_ext(sh, &modinfo, "pp");
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
>  
> -	ret = semanage_module_info_set_enabled(sh, &modinfo, 1);
> -	if (ret != 0) {
> -		status = -1;
> -		goto cleanup;
> -	}
> +	semanage_module_info_t *modinfo = NULL;
> +	char *data = NULL;
> +	size_t data_len = 0;
>  
> -	status = semanage_direct_install_info(
> +	status = semanage_path_to_info(
>  			sh,
> +			module_filename,
>  			&modinfo,
> -			base_data,
> +			&data,
> +			&data_len);
> +	if (status != 0) goto cleanup;
> +
> +	status = semanage_module_upgrade_info(
> +			sh,
> +			modinfo,
> +			data,
>  			data_len);
>  
>  cleanup:
> -	semanage_module_info_destroy(sh, &modinfo);
> -
> -	return status;
> -}
> -
> -/* Writes a base module into a sandbox, overwriting any previous base
> - * module.  
> - * Returns 0 on success, -1 if out of memory, -2 if the data does not represent
> - * a valid base module file, -3 if error while writing file.
> - */
> -static int semanage_direct_install_base_file(semanage_handle_t * sh,
> -					     const char *install_filename)
> -{
> -	int retval = -1;
> -	char *data = NULL;
> -	ssize_t data_len = 0;
> -	int compressed = 0;
> -	int in_fd;
> -
> -	if ((in_fd = open(install_filename, O_RDONLY)) == -1) {
> -		return -1;
> -	}
> -
> -	if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) {
> -		goto cleanup;
> -	}
> -		
> -	retval = semanage_direct_install_base(sh, data, data_len);
> +	semanage_module_info_destroy(sh, modinfo);
> +	free(modinfo);
>  
> -      cleanup:
> -	close(in_fd);
> -	if (data_len > 0) munmap(data, data_len);
> +	free(data);
>  
> -	return retval;
> +	return status;
>  }
>  
>  /* Removes a module from the sandbox.  Returns 0 on success, -1 if out
> @@ -1386,6 +1202,14 @@ cleanup:
>  	return status;
>  }
>  
> +/* qsort comparison function for semanage_direct_list. */
> +static int semanage_direct_list_cmp(const void *a, const void *b)
> +{
> +	semanage_module_info_t *ma = (semanage_module_info_t *)a;
> +	semanage_module_info_t *mb = (semanage_module_info_t *)b;
> +	return strverscmp(ma->name, mb->name);
> +}
> +
>  /* Allocate an array of module_info structures for each readable
>   * module within the store.  Note that if the calling program has
>   * already begun a transaction then this function will get a list of
> @@ -1393,97 +1217,108 @@ cleanup:
>   * semanage_module_info_datum_destroy() on each element of the array
>   * as well as free()ing the entire list.
>   */
> -static int semanage_direct_list(semanage_handle_t * sh,
> -				semanage_module_info_t ** modinfo,
> -				int *num_modules)
> +static int semanage_direct_list(semanage_handle_t *sh,
> +				semanage_module_info_t **modinfos,
> +				int *modinfos_len)
>  {
> -	struct sepol_policy_file *pf = NULL;
> -	int i, retval = -1;
> -	char **module_filenames = NULL;
> -	int num_mod_files;
> -	*modinfo = NULL;
> -	*num_modules = 0;
> +	assert(sh);
> +	assert(modinfos);
> +	assert(modinfos_len);
>  
> -	/* get the read lock when reading from the active
> -	   (non-transaction) directory */
> -	if (!sh->is_in_transaction)
> -		if (semanage_get_active_lock(sh) < 0)
> -			return -1;
> +	int status = 0;
> +	int ret = 0;
>  
> -	if (semanage_get_modules_names(sh, &module_filenames, &num_mod_files) ==
> -	    -1) {
> -		goto cleanup;
> -	}
> -	if (num_mod_files == 0) {
> -		retval = semanage_direct_get_serial(sh);
> -		goto cleanup;
> -	}
> +	int i = 0;
> +	int j = 0;
>  
> -	if (sepol_policy_file_create(&pf)) {
> -		ERR(sh, "Out of memory!");
> +	semanage_list_t *list = NULL;
> +	semanage_list_t *found = NULL;
> +
> +	semanage_module_info_t *all_modinfos = NULL;
> +	int all_modinfos_len = 0;
> +
> +	void *tmp = NULL;
> +
> +	/* get all modules */
> +	ret = semanage_module_list_all(sh, &all_modinfos, &all_modinfos_len);
> +	if (ret != 0) {
> +		status = -1;
>  		goto cleanup;
>  	}
> -	sepol_policy_file_set_handle(pf, sh->sepolh);
>  
> -	if ((*modinfo = calloc(num_mod_files, sizeof(**modinfo))) == NULL) {
> -		ERR(sh, "Out of memory!");
> +	/* allocate enough for worst case */
> +	(*modinfos) = calloc(all_modinfos_len, sizeof(semanage_module_info_t));
> +	if ((*modinfos) == NULL) {
> +		ERR(sh, "Error allocating space for module info array.");
> +		status = -1;
>  		goto cleanup;
>  	}
>  
> -	for (i = 0; i < num_mod_files; i++) {
> -		FILE *fp;
> -		char *name = NULL, *version = NULL;
> -		int type;
> -		if ((fp = fopen(module_filenames[i], "rb")) == NULL) {
> -			/* could not open this module file, so don't
> -			 * report it */
> -			continue;
> -		}
> -		ssize_t size;
> -		char *data = NULL;
> -
> -		if ((size = bunzip(sh, fp, &data)) > 0) {
> -			fclose(fp);
> -			fp = fmemopen(data, size, "rb");
> -			if (!fp) {
> -				ERR(sh, "Out of memory!");
> +	*modinfos_len = all_modinfos_len;
> +
> +	/* for each highest priority, enabled module clone */
> +	semanage_list_destroy(&list);
> +	for (i = 0, j = 0; i < all_modinfos_len; i++) {
> +		/* check if enabled */
> +		if (all_modinfos[i].enabled != 1) continue;
> +
> +		/* check if we've seen this before (i.e. highest priority) */
> +		found = semanage_list_find(list, all_modinfos[i].name);
> +		if (found == NULL) {
> +			ret = semanage_list_push(&list, all_modinfos[i].name);
> +			if (ret != 0) {
> +				ERR(sh, "Failed to add module name to list of known names.");
> +				status = -1;
>  				goto cleanup;
>  			}
>  		}
> -		rewind(fp);
> -		__fsetlocking(fp, FSETLOCKING_BYCALLER);
> -		sepol_policy_file_set_fp(pf, fp);
> -		if (sepol_module_package_info(pf, &type, &name, &version)) {
> -			fclose(fp);
> -			free(data);
> -			free(name);
> -			free(version);
> -			continue;
> -		}
> -		fclose(fp);
> -		free(data);
> -		if (type == SEPOL_POLICY_MOD) {
> -			(*modinfo)[*num_modules].name = name;
> -			(*modinfo)[*num_modules].version = version;
> -			(*num_modules)++;
> -		} else {
> -			/* file was not a module, so don't report it */
> -			free(name);
> -			free(version);
> +		else continue;
> +
> +		ret = semanage_module_info_clone(
> +				sh,
> +				&all_modinfos[i],
> +				&(*modinfos)[j]);
> +		if (ret != 0) {
> +			ERR(sh, "Failed to clone module into array.");
> +			status = -1;
> +			goto cleanup;
>  		}
> +
> +		j += 1;
>  	}
> -	retval = semanage_direct_get_serial(sh);
>  
> -      cleanup:
> -	sepol_policy_file_free(pf);
> -	for (i = 0; module_filenames != NULL && i < num_mod_files; i++) {
> -		free(module_filenames[i]);
> +	/* realloc the array to its min size */
> +	tmp = realloc(*modinfos, j * sizeof(semanage_module_info_t));
> +	if (tmp == NULL) {
> +		ERR(sh, "Error allocating space for module info array.");
> +		status = -1;
> +		goto cleanup;
>  	}
> -	free(module_filenames);
> -	if (!sh->is_in_transaction) {
> -		semanage_release_active_lock(sh);
> +	*modinfos = tmp;
> +	*modinfos_len = j;
> +
> +	/* sort array on module name */
> +	qsort(*modinfos,
> +	      *modinfos_len,
> +	      sizeof(semanage_module_info_t),
> +	      semanage_direct_list_cmp);
> +
> +cleanup:
> +	semanage_list_destroy(&list);
> +
> +	for (i = 0; i < all_modinfos_len; i++) {
> +		semanage_module_info_destroy(sh, &all_modinfos[i]);
>  	}
> -	return retval;
> +	free(all_modinfos);
> +
> +	if (status != 0) {
> +		for (i = 0; i < *modinfos_len; i++) {
> +			semanage_module_info_destroy(sh, &(*modinfos)[i]);
> +		}
> +		free(*modinfos);
> +	}
> +
> +	return status;
>  }
>  
>  static int semanage_direct_get_enabled(semanage_handle_t *sh,

-- 
James Carter <jwcart2@tycho.nsa.gov>
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 14/15] [src-policy] semodule: user message support
  2010-01-26 22:08                           ` [PATCH 14/15] [src-policy] semodule: user message support Caleb Case
  2010-01-26 22:08                             ` [PATCH 15/15] [src-policy] semanage: source permissive module Caleb Case
@ 2010-02-01 15:11                             ` James Carter
  2010-02-01 17:00                               ` Caleb Case
  1 sibling, 1 reply; 34+ messages in thread
From: James Carter @ 2010-02-01 15:11 UTC (permalink / raw)
  To: Caleb Case; +Cc: selinux, csellers, kmacmillan, jbrindle, sds

On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote:
> This adds the -m,--message option to semodule so that users can specify
> a message for the ChangeLog.
> 

Is there plans to add user message support to semanage?  Unfortunately,
in semanage "-m" is already in use.

>   -m,--message=MSG user message for the ChangeLog
> 
> Example:
> 
> # semodule -E alsa -m "Allow alsa to execute cowsay."
> ---
>  policycoreutils/semodule/semodule.8 |    3 +++
>  policycoreutils/semodule/semodule.c |   24 +++++++++++++++++++++++-
>  2 files changed, 26 insertions(+), 1 deletions(-)
> 
> diff --git a/policycoreutils/semodule/semodule.8 b/policycoreutils/semodule/semodule.8
> index 8baad8b..97d31dd 100644
> --- a/policycoreutils/semodule/semodule.8
> +++ b/policycoreutils/semodule/semodule.8
> @@ -87,6 +87,9 @@ prints help message and quit
>  .TP
>  .B  \-v,\-\-verbose     
>  be verbose
> +.TP
> +.B  \-m,\-\-message=MSG
> +user message for the ChangeLog
>  
>  .SH EXAMPLE
>  .nf
> diff --git a/policycoreutils/semodule/semodule.c b/policycoreutils/semodule/semodule.c
> index 3536253..c8bf986 100644
> --- a/policycoreutils/semodule/semodule.c
> +++ b/policycoreutils/semodule/semodule.c
> @@ -58,6 +58,7 @@ static int create_store;
>  static int build;
>  static int disable_dontaudit;
>  static uint16_t priority;
> +static char *message = NULL;
>  
>  static semanage_handle_t *sh = NULL;
>  static char *store;
> @@ -72,6 +73,8 @@ static void cleanup(void)
>  		free(commands[num_commands].output);
>  	}
>  	free(commands);
> +
> +	free(message);
>  }
>  
>  /* Signal handlers. */
> @@ -134,6 +137,7 @@ static void usage(char *progname)
>  	printf("  -h,--help        print this message and quit\n");
>  	printf("  -v,--verbose     be verbose\n");
>  	printf("  -D,--disable_dontaudit	Remove dontaudits from policy\n");
> +	printf("  -m,--message=MSG user message for the ChangeLog\n");
>  }
>  
>  /* Sets the global mode variable to new_mode, but only if no other
> @@ -186,6 +190,7 @@ static void parse_command_line(int argc, char **argv)
>  		{"output", required_argument, NULL, 'o'},
>  		{"cil", 0, NULL, 'c'},
>  		{"edit", required_argument, NULL, 'E'},
> +		{"message", required_argument, NULL, 'm'},
>  		{NULL, 0, NULL, 0}
>  	};
>  	int i;
> @@ -195,7 +200,7 @@ static void parse_command_line(int argc, char **argv)
>  	create_store = 0;
>  	priority = 400;
>  	while ((i =
> -		getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnBDp:e:d:g:o:cE:", opts,
> +		getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnBDp:e:d:g:o:cE:m:", opts,
>  			    NULL)) != -1) {
>  		switch (i) {
>  		case 'b':
> @@ -294,6 +299,13 @@ static void parse_command_line(int argc, char **argv)
>  		case 'E':
>  			set_mode(EDIT_M, optarg);
>  			break;
> +		case 'm':
> +			message = strdup(optarg);
> +			if (message == NULL) {
> +				fprintf(stderr, "Failed to set message (out of memory).");
> +				exit(1);
> +			}
> +			break;
>  		case '?':
>  		default:{
>  				usage(argv[0]);
> @@ -414,6 +426,16 @@ int main(int argc, char *argv[])
>  		goto cleanup;
>  	}
>  
> +	if (message) {
> +		result = semanage_set_log_message(sh, message);
> +		if (result != 0) {
> +			fprintf(stderr,
> +				"%s: Failed to set ChangeLog message.",
> +				argv[0]);
> +			goto cleanup;
> +		}
> +	}
> +
>  	for (i = 0; i < num_commands; i++) {
>  		enum client_modes mode = commands[i].mode;
>  		char *mode_arg = commands[i].arg;

-- 
James Carter <jwcart2@tycho.nsa.gov>
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* RE: [PATCH 14/15] [src-policy] semodule: user message support
  2010-02-01 15:11                             ` [PATCH 14/15] [src-policy] semodule: user message support James Carter
@ 2010-02-01 17:00                               ` Caleb Case
  2010-02-01 17:06                                 ` James Carter
  0 siblings, 1 reply; 34+ messages in thread
From: Caleb Case @ 2010-02-01 17:00 UTC (permalink / raw)
  To: jwcart2; +Cc: selinux, Chad Sellers, Karl MacMillan, Joshua Brindle, sds



> -----Original Message-----
> From: James Carter [mailto:jwcart2@tycho.nsa.gov]
> Sent: Monday, February 01, 2010 10:12 AM
> To: Caleb Case
> Cc: selinux@tycho.nsa.gov; Chad Sellers; Karl MacMillan; Joshua
Brindle;
> sds@tycho.nsa.gov
> Subject: Re: [PATCH 14/15] [src-policy] semodule: user message support
> 
> On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote:
> > This adds the -m,--message option to semodule so that users can
specify
> > a message for the ChangeLog.
> >
> 
> Is there plans to add user message support to semanage?
Unfortunately,
> in semanage "-m" is already in use.

Yes, maybe -M is better so we can use the same flag in both tools?

> 
> >   -m,--message=MSG user message for the ChangeLog
> >
> > Example:
> >
> > # semodule -E alsa -m "Allow alsa to execute cowsay."
> > ---
> >  policycoreutils/semodule/semodule.8 |    3 +++
> >  policycoreutils/semodule/semodule.c |   24 +++++++++++++++++++++++-
> >  2 files changed, 26 insertions(+), 1 deletions(-)
> >
> > diff --git a/policycoreutils/semodule/semodule.8
> b/policycoreutils/semodule/semodule.8
> > index 8baad8b..97d31dd 100644
> > --- a/policycoreutils/semodule/semodule.8
> > +++ b/policycoreutils/semodule/semodule.8
> > @@ -87,6 +87,9 @@ prints help message and quit
> >  .TP
> >  .B  \-v,\-\-verbose
> >  be verbose
> > +.TP
> > +.B  \-m,\-\-message=MSG
> > +user message for the ChangeLog
> >
> >  .SH EXAMPLE
> >  .nf
> > diff --git a/policycoreutils/semodule/semodule.c
> b/policycoreutils/semodule/semodule.c
> > index 3536253..c8bf986 100644
> > --- a/policycoreutils/semodule/semodule.c
> > +++ b/policycoreutils/semodule/semodule.c
> > @@ -58,6 +58,7 @@ static int create_store;
> >  static int build;
> >  static int disable_dontaudit;
> >  static uint16_t priority;
> > +static char *message = NULL;
> >
> >  static semanage_handle_t *sh = NULL;
> >  static char *store;
> > @@ -72,6 +73,8 @@ static void cleanup(void)
> >  		free(commands[num_commands].output);
> >  	}
> >  	free(commands);
> > +
> > +	free(message);
> >  }
> >
> >  /* Signal handlers. */
> > @@ -134,6 +137,7 @@ static void usage(char *progname)
> >  	printf("  -h,--help        print this message and quit\n");
> >  	printf("  -v,--verbose     be verbose\n");
> >  	printf("  -D,--disable_dontaudit	Remove dontaudits from
> policy\n");
> > +	printf("  -m,--message=MSG user message for the ChangeLog\n");
> >  }
> >
> >  /* Sets the global mode variable to new_mode, but only if no other
> > @@ -186,6 +190,7 @@ static void parse_command_line(int argc, char
> **argv)
> >  		{"output", required_argument, NULL, 'o'},
> >  		{"cil", 0, NULL, 'c'},
> >  		{"edit", required_argument, NULL, 'E'},
> > +		{"message", required_argument, NULL, 'm'},
> >  		{NULL, 0, NULL, 0}
> >  	};
> >  	int i;
> > @@ -195,7 +200,7 @@ static void parse_command_line(int argc, char
> **argv)
> >  	create_store = 0;
> >  	priority = 400;
> >  	while ((i =
> > -		getopt_long(argc, argv,
"s:b:hi:l::vqr:u:RnBDp:e:d:g:o:cE:",
> opts,
> > +		getopt_long(argc, argv,
"s:b:hi:l::vqr:u:RnBDp:e:d:g:o:cE:m:",
> opts,
> >  			    NULL)) != -1) {
> >  		switch (i) {
> >  		case 'b':
> > @@ -294,6 +299,13 @@ static void parse_command_line(int argc, char
> **argv)
> >  		case 'E':
> >  			set_mode(EDIT_M, optarg);
> >  			break;
> > +		case 'm':
> > +			message = strdup(optarg);
> > +			if (message == NULL) {
> > +				fprintf(stderr, "Failed to set message
(out of
> memory).");
> > +				exit(1);
> > +			}
> > +			break;
> >  		case '?':
> >  		default:{
> >  				usage(argv[0]);
> > @@ -414,6 +426,16 @@ int main(int argc, char *argv[])
> >  		goto cleanup;
> >  	}
> >
> > +	if (message) {
> > +		result = semanage_set_log_message(sh, message);
> > +		if (result != 0) {
> > +			fprintf(stderr,
> > +				"%s: Failed to set ChangeLog message.",
> > +				argv[0]);
> > +			goto cleanup;
> > +		}
> > +	}
> > +
> >  	for (i = 0; i < num_commands; i++) {
> >  		enum client_modes mode = commands[i].mode;
> >  		char *mode_arg = commands[i].arg;
> 
> --
> James Carter <jwcart2@tycho.nsa.gov>
> National Security Agency



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* RE: [PATCH 14/15] [src-policy] semodule: user message support
  2010-02-01 17:00                               ` Caleb Case
@ 2010-02-01 17:06                                 ` James Carter
  0 siblings, 0 replies; 34+ messages in thread
From: James Carter @ 2010-02-01 17:06 UTC (permalink / raw)
  To: Caleb Case; +Cc: selinux, Chad Sellers, Karl MacMillan, Joshua Brindle, sds

On Mon, 2010-02-01 at 12:00 -0500, Caleb Case wrote:
> 
> > -----Original Message-----
> > From: James Carter [mailto:jwcart2@tycho.nsa.gov]
> > Sent: Monday, February 01, 2010 10:12 AM
> > To: Caleb Case
> > Cc: selinux@tycho.nsa.gov; Chad Sellers; Karl MacMillan; Joshua
> Brindle;
> > sds@tycho.nsa.gov
> > Subject: Re: [PATCH 14/15] [src-policy] semodule: user message support
> > 
> > On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote:
> > > This adds the -m,--message option to semodule so that users can
> specify
> > > a message for the ChangeLog.
> > >
> > 
> > Is there plans to add user message support to semanage?
> Unfortunately,
> > in semanage "-m" is already in use.
> 
> Yes, maybe -M is better so we can use the same flag in both tools?

It would be confusing to have different flags, so -M is better.  It
would have been nice to use -m since cvs, svn, and git all use it for
log messages.  Oh well.

> 
> > 
> > >   -m,--message=MSG user message for the ChangeLog
> > >
> > > Example:
> > >
> > > # semodule -E alsa -m "Allow alsa to execute cowsay."
> > > ---
> > >  policycoreutils/semodule/semodule.8 |    3 +++
> > >  policycoreutils/semodule/semodule.c |   24 +++++++++++++++++++++++-
> > >  2 files changed, 26 insertions(+), 1 deletions(-)
> > >
> > > diff --git a/policycoreutils/semodule/semodule.8
> > b/policycoreutils/semodule/semodule.8
> > > index 8baad8b..97d31dd 100644
> > > --- a/policycoreutils/semodule/semodule.8
> > > +++ b/policycoreutils/semodule/semodule.8
> > > @@ -87,6 +87,9 @@ prints help message and quit
> > >  .TP
> > >  .B  \-v,\-\-verbose
> > >  be verbose
> > > +.TP
> > > +.B  \-m,\-\-message=MSG
> > > +user message for the ChangeLog
> > >
> > >  .SH EXAMPLE
> > >  .nf
> > > diff --git a/policycoreutils/semodule/semodule.c
> > b/policycoreutils/semodule/semodule.c
> > > index 3536253..c8bf986 100644
> > > --- a/policycoreutils/semodule/semodule.c
> > > +++ b/policycoreutils/semodule/semodule.c
> > > @@ -58,6 +58,7 @@ static int create_store;
> > >  static int build;
> > >  static int disable_dontaudit;
> > >  static uint16_t priority;
> > > +static char *message = NULL;
> > >
> > >  static semanage_handle_t *sh = NULL;
> > >  static char *store;
> > > @@ -72,6 +73,8 @@ static void cleanup(void)
> > >  		free(commands[num_commands].output);
> > >  	}
> > >  	free(commands);
> > > +
> > > +	free(message);
> > >  }
> > >
> > >  /* Signal handlers. */
> > > @@ -134,6 +137,7 @@ static void usage(char *progname)
> > >  	printf("  -h,--help        print this message and quit\n");
> > >  	printf("  -v,--verbose     be verbose\n");
> > >  	printf("  -D,--disable_dontaudit	Remove dontaudits from
> > policy\n");
> > > +	printf("  -m,--message=MSG user message for the ChangeLog\n");
> > >  }
> > >
> > >  /* Sets the global mode variable to new_mode, but only if no other
> > > @@ -186,6 +190,7 @@ static void parse_command_line(int argc, char
> > **argv)
> > >  		{"output", required_argument, NULL, 'o'},
> > >  		{"cil", 0, NULL, 'c'},
> > >  		{"edit", required_argument, NULL, 'E'},
> > > +		{"message", required_argument, NULL, 'm'},
> > >  		{NULL, 0, NULL, 0}
> > >  	};
> > >  	int i;
> > > @@ -195,7 +200,7 @@ static void parse_command_line(int argc, char
> > **argv)
> > >  	create_store = 0;
> > >  	priority = 400;
> > >  	while ((i =
> > > -		getopt_long(argc, argv,
> "s:b:hi:l::vqr:u:RnBDp:e:d:g:o:cE:",
> > opts,
> > > +		getopt_long(argc, argv,
> "s:b:hi:l::vqr:u:RnBDp:e:d:g:o:cE:m:",
> > opts,
> > >  			    NULL)) != -1) {
> > >  		switch (i) {
> > >  		case 'b':
> > > @@ -294,6 +299,13 @@ static void parse_command_line(int argc, char
> > **argv)
> > >  		case 'E':
> > >  			set_mode(EDIT_M, optarg);
> > >  			break;
> > > +		case 'm':
> > > +			message = strdup(optarg);
> > > +			if (message == NULL) {
> > > +				fprintf(stderr, "Failed to set message
> (out of
> > memory).");
> > > +				exit(1);
> > > +			}
> > > +			break;
> > >  		case '?':
> > >  		default:{
> > >  				usage(argv[0]);
> > > @@ -414,6 +426,16 @@ int main(int argc, char *argv[])
> > >  		goto cleanup;
> > >  	}
> > >
> > > +	if (message) {
> > > +		result = semanage_set_log_message(sh, message);
> > > +		if (result != 0) {
> > > +			fprintf(stderr,
> > > +				"%s: Failed to set ChangeLog message.",
> > > +				argv[0]);
> > > +			goto cleanup;
> > > +		}
> > > +	}
> > > +
> > >  	for (i = 0; i < num_commands; i++) {
> > >  		enum client_modes mode = commands[i].mode;
> > >  		char *mode_arg = commands[i].arg;
> > 
> > --
> > James Carter <jwcart2@tycho.nsa.gov>
> > National Security Agency
> 
> 
> 
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.

-- 
James Carter <jwcart2@tycho.nsa.gov>
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* RE: [PATCH 04/15] [src-policy] refpol intermediate language compiler (refpol_ilc)
  2010-01-28 21:03         ` [PATCH 04/15] [src-policy] refpol intermediate language compiler (refpol_ilc) James Carter
@ 2010-02-01 17:43           ` Caleb Case
  0 siblings, 0 replies; 34+ messages in thread
From: Caleb Case @ 2010-02-01 17:43 UTC (permalink / raw)
  To: jwcart2; +Cc: selinux, Chad Sellers, Karl MacMillan, Joshua Brindle, sds



> -----Original Message-----
> From: James Carter [mailto:jwcart2@tycho.nsa.gov]
> Sent: Thursday, January 28, 2010 4:03 PM
> To: Caleb Case
> Cc: selinux@tycho.nsa.gov; Chad Sellers; Karl MacMillan; Joshua
Brindle;
> sds@tycho.nsa.gov
> Subject: Re: [PATCH 04/15] [src-policy] refpol intermediate language
> compiler (refpol_ilc)
> 
> On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote:
> > In the interim, before the completion of the proposed CIL[1], the
> > intermediate language will be a specialized version of refpol and
the
> > Reference Policy build environment.
> >
> > [refpol_ilc CIL Compiler]
> >
> > The repfol intermediate language compiler (refpol_ilc) builds a
binary
> > base module from refpol module.  Producing a binary base module
allows
> > the existing libsemanage framework to continue to operate
essentially as
> > it does today (load base module, apply database changes, create
loadable
> > policy).
> >
> >    Usage: refpol_ilc [OPTIONS] MODULE MODULE ...
> >
> >    Options:
> >      --version             show program's version number and exit
> >      -h, --help            show this help message and exit
> >      -d FILE, --disabled=FILE
> >                            indicates module is disabled
> >      -f, --force           force overwriting existing files
> >      -t DIR, --tmp=DIR     temporary build directory
> >      -b DIR, --build-template=DIR
> >                            build template directory (Default:
> >                            /usr/share/selinux/refpol_ilc/build)
> >      -o FILE, --output=FILE
> >                            output file
> >      -c BOOL, --cleanup=BOOL
> >                            cleanup (remove) temporary directory
> (Default: True)
> >
> > Note: The paths passed to the refpol_ilc need to be in the format of
the
> >       semanage store in /var/lib/selinux. The refpol_ilc extracts
the
> >       module name from the path. Future CIL will also likely extract
the
> >       priority of the module from the path.
> >
> > Example:
> >
> > The compiles the moduless installed in the 'test' store into a
base.pp:
> >
> > # refpol_ilc `find /var/lib/selinux/test/active/modules/400/ -iname
cil`
> > base.pp
> >
> > [Compilation]
> >
> > Compilation proceeds as follows:
> >
> >   1. Copy build environment to temporary location.
> >
> >      Note: refpol_ilc anticipates the build environment being
installed
> >            to /usr/share/selinux/refpol_ilc/build by default.
> >
> >   2. Install modules (see Special Modules and Normal Modules below).
> >
> >   3. Create conf files.
> >
> >   4. Set all modules to base or off as appropriate in modules.conf.
> >
> >   5. Create base module (base.pp).
> >
> > [Special Modules]
> >
> > A number of modules are considered to be special and are installed
into
> > special locations in the build environment:
> >
> >    [Module Name]         [Reference Policy File]
> >
> >    _constraints           policy/constraints
> >    _global_booleans       policy/global_booleans
> >    _global_tunables       policy/global_tunables
> >    _mcs                   policy/mcs
> >    _mls                   policy/mls
> >    _policy_capabilities   policy/policy_capabilities
> >    _rolemap               policy/rolemap
> >    _users                 policy/users
> >    _access_vectors        policy/flask/access_vectors
> >    _initial_sids          policy/flask/initial_sids
> >    _security_classes      policy/flask/security_classes
> >    _file_patterns         policy/support/file_patterns.spt
> >    _ipc_patterns          policy/support/ipc_patterns.spt
> >    _loadable_module       policy/support/loadable_module.spt
> >    _misc_macros           policy/support/misc_macros.spt
> >    _misc_patterns         policy/support/misc_patterns.spt
> >    _mls_mcs_macros        policy/support/mls_mcs_macros.spt
> >    _obj_perm_sets         policy/support/obj_perm_sets.spt
> >
> 
> In the policy store, mcs and mls modules exist along with _mcs and
_mls
> modules.  But _mcs calls itself "mcs" in the policy_module statement
and
> _mls calls itself "mls" in the policy_module statement.
> 
> mcs:
> policy_module(mcs, 1.2.0)
> 
> _mcs:
> policy_module(mcs, 2.20091117)
> 
> mls:
> policy_module(mls, 1.8.0)
> 
> _mls:
> policy_module(mls, 2.20091117)
> 
> Is there a reason for this?

Oops, it's a bug in the refpolicy2refpol script. The names should match.

> 
> > The build.conf file is handled with another special module _defines.
> > This module provides some of the variables for the traditional
> > build.conf with the remaining variables determined by the build
> > environment as follows:
> >
> >    OUTPUT_POLICY   =>   Copied from _defines.
> >    TYPE            =>   Detect from the presence of the mls/mcs
modules.
> >                         mls > mcs > none: meaning that if there is
an
> >                         _mls module, then TYPE = mls, even if there
is
> an
> >                         mcs module present.
> >    NAME            =>   Copied from _defines.
> >    DISTRO          =>   Copied from _defines.
> >    UNK_PERMS       =>   Copied from _defines.
> >    DIRECT_INITRC   =>   Copied from _defines.
> >    MONOLITHIC      =>   Fixed to 'n'.
> >    UBAC            =>   Copied from _defines.
> >    MLS_SENS        =>   Copied from _defines.
> >    MLS_CATS        =>   Copied from _defines.
> >    MCS_CATS        =>   Copied from _defines.
> >    QUIET           =>   Copied from _defines.
> >
> > No other special modules are permitted. All special modules are
> > prepended with '_' to distinguish them from normal modules.
> >
> > Note: The MLS/MCS/Standard setting of the policy is derived from the
> >       presense of the _mls or _mcs modules. It is no longer
necessary to
> >       specify the policy type explicitly via the TYPE statement.
This
> >       also allows policy type to be switched simply by
enabling/disabled
> >       the _mls/_mcs modules.
> >
> > [Normal Modules]
> >
> > All normal (non-special) modules are copied to
policy/modules/kernel/
> > and unpacked into the Reference Policy module 3 file format.
> >
> > [1] CIL RFC: http://marc.info/?l=selinux&m=124759244409438&w=2
> > ---
> >  Makefile                            |    2 +-
> >  refpol_ilc/COPYING                  |  504
> +++++++++++++++++++++++++++++++++++
> >  refpol_ilc/Makefile                 |   24 ++
> >  refpol_ilc/refpol_ilc.py            |   17 ++
> >  refpol_ilc/refpol_ilc/refpol_ilc.py |  193 +++++++++++++
> >  refpol_ilc/setup.py                 |   13 +
> >  6 files changed, 752 insertions(+), 1 deletions(-)
> >  create mode 100644 refpol_ilc/COPYING
> >  create mode 100644 refpol_ilc/Makefile
> >  create mode 100755 refpol_ilc/refpol_ilc.py
> >  create mode 100644 refpol_ilc/refpol_ilc/__init__.py
> >  create mode 100644 refpol_ilc/refpol_ilc/refpol_ilc.py
> >  create mode 100755 refpol_ilc/setup.py
> >
> > diff --git a/Makefile b/Makefile
> > index be2a4ec..afb4843 100644
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -1,4 +1,4 @@
> > -SUBDIRS=libsepol libselinux libsemanage sepolgen checkpolicy
> policycoreutils refpol corenet # policy
> > +SUBDIRS=libsepol libselinux libsemanage sepolgen checkpolicy
> policycoreutils refpol corenet refpol_ilc # policy
> >  PYSUBDIRS=libselinux libsemanage
> >
> >  ifeq ($(DEBUG),1)
> > diff --git a/refpol_ilc/COPYING b/refpol_ilc/COPYING
> > new file mode 100644
> > index 0000000..8add30a
> > --- /dev/null
> > +++ b/refpol_ilc/COPYING
> > @@ -0,0 +1,504 @@
> > +		  GNU LESSER GENERAL PUBLIC LICENSE
> > +		       Version 2.1, February 1999
> > +
> > + Copyright (C) 1991, 1999 Free Software Foundation, Inc.
> > +     51 Franklin St, 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.
> > +
> > +[This is the first released version of the Lesser GPL.  It also
counts
> > + as the successor of the GNU Library Public License, version 2,
hence
> > + the version number 2.1.]
> > +
> > +			    Preamble
> > +
> > +  The licenses for most software are designed to take away your
> > +freedom to share and change it.  By contrast, the GNU General
Public
> > +Licenses are intended to guarantee your freedom to share and change
> > +free software--to make sure the software is free for all its users.
> > +
> > +  This license, the Lesser General Public License, applies to some
> > +specially designated software packages--typically libraries--of the
> > +Free Software Foundation and other authors who decide to use it.
You
> > +can use it too, but we suggest you first think carefully about
whether
> > +this license or the ordinary General Public License is the better
> > +strategy to use in any particular case, based on the explanations
> below.
> > +
> > +  When we speak of free software, we are referring to freedom of
use,
> > +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 and use pieces
of
> > +it in new free programs; and that you are informed that you can do
> > +these things.
> > +
> > +  To protect your rights, we need to make restrictions that forbid
> > +distributors to deny you these rights or to ask you to surrender
these
> > +rights.  These restrictions translate to certain responsibilities
for
> > +you if you distribute copies of the library or if you modify it.
> > +
> > +  For example, if you distribute copies of the library, whether
gratis
> > +or for a fee, you must give the recipients all the rights that we
gave
> > +you.  You must make sure that they, too, receive or can get the
source
> > +code.  If you link other code with the library, you must provide
> > +complete object files to the recipients, so that they can relink
them
> > +with the library after making changes to the library and
recompiling
> > +it.  And you must show them these terms so they know their rights.
> > +
> > +  We protect your rights with a two-step method: (1) we copyright
the
> > +library, and (2) we offer you this license, which gives you legal
> > +permission to copy, distribute and/or modify the library.
> > +
> > +  To protect each distributor, we want to make it very clear that
> > +there is no warranty for the free library.  Also, if the library is
> > +modified by someone else and passed on, the recipients should know
> > +that what they have is not the original version, so that the
original
> > +author's reputation will not be affected by problems that might be
> > +introduced by others.
> > +
> 
> 
> > +  Finally, software patents pose a constant threat to the existence
of
> > +any free program.  We wish to make sure that a company cannot
> > +effectively restrict the users of a free program by obtaining a
> > +restrictive license from a patent holder.  Therefore, we insist
that
> > +any patent license obtained for a version of the library must be
> > +consistent with the full freedom of use specified in this license.
> > +
> > +  Most GNU software, including some libraries, is covered by the
> > +ordinary GNU General Public License.  This license, the GNU Lesser
> > +General Public License, applies to certain designated libraries,
and
> > +is quite different from the ordinary General Public License.  We
use
> > +this license for certain libraries in order to permit linking those
> > +libraries into non-free programs.
> > +
> > +  When a program is linked with a library, whether statically or
using
> > +a shared library, the combination of the two is legally speaking a
> > +combined work, a derivative of the original library.  The ordinary
> > +General Public License therefore permits such linking only if the
> > +entire combination fits its criteria of freedom.  The Lesser
General
> > +Public License permits more lax criteria for linking other code
with
> > +the library.
> > +
> > +  We call this license the "Lesser" General Public License because
it
> > +does Less to protect the user's freedom than the ordinary General
> > +Public License.  It also provides other free software developers
Less
> > +of an advantage over competing non-free programs.  These
disadvantages
> > +are the reason we use the ordinary General Public License for many
> > +libraries.  However, the Lesser license provides advantages in
certain
> > +special circumstances.
> > +
> > +  For example, on rare occasions, there may be a special need to
> > +encourage the widest possible use of a certain library, so that it
> becomes
> > +a de-facto standard.  To achieve this, non-free programs must be
> > +allowed to use the library.  A more frequent case is that a free
> > +library does the same job as widely used non-free libraries.  In
this
> > +case, there is little to gain by limiting the free library to free
> > +software only, so we use the Lesser General Public License.
> > +
> > +  In other cases, permission to use a particular library in
non-free
> > +programs enables a greater number of people to use a large body of
> > +free software.  For example, permission to use the GNU C Library in
> > +non-free programs enables many more people to use the whole GNU
> > +operating system, as well as its variant, the GNU/Linux operating
> > +system.
> > +
> > +  Although the Lesser General Public License is Less protective of
the
> > +users' freedom, it does ensure that the user of a program that is
> > +linked with the Library has the freedom and the wherewithal to run
> > +that program using a modified version of the Library.
> > +
> > +  The precise terms and conditions for copying, distribution and
> > +modification follow.  Pay close attention to the difference between
a
> > +"work based on the library" and a "work that uses the library".
The
> > +former contains code derived from the library, whereas the latter
must
> > +be combined with the library in order to run.
> > +
> 
> 
> > +		  GNU LESSER GENERAL PUBLIC LICENSE
> > +   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
> > +
> > +  0. This License Agreement applies to any software library or
other
> > +program which contains a notice placed by the copyright holder or
> > +other authorized party saying it may be distributed under the terms
of
> > +this Lesser General Public License (also called "this License").
> > +Each licensee is addressed as "you".
> > +
> > +  A "library" means a collection of software functions and/or data
> > +prepared so as to be conveniently linked with application programs
> > +(which use some of those functions and data) to form executables.
> > +
> > +  The "Library", below, refers to any such software library or work
> > +which has been distributed under these terms.  A "work based on the
> > +Library" means either the Library or any derivative work under
> > +copyright law: that is to say, a work containing the Library or a
> > +portion of it, either verbatim or with modifications and/or
translated
> > +straightforwardly into another language.  (Hereinafter, translation
is
> > +included without limitation in the term "modification".)
> > +
> > +  "Source code" for a work means the preferred form of the work for
> > +making modifications to it.  For a library, 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 library.
> > +
> > +  Activities other than copying, distribution and modification are
not
> > +covered by this License; they are outside its scope.  The act of
> > +running a program using the Library is not restricted, and output
from
> > +such a program is covered only if its contents constitute a work
based
> > +on the Library (independent of the use of the Library in a tool for
> > +writing it).  Whether that is true depends on what the Library does
> > +and what the program that uses the Library does.
> > +
> > +  1. You may copy and distribute verbatim copies of the Library's
> > +complete 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 distribute a copy of this License along with the
> > +Library.
> > +
> > +  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 Library or any
portion
> > +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
> > +
> > +    b) You must cause the files modified to carry prominent notices
> > +    stating that you changed the files and the date of any change.
> > +
> > +    c) You must cause the whole of the work to be licensed at no
> > +    charge to all third parties under the terms of this License.
> > +
> > +    d) If a facility in the modified Library refers to a function
or a
> > +    table of data to be supplied by an application program that
uses
> > +    the facility, other than as an argument passed when the
facility
> > +    is invoked, then you must make a good faith effort to ensure
that,
> > +    in the event an application does not supply such function or
> > +    table, the facility still operates, and performs whatever part
of
> > +    its purpose remains meaningful.
> > +
> > +    (For example, a function in a library to compute square roots
has
> > +    a purpose that is entirely well-defined independent of the
> > +    application.  Therefore, Subsection 2d requires that any
> > +    application-supplied function or table used by this function
must
> > +    be optional: if the application does not supply it, the square
> > +    root function must still compute square roots.)
> > +
> > +These requirements apply to the modified work as a whole.  If
> > +identifiable sections of that work are not derived from the
Library,
> > +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 Library, 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 Library.
> > +
> > +In addition, mere aggregation of another work not based on the
Library
> > +with the Library (or with a work based on the Library) on a volume
of
> > +a storage or distribution medium does not bring the other work
under
> > +the scope of this License.
> > +
> > +  3. You may opt to apply the terms of the ordinary GNU General
Public
> > +License instead of this License to a given copy of the Library.  To
do
> > +this, you must alter all the notices that refer to this License, so
> > +that they refer to the ordinary GNU General Public License, version
2,
> > +instead of to this License.  (If a newer version than version 2 of
the
> > +ordinary GNU General Public License has appeared, then you can
specify
> > +that version instead if you wish.)  Do not make any other change in
> > +these notices.
> > +
> 
> 
> > +  Once this change is made in a given copy, it is irreversible for
> > +that copy, so the ordinary GNU General Public License applies to
all
> > +subsequent copies and derivative works made from that copy.
> > +
> > +  This option is useful when you wish to copy part of the code of
> > +the Library into a program that is not a library.
> > +
> > +  4. You may copy and distribute the Library (or a portion or
> > +derivative of it, under Section 2) in object code or executable
form
> > +under the terms of Sections 1 and 2 above provided that you
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.
> > +
> > +  If distribution of 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 satisfies the requirement to
> > +distribute the source code, even though third parties are not
> > +compelled to copy the source along with the object code.
> > +
> > +  5. A program that contains no derivative of any portion of the
> > +Library, but is designed to work with the Library by being compiled
or
> > +linked with it, is called a "work that uses the Library".  Such a
> > +work, in isolation, is not a derivative work of the Library, and
> > +therefore falls outside the scope of this License.
> > +
> > +  However, linking a "work that uses the Library" with the Library
> > +creates an executable that is a derivative of the Library (because
it
> > +contains portions of the Library), rather than a "work that uses
the
> > +library".  The executable is therefore covered by this License.
> > +Section 6 states terms for distribution of such executables.
> > +
> > +  When a "work that uses the Library" uses material from a header
file
> > +that is part of the Library, the object code for the work may be a
> > +derivative work of the Library even though the source code is not.
> > +Whether this is true is especially significant if the work can be
> > +linked without the Library, or if the work is itself a library.
The
> > +threshold for this to be true is not precisely defined by law.
> > +
> > +  If such an object file uses only numerical parameters, data
> > +structure layouts and accessors, and small macros and small inline
> > +functions (ten lines or less in length), then the use of the object
> > +file is unrestricted, regardless of whether it is legally a
derivative
> > +work.  (Executables containing this object code plus portions of
the
> > +Library will still fall under Section 6.)
> > +
> > +  Otherwise, if the work is a derivative of the Library, you may
> > +distribute the object code for the work under the terms of Section
6.
> > +Any executables containing that work also fall under Section 6,
> > +whether or not they are linked directly with the Library itself.
> > +
> 
> 
> > +  6. As an exception to the Sections above, you may also combine or
> > +link a "work that uses the Library" with the Library to produce a
> > +work containing portions of the Library, and distribute that work
> > +under terms of your choice, provided that the terms permit
> > +modification of the work for the customer's own use and reverse
> > +engineering for debugging such modifications.
> > +
> > +  You must give prominent notice with each copy of the work that
the
> > +Library is used in it and that the Library and its use are covered
by
> > +this License.  You must supply a copy of this License.  If the work
> > +during execution displays copyright notices, you must include the
> > +copyright notice for the Library among them, as well as a reference
> > +directing the user to the copy of this License.  Also, you must do
one
> > +of these things:
> > +
> > +    a) Accompany the work with the complete corresponding
> > +    machine-readable source code for the Library including whatever
> > +    changes were used in the work (which must be distributed under
> > +    Sections 1 and 2 above); and, if the work is an executable
linked
> > +    with the Library, with the complete machine-readable "work that
> > +    uses the Library", as object code and/or source code, so that
the
> > +    user can modify the Library and then relink to produce a
modified
> > +    executable containing the modified Library.  (It is understood
> > +    that the user who changes the contents of definitions files in
the
> > +    Library will not necessarily be able to recompile the
application
> > +    to use the modified definitions.)
> > +
> > +    b) Use a suitable shared library mechanism for linking with the
> > +    Library.  A suitable mechanism is one that (1) uses at run time
a
> > +    copy of the library already present on the user's computer
system,
> > +    rather than copying library functions into the executable, and
(2)
> > +    will operate properly with a modified version of the library,
if
> > +    the user installs one, as long as the modified version is
> > +    interface-compatible with the version that the work was made
with.
> > +
> > +    c) Accompany the work with a written offer, valid for at
> > +    least three years, to give the same user the materials
> > +    specified in Subsection 6a, above, for a charge no more
> > +    than the cost of performing this distribution.
> > +
> > +    d) If distribution of the work is made by offering access to
copy
> > +    from a designated place, offer equivalent access to copy the
above
> > +    specified materials from the same place.
> > +
> > +    e) Verify that the user has already received a copy of these
> > +    materials or that you have already sent this user a copy.
> > +
> > +  For an executable, the required form of the "work that uses the
> > +Library" must include any data and utility programs needed for
> > +reproducing the executable from it.  However, as a special
exception,
> > +the materials to be 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.
> > +
> > +  It may happen that this requirement contradicts the license
> > +restrictions of other proprietary libraries that do not normally
> > +accompany the operating system.  Such a contradiction means you
cannot
> > +use both them and the Library together in an executable that you
> > +distribute.
> > +
> 
> 
> > +  7. You may place library facilities that are a work based on the
> > +Library side-by-side in a single library together with other
library
> > +facilities not covered by this License, and distribute such a
combined
> > +library, provided that the separate distribution of the work based
on
> > +the Library and of the other library facilities is otherwise
> > +permitted, and provided that you do these two things:
> > +
> > +    a) Accompany the combined library with a copy of the same work
> > +    based on the Library, uncombined with any other library
> > +    facilities.  This must be distributed under the terms of the
> > +    Sections above.
> > +
> > +    b) Give prominent notice with the combined library of the fact
> > +    that part of it is a work based on the Library, and explaining
> > +    where to find the accompanying uncombined form of the same
work.
> > +
> > +  8. You may not copy, modify, sublicense, link with, or distribute
> > +the Library except as expressly provided under this License.  Any
> > +attempt otherwise to copy, modify, sublicense, link with, or
> > +distribute the Library 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.
> > +
> > +  9. 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 Library or its derivative works.  These actions are
> > +prohibited by law if you do not accept this License.  Therefore, by
> > +modifying or distributing the Library (or any work based on the
> > +Library), you indicate your acceptance of this License to do so,
and
> > +all its terms and conditions for copying, distributing or modifying
> > +the Library or works based on it.
> > +
> > +  10. Each time you redistribute the Library (or any work based on
the
> > +Library), the recipient automatically receives a license from the
> > +original licensor to copy, distribute, link with or modify the
Library
> > +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
with
> > +this License.
> > +
> 
> 
> > +  11. 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 Library at all.  For example, if a patent
> > +license would not permit royalty-free redistribution of the Library
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 Library.
> > +
> > +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.
> > +
> > +  12. If the distribution and/or use of the Library is restricted
in
> > +certain countries either by patents or by copyrighted interfaces,
the
> > +original copyright holder who places the Library 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.
> > +
> > +  13. The Free Software Foundation may publish revised and/or new
> > +versions of the Lesser 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
Library
> > +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 Library does not specify a
> > +license version number, you may choose any version ever published
by
> > +the Free Software Foundation.
> > +
> 
> 
> > +  14. If you wish to incorporate parts of the Library into other
free
> > +programs whose distribution conditions are incompatible with these,
> > +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
> > +
> > +  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
> > +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE
LAW.
> > +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS
AND/OR
> > +OTHER PARTIES PROVIDE THE LIBRARY "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
> > +LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU
ASSUME
> > +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
> > +
> > +  16. 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 LIBRARY 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
> > +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
> > +
> > +  If you develop a new library, and you want it to be of the
greatest
> > +possible use to the public, we recommend making it free software
that
> > +everyone can redistribute and change.  You can do so by permitting
> > +redistribution under these terms (or, alternatively, under the
terms of
> the
> > +ordinary General Public License).
> > +
> > +  To apply these terms, attach the following notices to the
library.
> 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.
> > +
> > +    <one line to give the library's name and a brief idea of what
it
> does.>
> > +    Copyright (C) <year>  <name of author>
> > +
> > +    This library is free software; you can redistribute it and/or
> > +    modify it under the terms of the GNU Lesser General Public
> > +    License as published by the Free Software Foundation; either
> > +    version 2.1 of the License, or (at your option) any later
version.
> > +
> > +    This library 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
> > +    Lesser General Public License for more details.
> > +
> > +    You should have received a copy of the GNU Lesser General
Public
> > +    License along with this library; if not, write to the Free
Software
> > +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
02110-
> 1301  USA
> > +
> > +Also add information on how to contact you by electronic and paper
> mail.
> > +
> > +You should also get your employer (if you work as a programmer) or
your
> > +school, if any, to sign a "copyright disclaimer" for the library,
if
> > +necessary.  Here is a sample; alter the names:
> > +
> > +  Yoyodyne, Inc., hereby disclaims all copyright interest in the
> > +  library `Frob' (a library for tweaking knobs) written by James
Random
> Hacker.
> > +
> > +  <signature of Ty Coon>, 1 April 1990
> > +  Ty Coon, President of Vice
> > +
> > +That's all there is to it!
> > +
> > +
> > diff --git a/refpol_ilc/Makefile b/refpol_ilc/Makefile
> > new file mode 100644
> > index 0000000..f6cdb14
> > --- /dev/null
> > +++ b/refpol_ilc/Makefile
> > @@ -0,0 +1,24 @@
> > +PREFIX ?= $(DESTDIR)/usr
> > +BINDIR ?= $(PREFIX)/bin
> > +
> > +PYTHON ?= python
> > +
> > +ifneq ($(origin DESTDIR), undefined)
> > +	PYDESTDIR ?= --root=$(DESTDIR)
> > +endif
> > +
> > +TARGET = refpol_ilc.py
> > +
> > +all:
> > +	$(PYTHON) setup.py build
> > +
> > +install:
> > +	$(PYTHON) setup.py install $(PYDESTDIR)
> > +	-mkdir -p $(BINDIR)
> > +	install -m 755 $(TARGET) $(BINDIR)/$(TARGET:.py=)
> > +
> > +clean distclean:
> > +	$(PYTHON) setup.py clean
> > +	rm -fr build
> > +	rm -f refpol_ilc/*.pyc
> > +
> > diff --git a/refpol_ilc/refpol_ilc.py b/refpol_ilc/refpol_ilc.py
> > new file mode 100755
> > index 0000000..31021b4
> > --- /dev/null
> > +++ b/refpol_ilc/refpol_ilc.py
> > @@ -0,0 +1,17 @@
> > +#!/usr/bin/python
> > +
> > +# Authors:	Caleb Case <ccase@tresys.com>
> > +#
> > +# Copyright (C) 2009-2010 Tresys Technology, LLC
> > +#      This program is free software; you can redistribute it
and/or
> modify
> > +#      it under the terms of the Lesser GNU General Public License
as
> > +#      published by the Free Software Foundation, version 2.
> > +
> > +import refpol_ilc.refpol_ilc
> > +import sys
> > +
> > +try:
> > +	refpol_ilc.refpol_ilc.main()
> > +except Exception as e:
> > +	sys.stderr.write(sys.argv[0] + ": Error: " + str(e) + "\n")
> > +	sys.exit(1)
> > diff --git a/refpol_ilc/refpol_ilc/__init__.py
> b/refpol_ilc/refpol_ilc/__init__.py
> > new file mode 100644
> > index 0000000..e69de29
> > diff --git a/refpol_ilc/refpol_ilc/refpol_ilc.py
> b/refpol_ilc/refpol_ilc/refpol_ilc.py
> > new file mode 100644
> > index 0000000..7e5430e
> > --- /dev/null
> > +++ b/refpol_ilc/refpol_ilc/refpol_ilc.py
> > @@ -0,0 +1,193 @@
> > +#!/usr/bin/python
> > +
> > +# Authors:	Caleb Case <ccase@tresys.com>
> > +#
> > +# Copyright (C) 2009-2010 Tresys Technology, LLC
> > +#      This program is free software; you can redistribute it
and/or
> modify
> > +#      it under the terms of the Lesser GNU General Public License
as
> > +#      published by the Free Software Foundation, version 2.
> > +
> > +from optparse import OptionParser, OptionGroup
> > +import os
> > +import os.path
> > +import tempfile
> > +from refpol import refpol
> > +from refpol import refpolicy2refpol
> > +import shutil
> > +import subprocess
> > +import sys
> > +
> > +build_directory = "/usr/share/selinux/refpol_ilc/build"
> > +
> > +# setup PATH (for gcc) if missing
> > +if not "PATH" in os.environ:
> > +	os.environ["PATH"] = "/bin:/usr/bin"
> > +
> > +def to_bool(str):
> > +	return 	{
> > +			"true"	: True,
> > +			"t"	: True,
> > +			"1"	: True,
> > +			"false"	: False,
> > +			"f"	: False,
> > +			"0"	: False,
> > +		}[str.lower()]
> > +
> > +usage = "%prog [OPTIONS] MODULE MODULE ..."
> > +version = "%prog 1.0"
> > +
> > +def main():
> > +	def disabled(option, opt_str, value, parser, *args, **kwargs):
> > +		parser.values.disabled.append(value)
> > +
> > +	# create cmdline parser
> > +	parser = OptionParser(usage = usage, version = version)
> > +	parser.add_option("-d", "--disabled", action = "callback",
callback
> = disabled, type = "string", default = [], dest = "disabled", help =
> "indicates module is disabled", metavar = "FILE")
> > +	parser.add_option("-f", "--force", action = "store_true",
default =
> False, dest = "force", help = "force overwriting existing files")
> > +	parser.add_option("-t", "--tmp", action = "store", default =
None,
> dest = "tmp", help = "temporary build directory", metavar = "DIR")
> > +	parser.add_option("-b", "--build-template", action = "store",
> default = build_directory, dest = "build_template", help = "build
template
> directory (Default: %s)" % build_directory, metavar = "DIR")
> > +	parser.add_option("-o", "--output", action = "store", default =
> None, dest = "output", help = "output file", metavar = "FILE")
> > +	parser.add_option("-c", "--cleanup", action = "store", default =
> "True", dest = "cleanup", help = "cleanup (remove) temporary directory
> (Default: True)", metavar = "BOOL")
> > +
> > +	# parse cmdline
> > +	(options, args) = parser.parse_args()
> > +	if len(args) <= 0:
> > +		parser.error("Invalid number of arguments %d." %
len(args))
> > +
> > +	# save the working directory
> > +	saved_cwd = os.getcwd()
> > +
> > +	force = options.force
> > +	refpol.force = options.force
> > +	refpolicy2refpol.force = options.force
> > +
> > +	if options.output is None:
> > +		options.output = sys.stdout
> > +	else:
> > +		refpol.file_exists(options.output)
> > +		options.output = open(options.output, "w")
> > +
> > +	try:
> > +		if not options.tmp:
> > +			# create tmp build dir if one isn't provided
> > +			options.tmp = tempfile.mkdtemp("-refpol_ilc")
> > +		else:
> > +			shutil.rmtree(options.tmp, ignore_errors = True)
> > +			os.mkdir(options.tmp)
> > +
> > +		# copy build dir template
> > +		build_root = options.tmp + "/build"
> > +		shutil.copytree(options.build_template, build_root)
> > +
> > +		# set default policy TYPE
> > +		type = "standard"
> > +
> > +		# copy modules into build dir
> > +		special_names = dict(zip(["_" +
> os.path.basename(i).rsplit('.', 1)[0] for i in
> refpolicy2refpol.specials("")],
refpolicy2refpol.specials(build_root)))
> > +		disabled_names = [os.path.basename(os.path.dirname(i))
for i
> in options.disabled]
> > +
> > +		all_modules = []
> > +		all_modules.extend(args)
> > +		all_modules.extend(options.disabled)
> > +		for path in all_modules:
> > +			module_name =
os.path.basename(os.path.dirname(path))
> > +
> > +			if module_name in special_names and not
module_name in
> disabled_names:
> > +				if module_name == "_mls":
> > +					type = "mls"
> > +				elif module_name == "_mcs" and type !=
"mls":
> > +					type = "mcs"
> > +
> > +				# copy to special location
> > +				with open(path, "r") as input:
> > +					with
open(special_names[module_name], "w")
> as output:
> > +						for line in input:
> > +							# remove
policy_module statement
> > +							if not
> line.strip().startswith("policy_module"):
> > +
output.write(line)
> > +			elif module_name == "_defines":
> > +				shutil.copy(path, build_root +
"/_defines.ref")
> > +			else:
> > +				# copy module to policy/kernel/
> > +				dest_ref = build_root +
"/policy/modules/kernel/"
> + module_name + ".ref"
> > +				dest_name = build_root +
"/policy/modules/kernel/"
> + module_name
> > +				shutil.copy(path, dest_ref)
> > +
> > +				refpol.ref_to_itf(dest_ref, dest_name +
".if",
> dest_name + ".te", dest_name + ".fc")
> > +
> > +		os.chdir(build_root)
> > +
> > +		# compose build.conf (build.conf.in from _defines.ref)
> > +		with open("_defines.ref", "r") as input:
> > +			with open("build.conf", "w") as output:
> > +				# write out the type
> > +				output.write("TYPE = %s\n\n" % type)
> > +
> > +				# write out monolithic
> > +				output.write("MONOLITHIC = n\n\n")
> > +
> > +				for line in input:
> > +					# remove policy_module statement
> > +					if not
> line.strip().startswith("policy_module"):
> > +						output.write(line)
> > +
> > +		# make conf
> > +		p = subprocess.Popen("make conf", shell = True, stdout =
> subprocess.PIPE, stderr = subprocess.PIPE, close_fds = True)
> > +
> > +		(stdout, stderr) = p.communicate()
> > +		sys.stderr.write(stdout)
> > +		sys.stderr.write(stderr)
> > +
> > +		if p.returncode != 0:
> > +			raise Exception("Failed to run make conf (%d)."
%
> p.returncode)
> > +
> > +		# sed modules.conf to base module if enabled
> > +		sed_cmd = "sed -i '1,/^END/{ s/= module/= base/; "
> > +		disabled_len = len(options.disabled)
> > +		if disabled_len > 0:
> > +			sed_cmd = sed_cmd + "s/\\("
> > +			i = 0
> > +			for d in options.disabled:
> > +				i = i + 1
> > +				sed_cmd = sed_cmd +
> os.path.basename(os.path.dirname(d))
> > +				if i != disabled_len:
> > +					sed_cmd = sed_cmd + "\\|"
> > +			sed_cmd = sed_cmd + "\\) = base/\\1 = off/ "
> > +		sed_cmd = sed_cmd + "}' policy/modules.conf"
> > +
> > +		p = subprocess.Popen(sed_cmd, shell = True, stdout =
> subprocess.PIPE, stderr = subprocess.PIPE, close_fds = True)
> > +
> > +		(stdout, stderr) = p.communicate()
> > +		sys.stderr.write(stdout)
> > +		sys.stderr.write(stderr)
> > +
> > +		if p.returncode != 0:
> > +			raise Exception("Failed to modify modules.conf
(%d)." %
> p.returncode)
> > +
> > +		# make base module
> > +		p = subprocess.Popen("make base.pp", shell = True,
stdout =
> subprocess.PIPE, stderr = subprocess.PIPE, close_fds = True)
> > +
> > +		(stdout, stderr) = p.communicate()
> > +		sys.stderr.write(stdout)
> > +		sys.stderr.write(stderr)
> > +
> > +		if p.returncode != 0:
> > +			raise Exception("Failed to run make base.pp
(%d)." %
> p.returncode)
> > +
> > +		# output base module
> > +		options.output.write(open("base.pp", "r").read())
> > +	finally:
> > +		if to_bool(options.cleanup):
> > +			shutil.rmtree(options.tmp)
> > +
> > +		options.output.close()
> > +
> > +		# return the saved directory
> > +		os.chdir(saved_cwd)
> > +
> > +if __name__ == '__main__':
> > +	try:
> > +		main()
> > +	except Exception as e:
> > +		sys.stderr.write(sys.argv[0] + ": Error: " + str(e) +
"\n")
> > +		sys.exit(1)
> > diff --git a/refpol_ilc/setup.py b/refpol_ilc/setup.py
> > new file mode 100755
> > index 0000000..31c3a14
> > --- /dev/null
> > +++ b/refpol_ilc/setup.py
> > @@ -0,0 +1,13 @@
> > +#!/usr/bin/python
> > +
> > +from distutils.core import setup
> > +
> > +setup(	name		= "refpol_ilc",
> > +	version		= "0.1",
> > +	description	= "Refpol Intermediate Language Compiler",
> > +#	url		= "",
> > +	author		= "Caleb Case",
> > +	author_email	= "ccase@tresys.com",
> > +	license		= "LGPL v2.1",
> > +	packages	= ['refpol_ilc'],
> > +	)
> 
> --
> James Carter <jwcart2@tycho.nsa.gov>
> National Security Agency



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2010-02-01 17:43 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-26 22:08 [PATCH 00/15] RFC Source Policy Support Caleb Case
2010-01-26 22:08 ` [PATCH 01/15] [src-policy] refpol language and tools Caleb Case
2010-01-26 22:08   ` [PATCH 02/15] [src-policy] corenet " Caleb Case
2010-01-26 22:08     ` [PATCH 03/15] [src-policy] Reference Policy to refpol conversion tool Caleb Case
2010-01-26 22:08       ` [PATCH 04/15] [src-policy] refpol intermediate language compiler (refpol_ilc) Caleb Case
2010-01-26 22:08         ` [PATCH 05/15] [src-policy] language.d and language.conf parser Caleb Case
2010-01-26 22:08           ` [PATCH 06/15] [src-policy] libsemanage: compile hll module Caleb Case
2010-01-26 22:08             ` [PATCH 07/15] [src-policy] libsemanage: compile common intermediary language Caleb Case
2010-01-26 22:08               ` [PATCH 08/15] [src-policy] libsemanage: remove binary interfaces Caleb Case
2010-01-26 22:08                 ` [PATCH 09/15] [src-policy] semodule: remove base module support Caleb Case
2010-01-26 22:08                   ` [PATCH 10/15] [src-policy] libsemanage: get source module Caleb Case
2010-01-26 22:08                     ` [PATCH 11/15] [src-policy] semodule: get module source Caleb Case
2010-01-26 22:08                       ` [PATCH 12/15] [src-policy] semodule: edit module Caleb Case
2010-01-26 22:08                         ` [PATCH 13/15] [src-policy] libsemanage: ChangeLog support Caleb Case
2010-01-26 22:08                           ` [PATCH 14/15] [src-policy] semodule: user message support Caleb Case
2010-01-26 22:08                             ` [PATCH 15/15] [src-policy] semanage: source permissive module Caleb Case
2010-02-01 15:11                             ` [PATCH 14/15] [src-policy] semodule: user message support James Carter
2010-02-01 17:00                               ` Caleb Case
2010-02-01 17:06                                 ` James Carter
2010-01-27 20:21                         ` [PATCH 12/15] [src-policy] semodule: edit module Stephen Smalley
2010-01-28 20:52                       ` [PATCH 11/15] [src-policy] semodule: get module source James Carter
2010-01-29 20:32                 ` [PATCH 08/15] [src-policy] libsemanage: remove binary interfaces James Carter
2010-01-27 20:18             ` [PATCH 06/15] [src-policy] libsemanage: compile hll module Stephen Smalley
2010-01-27 20:42               ` Caleb Case
2010-01-27 20:46               ` Caleb Case
2010-01-28 21:03         ` [PATCH 04/15] [src-policy] refpol intermediate language compiler (refpol_ilc) James Carter
2010-02-01 17:43           ` Caleb Case
2010-01-27 19:39   ` [PATCH 01/15] [src-policy] refpol language and tools Stephen Smalley
2010-01-27 19:54     ` Caleb Case
2010-01-26 22:41 ` [PATCH 00/15] RFC Source Policy Support Xavier Toth
2010-01-27  1:17   ` Caleb Case
2010-01-27 15:10     ` Xavier Toth
2010-01-27 20:00 ` Stephen Smalley
2010-01-27 20:18   ` Caleb Case

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.