From mboxrd@z Thu Jan  1 00:00:00 1970
Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org)
	by finch.gentoo.org with esmtp (Exim 4.60)
	(envelope-from <gentoo-commits+bounces-338282-garchives=archives.gentoo.org@lists.gentoo.org>)
	id 1QDb7X-0006AQ-Fc
	for garchives@archives.gentoo.org; Sat, 23 Apr 2011 11:35:34 +0000
Received: from pigeon.gentoo.org (localhost [127.0.0.1])
	by pigeon.gentoo.org (Postfix) with SMTP id B1C4A1C019;
	Sat, 23 Apr 2011 11:35:19 +0000 (UTC)
Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183])
	by pigeon.gentoo.org (Postfix) with ESMTP id 326FB1C019
	for <gentoo-commits@lists.gentoo.org>; Sat, 23 Apr 2011 11:35:19 +0000 (UTC)
Received: from pelican.gentoo.org (unknown [66.219.59.40])
	(using TLSv1 with cipher ADH-CAMELLIA256-SHA (256/256 bits))
	(No client certificate requested)
	by smtp.gentoo.org (Postfix) with ESMTPS id 615A51B4017
	for <gentoo-commits@lists.gentoo.org>; Sat, 23 Apr 2011 11:35:18 +0000 (UTC)
Received: from localhost.localdomain (localhost [127.0.0.1])
	by pelican.gentoo.org (Postfix) with ESMTP id C90D18034E
	for <gentoo-commits@lists.gentoo.org>; Sat, 23 Apr 2011 11:35:17 +0000 (UTC)
From: "Sven Vermeulen" <sven.vermeulen@siphos.be>
To: gentoo-commits@lists.gentoo.org
Content-type: text/plain; charset=UTF-8
Reply-To: gentoo-dev@lists.gentoo.org, "Sven Vermeulen" <sven.vermeulen@siphos.be>
Message-ID: <bdb128145f81f05f094fb220d4df1a1768458779.SwifT@gentoo>
Subject: [gentoo-commits] proj/hardened-docs:master commit in: html/
X-VCS-Repository: proj/hardened-docs
X-VCS-Files: html/selinux-development.html
X-VCS-Directories: html/
X-VCS-Committer: SwifT
X-VCS-Committer-Name: Sven Vermeulen
X-VCS-Revision: bdb128145f81f05f094fb220d4df1a1768458779
Date: Sat, 23 Apr 2011 11:35:17 +0000 (UTC)
Precedence: bulk
List-Post: <mailto:gentoo-commits@lists.gentoo.org>
List-Help: <mailto:gentoo-commits+help@lists.gentoo.org>
List-Unsubscribe: <mailto:gentoo-commits+unsubscribe@lists.gentoo.org>
List-Subscribe: <mailto:gentoo-commits+subscribe@lists.gentoo.org>
List-Id: Gentoo Linux mail <gentoo-commits.gentoo.org>
X-BeenThere: gentoo-commits@lists.gentoo.org
Content-Transfer-Encoding: quoted-printable
X-Archives-Salt: 
X-Archives-Hash: 320a4e6574162eb37fb40358ec906a0c

commit:     bdb128145f81f05f094fb220d4df1a1768458779
Author:     Sven Vermeulen <sven.vermeulen <AT> siphos <DOT> be>
AuthorDate: Sat Apr 23 11:32:27 2011 +0000
Commit:     Sven Vermeulen <sven.vermeulen <AT> siphos <DOT> be>
CommitDate: Sat Apr 23 11:32:27 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=3Dproj/hardened-docs=
.git;a=3Dcommit;h=3Dbdb12814

update previews

---
 html/selinux-development.html |  654 +++++++++++++++++++++++++++++++++++=
+++---
 1 files changed, 618 insertions(+), 36 deletions(-)

diff --git a/html/selinux-development.html b/html/selinux-development.htm=
l
index 72f7a56..9767824 100644
--- a/html/selinux-development.html
+++ b/html/selinux-development.html
@@ -97,6 +97,12 @@ highlights...
     <span class=3D"emphasis">interface file</span> which can then be cal=
led by other modules. This
     includes the necessary permissions to allow domain transitions
   </li>
+  <li>
+    SELinux uses attributes to make multiple domains manageable. Domains=
 can
+    have certain permissions against all domains or types that are given=
 a
+    particular attribute. Be aware of this when you start assigning attr=
ibutes
+    to your own types or domains.
+  </li>
 </ul>
 <p class=3D"chaphead"><a name=3D"doc_chap2"></a><span class=3D"chapnum">=
2.
             </span>Setting Up Your Environment</p>
@@ -209,14 +215,14 @@ one:
 <a name=3D"doc_chap2_pre4"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
 <tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing2.4: Sett=
ing up a local workspace</p></td></tr>
 <tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
-~$ <span class=3D"code-input">mkdir dev/local</span>
-~$ <span class=3D"code-input">cp -r dev/hardened/strict dev/local/</span=
>
+~$ <span class=3D"code-input">cd dev/hardened</span>
+~$ <span class=3D"code-input">cp -r strict strict.local/</span>
 </pre></td></tr>
 </table>
 <p class=3D"secthead"><a name=3D"doc_chap2_sect4">Navigating the policy =
workspace</a></p>
 <p>
 The main location you will work with is
-<span class=3D"path" dir=3D"ltr">dev/local/strict/policy/modules</span>.=
 This location is subdivided in
+<span class=3D"path" dir=3D"ltr">dev/hardened/strict.local/policy/module=
s</span>. This location is subdivided in
 categories:
 </p>
 <dl>
@@ -244,7 +250,7 @@ Inside the categories, the modules are available usin=
g their three files
 <a name=3D"doc_chap2_pre5"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
 <tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing2.5: List=
ing the available sudo files</p></td></tr>
 <tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
-~$ <span class=3D"code-input">cd dev/local/strict/policy/modules/admin</=
span>
+~$ <span class=3D"code-input">cd dev/hardened/strict.local/policy/module=
s/admin</span>
 ~$ <span class=3D"code-input">ls sudo.*</span>
 sudo.fc    sudo.if     sudo.te
 </pre></td></tr>
@@ -257,7 +263,7 @@ To build a module, go to the location where the modul=
e code is. Then, run
 <a name=3D"doc_chap2_pre6"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
 <tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing2.6: Buil=
ding the portage module</p></td></tr>
 <tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
-~$ <span class=3D"code-input">cd dev/local/strict/policy/modules/admin</=
span>
+~$ <span class=3D"code-input">cd dev/hardened/strict.local/policy/module=
s/admin</span>
 ~$ <span class=3D"code-input">make -f ../../../support/Makefile.devel po=
rtage.pp</span>
 </pre></td></tr>
 </table>
@@ -272,7 +278,7 @@ If you want to build the base policy, run <span class=
=3D"code" dir=3D"ltr">make base
 <a name=3D"doc_chap2_pre7"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
 <tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing2.7: Buil=
ding the base policy</p></td></tr>
 <tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
-~$ <span class=3D"code-input">cd dev/local/strict</span>
+~$ <span class=3D"code-input">cd dev/hardened/strict.local</span>
 ~$ <span class=3D"code-input">make base</span>
 </pre></td></tr>
 </table>
@@ -406,7 +412,9 @@ find the AVC denials you are looking for.
 <p>
 The next step is to see if we are dealing with the right security contex=
ts. This
 does require a bit of insight in how both the application (that is faili=
ng) and
-the policy relate to each other.
+the policy relate to each other. In essence, you want to make sure that =
the
+process is running in the right domain and is trying to work on the righ=
t target
+type.
 </p>
 <p>
 Say you are having issues with SELinux (re)labeling and you notice the f=
ollowing
@@ -557,7 +565,7 @@ creating an additional domain or type can be benefici=
al.
 <p>
 A noticeable example is Portage' support for CVS/SVN/GIT ebuilds (the so=
-called
 live ebuilds). These ebuilds get their repository and store it in the
-<span class=3D"path" dir=3D"ltr">distfiles/svn+src</span> location, whic=
h was by default labelled
+<span class=3D"path" dir=3D"ltr">distfiles/svn+src</span> location, whic=
h was by default labeled
 <span class=3D"path" dir=3D"ltr">portage_ebuild_t</span> with only read-=
access for the
 <span class=3D"path" dir=3D"ltr">portage_sandbox_t</span> domain. Howeve=
r, with those live ebuilds, the
 <span class=3D"path" dir=3D"ltr">portage_sandbox_t</span> domain also ne=
eds write privileges to this
@@ -573,67 +581,641 @@ need to create the proper interface functions in t=
he target domain and call
 these functions from the source domain.
 </p>
 <p>
-TODO extend this explanation, use a common example, like mysql_stream_co=
nnect in
-postfix.
+Interface functions are the APIs that a module provides towards other SE=
Linux
+modules when they need to interact with the domains. For instance, the
+<span class=3D"path" dir=3D"ltr">mysql</span> module provides, amongst o=
ther functions, the
+<span class=3D"code" dir=3D"ltr">mysql_stream_connect</span> interface:
+</p>
+<a name=3D"doc_chap3_pre12"></a><table class=3D"ntable" width=3D"100%" c=
ellspacing=3D"0" cellpadding=3D"0" border=3D"0">
+<tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing3.12: mys=
ql_stream_connect interface</p></td></tr>
+<tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
+########################################
+## &lt;summary&gt;
+##      Connect to MySQL using a unix domain stream socket.
+## &lt;/summary&gt;
+## &lt;param name=3D"domain"&gt;
+##      &lt;summary&gt;
+##      Domain allowed access.
+##      &lt;/summary&gt;
+## &lt;/param&gt;
+## &lt;rolecap/&gt;
+#
+interface(`mysql_stream_connect',`
+        gen_require(`
+                type mysqld_t, mysqld_var_run_t, mysqld_db_t;
+        ')
+
+        stream_connect_pattern($1, mysqld_var_run_t, mysqld_var_run_t, m=
ysqld_t)
+        stream_connect_pattern($1, mysqld_db_t, mysqld_var_run_t, mysqld=
_t)
+')
+</pre></td></tr>
+</table>
+<p>
+The interface declares that the domain passed on as its first (and only)
+argument gets the rights offered by <span class=3D"code" dir=3D"ltr">str=
eam_connect_pattern</span>, which is a
+macro (defined in <span class=3D"path" dir=3D"ltr">policy/support/ipc_pa=
tterns.spt</span> that looks like
+so:
+</p>
+<a name=3D"doc_chap3_pre13"></a><table class=3D"ntable" width=3D"100%" c=
ellspacing=3D"0" cellpadding=3D"0" border=3D"0">
+<tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing3.13: str=
eam_connect_pattern</p></td></tr>
+<tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
+define(`stream_connect_pattern',`
+        allow $1 $2:dir search_dir_perms;
+        allow $1 $3:sock_file write_sock_file_perms;
+        allow $1 $4:unix_stream_socket connectto;
+')
+</pre></td></tr>
+</table>
+<p>
+Modules that need to interact with MySQL through a Unix domain stream so=
cket
+(<span class=3D"path" dir=3D"ltr">/var/run/mysqld/mysqld.sock</span>) wi=
ll need the proper permissions to
+work with the target type (<span class=3D"path" dir=3D"ltr">mysqld_var_r=
un_t</span>). Modules cannot just
+set <span class=3D"emphasis">allow</span> statements towards <span class=
=3D"path" dir=3D"ltr">mysqld_var_run_t</span> as they do not
+know this type. Instead, they call the <span class=3D"code" dir=3D"ltr">=
mysql_stream_connect</span> interface,
+like the <span class=3D"path" dir=3D"ltr">postfix.te</span> file does:
 </p>
+<a name=3D"doc_chap3_pre14"></a><table class=3D"ntable" width=3D"100%" c=
ellspacing=3D"0" cellpadding=3D"0" border=3D"0">
+<tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing3.14: Pos=
tfix module calling mysql_stream_connect</p></td></tr>
+<tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
+optional_policy(`
+        mysql_stream_connect(postfix_master_t)
+        mysql_stream_connect(postfix_cleanup_t)
+        mysql_stream_connect(postfix_local_t)
+')
+</pre></td></tr>
+</table>
 <p>
-TODO explain that changes in the interface require rebuilds and reinstal=
lations
-of the base (package, not only .pp file, due to includes). tell that thi=
s is the
-reason why selinux-base-policy has that many revisions.
+If the change you need is adding existing interface calls to the module =
(in=20
+the <span class=3D"path" dir=3D"ltr">.te</span> file) then you should be=
 able to test it easily by building
+the changed module and loading it. However, if you need to change the in=
terface
+of your module itself (in the <span class=3D"path" dir=3D"ltr">.if</span=
> file) you will eventually need
+to rebuild the base policy and even provide and install a new
+<span class=3D"path" dir=3D"ltr">sec-policy/selinux-base-policy</span> p=
ackage as the interfaces are placed
+in <span class=3D"path" dir=3D"ltr">/usr/share/selinux/strict/include</s=
pan>. This is one of the reasons
+why the <span class=3D"path" dir=3D"ltr">sec-policy/selinux-base-policy<=
/span> package in Gentoo Hardened
+has a high revision number (and many updates).
 </p>
 <p class=3D"chaphead"><a name=3D"doc_chap4"></a><span class=3D"chapnum">=
4.
             </span>No Domain Exists (Yet)</p>
 <p class=3D"secthead"><a name=3D"doc_chap4_sect1">Reuse existing domains=
</a></p>
 <p>
-TODO talk about potentially reusing domains (like apache module providin=
g the
-various httpd_* domains which can be reused by lighttpd). Talk about ass=
igning
-the proper labels to the files to see if that is sufficient.
+If you are facing problems because you run an application which has no d=
omain
+itself (and hence is probably running in the <span class=3D"path" dir=3D=
"ltr">user_t</span>,
+<span class=3D"path" dir=3D"ltr">staff_t</span> or <span class=3D"path" =
dir=3D"ltr">sysadm_t</span> domains - or even tries to run in
+the <span class=3D"path" dir=3D"ltr">initrc_t</span> domain), you will n=
eed to create one. But before we do
+that, it might be possible that the application can work within the doma=
in
+definition of a different application.
 </p>
-<p class=3D"secthead"><a name=3D"doc_chap4_sect2">Copy from existing dom=
ains</a></p>
 <p>
-TODO talk about finding a similar module (apps or service) and start fro=
m a
-(slimmed-down) domain. Not recommended as it might already open too much=
, but it
-is a good start, if not to just look at with every denial you get later.=
 Keep it
-short, most information is in next section.
+One example here is lighttpd. This lightweight HTTPd service "uses" the
+definitions offered by the <span class=3D"path" dir=3D"ltr">apache</span=
> module. By marking its executable
+file <span class=3D"path" dir=3D"ltr">httpd_exec_t</span> it runs in the=
 <span class=3D"path" dir=3D"ltr">httpd_t</span> domain and
+uses the same policy like Apache. By labeling the files according to the
+<span class=3D"path" dir=3D"ltr">apache.fc</span> definitions (but now f=
or lighttpd) it might Just Work
+=E2=84=A2
+</p>
+<p>
+Reusing existing domains requires that you at least consider the followi=
ng
+aspects:
+</p>
+<ul>
+  <li>
+    Will the application run on the same system as the application for w=
hich the
+    domain is originally intended? If so, then both might run in the sam=
e domain
+    (and as such have more privileges towards each other than intended) =
which
+    might not be what you want.
+  </li>
+  <li>
+    Do you need to enhance (read: add additional privileges) the master =
domain?
+    If so, make sure that you don't add more privileges than the origina=
l domain
+    would ever need to the extend that these privileges become a securit=
y risk.
+  </li>
+</ul>
+<p class=3D"secthead"><a name=3D"doc_chap4_sect2">(Do Not) Copy from exi=
sting domains</a></p>
+<p>
+If reusing existing domains introduces too many risks, you'll need to cr=
eate a
+new domain for the application. Many people would be inclined to copy th=
e domain
+definition of a similar application and work from there. Although this i=
s a
+viable approach, it is considered a bad practice because you start by pr=
oviding
+privileges to the domain that are never needed, and removing privileges =
from a
+domain later is very difficult. Even more, if you are not the author of =
the
+modules, most developers will not even try to remove them as they assume=
 that
+the author of the domain had a good reason to add it in the first place.=
 This is
+one of the reasons why upstream takes great care in accepting patches - =
they
+must be properly documented before they are accepted.
+</p>
+<p>
+Instead, create a domain from scratch but take a close eye on the domain=
 you
+belief is very similar. Issues that arise during the module development =
might be
+quickly resolved by looking at how the original domain is defined.
 </p>
 <p class=3D"secthead"><a name=3D"doc_chap4_sect3">Starting from scratch<=
/a></p>
 <p>
-TODO talk about defining the proper domains, set proper types (like file=
_type or
-application_type), refer to refpolicy guidelines
+To start the development of a new module from scratch, first identify th=
e
+domain(s) you want to have. An application that, in its entire lifespan =
only
+constitutes of a single process, will most likely only have one domain. =
For
+instance, the Skype client will have just <span class=3D"path" dir=3D"lt=
r">skype_t</span>. However,
+applications that have multiple processes running might need multiple do=
mains
+too. For instance, the Postfix application runs a master
+(<span class=3D"path" dir=3D"ltr">postfix_master_t</span>), queue manage=
r (<span class=3D"path" dir=3D"ltr">postfix_qmgr_t</span>) and
+pickup service (<span class=3D"path" dir=3D"ltr">postfix_pickup_t</span>=
), but depending on the commands
+you execute, it will also have (short-lived) processes running as
+<span class=3D"path" dir=3D"ltr">postfix_cleanup_t</span>, <span class=3D=
"path" dir=3D"ltr">postfix_bounce_t</span>, etc.) It is
+considered a best practice to start with a fine-grained model for domain=
s
+and only later decide if merging multiple domains into one is beneficial=
.
+Splitting domains later is more difficult. Don't forget to look at the
+client-side aspect too!
+</p>
+<p>
+Next, define the types that each domain interacts with. This of course i=
ncludes
+the binary (like <span class=3D"path" dir=3D"ltr">skype_exec_t</span>) b=
ut do not forget resources like
+</p>
+<ul>
+  <li>
+    The configuration file(s) in <span class=3D"path" dir=3D"ltr">/etc</=
span> (f.i.
+    <span class=3D"path" dir=3D"ltr">postfix_etc_t</span>)
+  </li>
+  <li>
+    PID files (f.i. <span class=3D"path" dir=3D"ltr">sshd_var_run_t</spa=
n>)
+  </li>
+  <li>
+    Spool files (f.i. <span class=3D"path" dir=3D"ltr">postfix_spool_t</=
span>)
+  </li>
+  <li>
+    Variable data files (f.i. <span class=3D"path" dir=3D"ltr">snmpd_var=
_lib_t</span>)
+  </li>
+  <li>
+    Log files (f.i. <span class=3D"path" dir=3D"ltr">zebra_log_t</span>)
+  </li>
+  <li>
+    Cache files (f.i. <span class=3D"path" dir=3D"ltr">squid_cache_t</sp=
an>)
+  </li>
+  <li>
+    (User) content files (f.i. <span class=3D"path" dir=3D"ltr">httpd_sy=
s_content_t</span> and
+    <span class=3D"path" dir=3D"ltr">httpd_user_content_t</span>)
+  </li>
+</ul>
+<p>
+Also, try to separate types that are used by other domains as well. This=
 way,
+the other domains can only interact with those files or resources that a=
re
+labeled accordingly, rather than interact with a broad spectrum of files=
. The
+distinction that the <span class=3D"path" dir=3D"ltr">apache</span> modu=
le makes between system-provided
+content (like phpmyadmin files) and user-provided content (in the
+<span class=3D"path" dir=3D"ltr">public_html</span> directory in the use=
rs' home directories) seems (and
+is) very logical, but one could wrongly say that for Apache itself, the =
access
+controls are the same. Although that might be true, both types are clear=
ly used
+in different ways so this mandates the use of different domains.
+</p>
+<p>
+Once you have defined those types too, start writing down the intra-doma=
in
+permissions. Right now is a good time to look at other modules to see ho=
w they
+do things. Start with defining the accesses towards the domains.
+</p>
+<a name=3D"doc_chap4_pre1"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
+<tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing4.1: Snip=
pet from the spamassassin module</p></td></tr>
+<tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
+type spamassassin_t;
+type spamassassin_exec_t;
+application_domain(spamassassin_t, spamassassin_exec_t)
+ubac_constrained(spamassassin_t)
+</pre></td></tr>
+</table>
+<p>
+This small snippet defines many things. The first two lines just mention=
 the new
+types (the <span class=3D"path" dir=3D"ltr">spamassassin_t</span> domain=
 and
+<span class=3D"path" dir=3D"ltr">spamassassin_exec_t</span> type). The <=
span class=3D"code" dir=3D"ltr">application_domain</span> interface
+marks <span class=3D"path" dir=3D"ltr">spamassassin_t</span> as an appli=
cation domain type (it gets the
+<span class=3D"path" dir=3D"ltr">application_domain_type</span> and <spa=
n class=3D"path" dir=3D"ltr">domain</span> attributes and a
+few default permissions (like allowing that it sends SIGCHLD and SIGNULL=
 to
+init). It also marks <span class=3D"path" dir=3D"ltr">spamassassin_exec_=
t</span> as an applications'
+executable type (<span class=3D"path" dir=3D"ltr">application_exec_type<=
/span> and <span class=3D"path" dir=3D"ltr">exec_type</span>
+attributes) so that it can be executed by regular users (these domains h=
ave
+execute rights against all resources that have the
+<span class=3D"path" dir=3D"ltr">application_exec_type</span> attribute =
set. Finally, it marks the
+<span class=3D"path" dir=3D"ltr">spamassassin_t</span> domain as a const=
rained domain for user-based access
+controls. In other words, if SELinux users <span class=3D"path" dir=3D"l=
tr">user_u</span> and
+<span class=3D"path" dir=3D"ltr">staff_u</span> launch the application i=
n <span class=3D"path" dir=3D"ltr">spamassassin_t</span>
+domains, then the domains are segregated from each other (the intra-doma=
in rules
+inside <span class=3D"path" dir=3D"ltr">spamassassin_t</span> are only v=
alid for communication within the
+same SELinux user, not between SELinux users).
+</p>
+<p>
+Attributes are an important aspect in SELinux policy development. They m=
ake
+managing the domains easier, but you should always consider the implicat=
ions
+when you add an attribute to one of your types. It usually means that a =
whole
+lot of permissions are suddenly granted between other domains and yours.
+</p>
+<p>
+Next, set the proper intra-domain permissions. For instance, allow your =
domain
+to read its configuration files as well as more access inside its own
+<span class=3D"path" dir=3D"ltr">/var/lib</span> location:
+</p>
+<a name=3D"doc_chap4_pre2"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
+<tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing4.2: Snip=
pet from openca module</p></td></tr>
+<tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
+allow openca_ca_t openca_etc_t:file read_file_perms;
+allow openca_ca_t openca_etc_t:dir list_dir_perms;
+
+manage_dirs_pattern(openca_ca_t, openca_var_lib_t, openca_var_lib_t)
+manage_files_pattern(openca_ca_t, openca_var_lib_t, openca_var_lib_t)
+</pre></td></tr>
+</table>
+<p>
+The majority of work in developing SELinux policy modules is using and c=
hoosing
+the right interfaces. Having a few functions available to browse through=
 all the
+available information is always interesting, so you might want to use th=
e
+following function definitions (definitely not mandatory - this is only =
to help
+people skim through the policy definitions):
+</p>
+<a name=3D"doc_chap4_pre3"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
+<tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing4.3: SELi=
nux policy development function definitions</p></td></tr>
+<tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
+POLICY_LOCATION=3D"http://www.gentoo.org/path/to/your/refpolicy";
+
+# sefindif - Find interface definitions that have a string that matches =
the
+# given regular expression
+sefindif() {
+  REGEXP=3D"$1";
+  cd ${POLICY_LOCATION}/policy/modules;
+  for FILE in */*.if;
+  do
+    awk "http://www.gentoo.org/(interface\(|template\()/ { NAME=3D\$NF; =
P=3D0 }; /${REGEXP}/ { if (P=3D=3D0) {P=3D1; print NAME}; print };" ${FIL=
E} | sed -e "s:^:${FILE}\: :g";
+  done
+}
+
+# seshowif - Show the interface definition
+seshowif() {
+  INTERFACE=3D"$1";
+  cd ${POLICY_LOCATION}/policy/modules;
+  for FILE in */*.if;
+  do
+    grep -A 9999 "\(interface(\`${INTERFACE}'\|template(\`${INTERFACE}'\=
)" ${FILE} | grep -B 9999 -m 1 "^')";
+  done
+}
+
+# sefinddef - Find macro definitions that have a string that matches the=
 given
+# regular expression
+sefinddef() {
+  REGEXP=3D"$1";
+  grep -H "define(\`.*${REGEXP}.*" ${POLICY_LOCATION}/policy/support/* |=
 sed -e 's:.*\/\([^(]*\):\1:g'
+}
+
+# seshowdef - Show the macro definition
+seshowdef() {
+  MACRONAME=3D"$1";
+  cd ${POLICY_LOCATION}/policy/support;
+  for FILE in *.spt;
+  do
+    grep -A 9999 "define(\`${MACRONAME}'" ${FILE} | grep -B 999 -m 1 "')=
";
+  done
+}
+</pre></td></tr>
+</table>
+<p>
+These functions can then be used to find the information / interfaces yo=
u are
+looking for. For instance, you need the application to read the postfix
+configuration files:
+</p>
+<a name=3D"doc_chap4_pre4"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
+<tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing4.4: Look=
ing for the interface(s) needed</p></td></tr>
+<tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
+~$ <span class=3D"code-input">sefindif postfix_etc_t</span>
+services/postfix.if: template(`postfix_domain_template',`
+services/postfix.if:    allow postfix_$1_t postfix_etc_t:dir list_dir_pe=
rms;
+services/postfix.if:    read_files_pattern(postfix_$1_t, postfix_etc_t, =
postfix_etc_t)
+services/postfix.if:    read_lnk_files_pattern(postfix_$1_t, postfix_etc=
_t, postfix_etc_t)
+<span class=3D"code-comment">services/postfix.if: interface(`postfix_rea=
d_config',`
+services/postfix.if:            type postfix_etc_t;
+services/postfix.if:    read_files_pattern($1, postfix_etc_t, postfix_et=
c_t)
+services/postfix.if:    read_lnk_files_pattern($1, postfix_etc_t, postfi=
x_etc_t)</span>
+services/postfix.if: interface(`postfix_config_filetrans',`
+services/postfix.if:            type postfix_etc_t;
+services/postfix.if:    filetrans_pattern($1, postfix_etc_t, $2, $3)
+
+~$ <span class=3D"code-input">seshowif postfix_read_config</span>
+interface(`postfix_read_config',`
+        gen_require(`
+                type postfix_etc_t;
+        ')
+
+        read_files_pattern($1, postfix_etc_t, postfix_etc_t)
+        read_lnk_files_pattern($1, postfix_etc_t, postfix_etc_t)
+        files_search_etc($1)
+')
+</pre></td></tr>
+</table>
+<p>
+Same thing if you want to look for the correct macro definition (usually=
, if you
+notice something but you cannot find it as an interface, then it is most=
 likely
+a macro):
+</p>
+<a name=3D"doc_chap4_pre5"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
+<tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing4.5: Look=
ing for the right macros</p></td></tr>
+<tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
+<span class=3D"code-comment"># Suppose you need to read, write, connect,=
 ... to a socket</span>
+~$ <span class=3D"code-input">sefinddef connect</span>
+ipc_patterns.spt:define(`stream_connect_pattern',`
+<span class=3D"code-comment">obj_perm_sets.spt:define(`rw_socket_perms',=
 `{ ioctl read getattr write setattr append bind connect getopt setopt sh=
utdown }')</span>
+obj_perm_sets.spt:define(`connected_socket_perms', `{ create ioctl read =
getattr write setattr append bind getopt setopt shutdown }')
+obj_perm_sets.spt:define(`connected_stream_socket_perms', `{ connected_s=
ocket_perms listen accept }')
+
+<span class=3D"code-comment"># To see what the ps_process_pattern is abo=
ut</span>
+~$ <span class=3D"code-input">seshowdef ps_process_pattern</span>
+define(`ps_process_pattern',`
+        allow $1 $2:dir list_dir_perms;
+        allow $1 $2:file read_file_perms;
+        allow $1 $2:lnk_file read_lnk_file_perms;
+        allow $1 $2:process getattr;
+')
+</pre></td></tr>
+</table>
+<p>
+As we strive to bring most of our patches upstream, please do consider t=
he <a href=3D"http://oss.tresys.com/projects/refpolicy/wiki/HowToContribu=
te">contribution
+guidelines</a> of the reference policy project. The project has a docume=
nted
+style guide, naming convention and an online API reference (for the vari=
ous
+interfaces).
+</p>
+<p>
+Note that, the moment you create a new module, you'll need to create the=
 proper
+role interfaces (if it is an application that is directly called from a =
user
+domain). Take a look at <span class=3D"code" dir=3D"ltr">tvtime_role</sp=
an> and how it is used in the
+<span class=3D"path" dir=3D"ltr">staff.te</span> and <span class=3D"path=
" dir=3D"ltr">sysadm.te</span> role definitions.
 </p>
 <p class=3D"secthead"><a name=3D"doc_chap4_sect4">Testing new modules</a=
></p>
 <p>
-TODO talk about users trying to do maximum testing (all the way). Also, =
if they
-want to support unconfined domains too, how they can do this (and should=
 test).
+When you test your application, test it in as many ways as possible. If =
your
+application is a command-line application, run it both from a regular te=
rminal
+(tty) as well as a virtual one (in an xterm). See if it still works if y=
ou run
+it in a screen session. Try out all functions and features that the appl=
ication
+supports.
+</p>
+<p>
+This rigorous testing is necessary because SELinux denies everything tha=
t isn't
+explicitly allowed. If you do not test certain features, chances are tha=
t the
+module does not provide the necessary permissions and as such, users wil=
l be
+impacted.
 </p>
+<p>
+To test out a new module, load it (<span class=3D"code" dir=3D"ltr">semo=
dule -i modulename.pp</span>) and relabel
+the files affiliated with the application (either through <span class=3D=
"code" dir=3D"ltr">rlpkg</span> or using
+<span class=3D"code" dir=3D"ltr">restorecon</span>). Consider the follow=
ing testing activities if applicable (not
+all domains are interactive domains, so please read the activities with =
your
+domain definition in mind):
+</p>
+<ul>
+  <li>
+    Sending signals to the application (if you need to be able to kill i=
t, try
+    killing it)
+  </li>
+  <li>
+    Run it both as a regular user (<span class=3D"path" dir=3D"ltr">user=
_u</span>) as well as
+    administrative users (if applicable). If your domain needs to suppor=
t
+    unconfined domains/users, run it from an unconfined user domain too.
+  </li>
+  <li>
+    Run it from a terminal, console, screen, sudo, ...
+  </li>
+  <li>
+    Change the applications' configuration file (including rendering it =
useless
+    with syntax errors) and look at the applications' behavior. Especial=
ly
+    syntax failures as that might trigger the application to log things =
at
+    places that you haven't discovered earlier.
+  </li>
+</ul>
 <p class=3D"chaphead"><a name=3D"doc_chap5"></a><span class=3D"chapnum">=
5.
             </span>Policy Guidelines</p>
+<p class=3D"secthead"><a name=3D"doc_chap5_sect1">Cosmetic denials</a></=
p>
 <p>
-TODO dealing with cosmetic denials
+When working on policy modules, you'll notice that the application is tr=
ying to
+do things which are denied, but have no obvious effect on the applicatio=
ns
+functionality. This is to be expected: many applications do not handle f=
ile
+descriptors properly (file descriptor leaks are common) or applications =
read
+attributes of files but don't do anything with it. You'll notice that yo=
u learn
+a lot from the application while writing its policy ;-)
 </p>
 <p>
-TODO resources - gentoo selinux policy, refpolicy guidelines
+Gentoo Hardened's idea here is to only allow what is actually needed by =
the
+application. Cosmetic denials are to be <span class=3D"code" dir=3D"ltr"=
>dontaudit</span>'ed. Gentoo Hardened
+uses the <span class=3D"code" dir=3D"ltr">gentoo_try_dontaudit</span> bo=
olean for this:
+</p>
+<a name=3D"doc_chap5_pre1"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
+<tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing5.1: Exam=
ple usage of gentoo_try_dontaudit</p></td></tr>
+<tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
+<span class=3D"code-comment"># Hide sshd_t calling module_request from t=
he kernel_t domain</span>
+tunable_policy(`gentoo_try_dontaudit',`
+        kernel_dontaudit_request_load_module(sshd_t)
+')
+</pre></td></tr>
+</table>
+<p class=3D"secthead"><a name=3D"doc_chap5_sect2">Gentoo Hardened SELinu=
x policy</a></p>
+<p>
+To streamline the policy development efforts, Gentoo Hardened as a <a hr=
ef=3D"selinux-policy.xml">SELinux Policy</a> document explaining the
+principles used during policy development and the implementation guideli=
nes we
+strive to follow during development.
+</p>
+<p>
+Such a policy is important because we want to have a consistent security=
 policy
+that users and developers can relate to. By following the policy, we hop=
e that
+other developers can quickly jump in and work on it further.
 </p>
 <p class=3D"chaphead"><a name=3D"doc_chap6"></a><span class=3D"chapnum">=
6.
             </span>Submitting Patches</p>
+<p class=3D"secthead"><a name=3D"doc_chap6_sect1">File context patches</=
a></p>
+<p>
+If you are able to fix a problem by adding the proper file contexts (usi=
ng
+<span class=3D"code" dir=3D"ltr">semanage fcontext -a</span>), please co=
nsider the following:
+</p>
+<ul>
+  <li>
+    If the location for which you set the context deviates from the stan=
dard
+    location as either intended by the project or Gentoo itself, it migh=
t be
+    best to document it in the forums or elsewhere. We will not change f=
ile
+    contexts to match every ones configuration, unless the file context =
change
+    is apparent for each installation.
+  </li>
+  <li>
+    Developers might not immediately push file context changes in new po=
licy
+    module packages to keep the amount of policy module changes low. Ins=
tead,
+    these changes can be stacked and pushed when other changes occur as =
well.
+  </li>
+</ul>
 <p>
-TODO differentiate between base patch and module patch.
+If you believe that the change is needed for everyone using Gentoo Harde=
ned with
+SELinux, create a <a href=3D"https://bugs.gentoo.org">bugreport</a> and =
assign
+it to <span class=3D"code" dir=3D"ltr">selinux@gentoo.org</span>. In the=
 bugreport, mention the file context you
+think is necessary and why.
 </p>
+<p class=3D"secthead"><a name=3D"doc_chap6_sect2">Module patches</a></p>
 <p>
-TODO perhaps talk about file context patches. Perhaps we will not make a=
 new
-build release for it, but stage it to be included in the next release wh=
en a
-non-filecontext patch is added?
+Module patches with changes that are intra-module (and have no effect ou=
tside)
+are best generated from the <span class=3D"path" dir=3D"ltr">policy/modu=
les</span> location:
+</p>
+<a name=3D"doc_chap6_pre1"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
+<tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing6.1: Exam=
ple generating patch for modular changes</p></td></tr>
+<tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
+~$ <span class=3D"code-input">cd dev/hardened/strict.local/policy/module=
s</span>
+~$ <span class=3D"code-input">diff -ut ../../../strict/policy/modules/se=
rvices/openct.te services/openct.te</span>
+--- ../../../../strict/policy/modules/services/openct.te   2011-04-22 23=
:28:17.932918002 +0200
++++ services/openct.te  2011-04-23 09:55:08.156918002 +0200
+@@ -47,6 +47,10 @@
+=20
+ miscfiles_read_localization(openct_t)
+=20
++tunable_policy(`gentoo_try_dontaudit',`
++        kernel_dontaudit_read_system_state(openct_t)
++')
++
+ userdom_dontaudit_use_unpriv_user_fds(openct_t)
+ userdom_dontaudit_search_user_home_dirs(openct_t)
+</pre></td></tr>
+</table>
+<p>
+Attach this patch to the <a href=3D"https://bugs.gentoo.org">bugreport</=
a>
+explaining why it is needed. If you think the patch itself is not obviou=
s, make
+sure that the necessary comments are in place <span class=3D"emphasis">i=
nside the patch</span> for future
+reference.
+</p>
+<p>
+Please have a separate patch file per module (do not combine multiple mo=
dules in
+a single patch).
+</p>
+<p class=3D"secthead"><a name=3D"doc_chap6_sect3">Base policy patches</a=
></p>
+<p>
+If a patch extends a single module, or it includes interface changes on =
a
+module, you'll need to create a patch for the base policy. In this case,=
 the
+patch is best made from the upper location.
+</p>
+<a name=3D"doc_chap6_pre2"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
+<tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing6.2: Gene=
rating a base policy patch</p></td></tr>
+<tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
+~$ <span class=3D"code-input">cd dev/hardened/strict.local</span>
+~$ <span class=3D"code-input">diff -ut ../strict/policy/modules/services=
/openct.if policy/modules/services/openct.if</span>
+--- ../strict/policy/modules/services/openct.if    2011-04-22 23:28:17.9=
18918002 +0200
++++ policy/modules/services/openct.if       2011-04-23 10:01:38.75391800=
1 +0200
+@@ -15,7 +15,7 @@
+                 type openct_t;
+         ')
+=20
+-        allow $1 openct_t:process signull;
++        allow $1 openct_t:process { signull sigchld };
+ ')
+=20
+ ########################################
+</pre></td></tr>
+</table>
+<p>
+Attach this patch to the <a href=3D"https://bugs.gentoo.org">bugreport</=
a>
+explaining why it is needed. If you think the patch itself is not obviou=
s, make
+sure that the necessary comments are in place <span class=3D"emphasis">i=
nside the patch</span> for future
+reference.
+</p>
+<p>
+Please have a separate patch file per major change (do not combine multi=
ple
+unrelated changes in a single patch).
 </p>
 <p class=3D"chaphead"><a name=3D"doc_chap7"></a><span class=3D"chapnum">=
7.
             </span>Running Your Own Policy</p>
+<p class=3D"secthead"><a name=3D"doc_chap7_sect1">Creating a local overl=
ay</a></p>
+<p>
+If you want to use your own policy rather than Gentoo's, we seriously re=
commend
+to use a local overlay which uses the same package names and constructs.=
 This
+allows your policy to integrate properly with the other Gentoo packages =
(which
+might depend on the SELinux packages). For instance, when you install op=
enldap,
+it will still properly depend on the <span class=3D"path" dir=3D"ltr">se=
c-policy/selinux-ldap</span>
+package even if you provide it completely.
+</p>
+<p>
+To do so, first create a local overlay and copy the content of the
+<span class=3D"path" dir=3D"ltr">sec-policy</span> category inside it.
+</p>
+<a name=3D"doc_chap7_pre1"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
+<tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing7.1: Crea=
ting a local overlay</p></td></tr>
+<tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
+~$ <span class=3D"code-input">mkdir dev/overlay</span>
+~$ <span class=3D"code-input">cp -r /usr/portage/sec-policy dev/overlay<=
/span>
+</pre></td></tr>
+</table>
+<p>
+Next, tell Portage to not synchronise the <span class=3D"path" dir=3D"lt=
r">sec-policy</span> category of
+the main tree anymore. To do so, create the file
+<span class=3D"path" dir=3D"ltr">/etc/portage/rsync_excludes</span> with=
 the following content:
+</p>
+<a name=3D"doc_chap7_pre2"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
+<tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing7.2: Rsyn=
c exclusion information</p></td></tr>
+<tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
+sec-policy/
+</pre></td></tr>
+</table>
+<p>
+Finally, add your current overlay by editing <span class=3D"path" dir=3D=
"ltr">/etc/make.conf</span>:
+</p>
+<a name=3D"doc_chap7_pre3"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
+<tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing7.3: Edit=
ing make.conf</p></td></tr>
+<tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
+PORTDIR_OVERLAY=3D"${PORTDIR_OVERLAY} /home/user/dev/overlay"
+</pre></td></tr>
+</table>
+<p>
+From now onwards, Gentoo Portage will only use your local overlay (you c=
an
+remove <span class=3D"path" dir=3D"ltr">/usr/portage/sec-policy</span> i=
f you don't want Portage to even
+reuse the current set of packages.
+</p>
+<p class=3D"secthead"><a name=3D"doc_chap7_sect2">Updating module packag=
es</a></p>
 <p>
-TODO describe how to create your own overlay with modules and patchbundl=
es. Also
-usable for developers to stage their ebuild / patch submissions before a=
ctually
-putting in git repo. Ensure that naming is consistent (so that ebuild
-dependencies of packages remain).
+To create or update a module package, you can use the following skeleton=
 for the
+ebuilds:
 </p>
+<a name=3D"doc_chap7_pre4"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
+<tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing7.4: Skel=
eton for ebuilds, example for postfix</p></td></tr>
+<tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+<span class=3D"code-comment"># Set the MODS variable to the refpolicy na=
me used, so services/postfix.te gives "postfix"</span>
+MODS=3D"postfix"
+IUSE=3D""
+
+inherit selinux-policy-2
+
+DESCRIPTION=3D"SELinux policy for postfix"
+
+KEYWORDS=3D"~amd64 ~x86"
+
+<span class=3D"code-comment"># POLICY_PATCH is optional (only when you h=
ave a patch), without it just uses the=20
+# refpolicy version.</span>
+POLICY_PATCH=3D"${FILESDIR}/fix-services-postfix-r3.patch"
+</pre></td></tr>
+</table>
+<p>
+The patch(es) that you can put in the <span class=3D"path" dir=3D"ltr">f=
iles/</span> location (and referred to
+in the <span class=3D"code" dir=3D"ltr">POLICY_PATCH</span>) should be m=
ade as defined earlier in this document.
+You can put multiple patches in this variable if you want.
+</p>
+<p>
+Don't forget to run <span class=3D"code" dir=3D"ltr">repoman manifest</s=
pan> with every change, and run
+<span class=3D"code" dir=3D"ltr">repoman scan</span> to check for potent=
ial mistakes.
+</p>
+<p class=3D"secthead"><a name=3D"doc_chap7_sect3">Updating base package<=
/a></p>
+<p>
+To provide updates on the base policy, it is recommended to keep all pat=
ches you
+made centrally in a directory (say <span class=3D"path" dir=3D"ltr">dev/=
hardened/base-patches</span>). When
+you want to create a new <span class=3D"path" dir=3D"ltr">sec-policy/sel=
inux-base-policy</span> release,
+create a patchbundle from your patch directory, put the bundle in the
+<span class=3D"path" dir=3D"ltr">files</span> location, create the updat=
ed ebuild and try it out.
+</p>
+<a name=3D"doc_chap7_pre5"></a><table class=3D"ntable" width=3D"100%" ce=
llspacing=3D"0" cellpadding=3D"0" border=3D"0">
+<tr><td bgcolor=3D"#7a5ada"><p class=3D"codetitle">Code Listing7.5: Buil=
ding a base policy package</p></td></tr>
+<tr><td bgcolor=3D"#eeeeff" align=3D"left" dir=3D"ltr"><pre>
+~$ <span class=3D"code-input">cd dev/hardened/base-patches</span>
+~$ <span class=3D"code-input">tar cjvf ../overlay/sec-policy/selinux-bas=
e-policy/files/patchbundle-selinux-base-policy-2.20101213-r13.tar.bz2 *</=
span>
+~$ <span class=3D"code-input">cd ../overlay/sec-policy/selinux-base-poli=
cy</span>
+~$ <span class=3D"code-input">cp selinux-base-policy-2.20101213-r12.ebui=
ld selinux-base-policy-2.20101213-r13.ebuild</span>
+</pre></td></tr>
+</table>
 <p>
-TODO describe how to exclude sec-policy in regular rsync
+Don't forget to run <span class=3D"code" dir=3D"ltr">repoman manifest</s=
pan> and <span class=3D"code" dir=3D"ltr">repoman scan</span>. You can
+then install <span class=3D"path" dir=3D"ltr">sec-policy/selinux-base-po=
licy-2.20101213-r13</span> and test
+it out.
 </p>
 <br><p class=3D"copyright">
     The contents of this document are licensed under the <a href=3D"http=
://creativecommons.org/licenses/by-sa/2.5">Creative Commons -