I will create a SELinux policy module for the irssi user application and i will integrate this new policy module into the main Fedora selinux-policy with RPM devtools.
What i need:
yum install rpmdevtools selinux-policy-devel eclipse-slide
Chapter 1. Preparing the source:
First we should determine which selinux policy we have installed so that we can go find and download the corresponding selinux-policy source rpm.

It is determined that the source rpm that i need is not available on the main mirrors and therefore i will try to find it on koji.fedoraproject.org/koji.

I will download the source rpm to my default Download location and extract the package simple by alter-click ing it and chooce extract here from the menu.

Once the source rpm is extracted, a new folder appears with its contents. I am going to copy the included serefpolicy-3.3.1.tgz plus policy-20071130.patch to my desktop. After that i will extract the serefpolicy-3..3.1.tgz located on my desktop and apply the patch thats located on my desktop as well.

At this point the folder serefpolicy-3.3.1 on my desktop represents the prepared source for the binary policy that is installed on my system.
Chapter 2. Loading source policy into a Eclipse-Slide project:
Now i am ready to load the prepared source policy into the Eclipse-Slide IDE. I do this by starting Eclipse, creating a new Slide project and loading the prepared serefpolicy-3.3.1 folder into my new Slide project.





Chapter 3. Integrating a new policy module into our Eclipse-Slide project:
Now its time to actually integrate a new policy module into the current project.
I choose the irssi application. This is application is started by users and therefore belongs in the apps subsection of the modules location in our project.



Chapter 4. Installing and perusing Irssi application:
Since we are going to integrate policy for Irssi, we should install this package by running: yum install irssi. Once this package is installed we can query information about this package. We want to find out to which files irssi application needs to write or which objects Irssi must execute. In this case irssi also has a configuration file /etc/irssi.config that is of particular interest to us.

Before i start to write policy i want to explain something. Since Irssi is a user application, it is expected that users (or as wel call them userdomains) have to interact with it. The SELinux world can have infinite userdomains, and policy is based on which user domain interacts with the irssi application domain.
You can imagine how much maintenance work it would take for us to keep our irssi policy up-to-date for any (new) selinux userdomains that may come or go.
It would require very many rules just to differentiate between users. This is why templates and in particular the per_role_template was invented. This template can be invokes for each userdomain.
User information is replaced by variables which are instantiated when the user domain calls the template. This mean that i can use one piece of policy for any user domains that may call it. This saves much maintenance work but also saves us from a huge pile of policy. These templates are hosted by the domain in the interface file in the module. This file is used by domains to host policy. Other domains have easy access to theres interfaces and templates to interact with the domain that hosts the interfaces or templates.
The first step for me to take is to declare any non-user specific types. We know that irssi has an executable in /usr/bin/irssi and we have to declare a type for this excutable: irssi_exec_t.
We also know that irssi owns a file in /etc/irssi.conf, and we should declare a type for this config file in etc as well: irssi_etc_t.
We do this in the irssi.te file. This file has local policy regarding to irssi. The .te file in a module has a few parts: first we declare the policy_module, than we declare any types, booleans and others. and than we call interfaces in other domains and specificy local policy.
Policy that is user domain specific does not belong in a .te file as this policy is called by the user domain and thus should be hosted in the .if file by our domain. More about the .if file later.
So now we have to declare a tpye for irssi_exec_t and irssi_etc_t in irssi.te file in out module

So now we have those two types declared and now i have to make sure that these objects that we declared types for get labelled (/usr/bin/irssi and /etc/irssi.conf) This is done in the .fc file

At this point all out non-user domain specific types are declared and we have taken care of those objects file labelling via the file context file in our module.
Chapter 6. User domain specific policy in modules interface file:
Now we are ready for the part of the module that is called by the userdomains that want to execute irssi. This part is done in the interface file of the module. policy in this file is accessible by domains that call it.
Here is how this works: user domains can call irssi per_role_template so that they can run irssi in its application domain. user domains are expected to call this template in their local policy (.te file): irssi_per_role_template(myuser, myuser_t, myuser_r)

And so if a user domain called myuser wants to run our application domain (in its domain) than that user domain will have to call our per_role_template in its own local policy.
My next step is to declare the remaining user domain specific types. such as the type for the application domain and the type of our application domains objects in the user space.


Now were done with the .fc file
If you remember , we have declared two non user domain specific types in our irssi.te file: irrsi_exec_t and irssi_etc_t. These types are locally declared however, user domains that call the irssi_per_role_template also need access to these types, and since other domains cannot access our local policy (.te) we hav to include or require those types in our irssi_per_role_template in our .if file so that other domains can also interact with these types.

Next we have to make some more decisions. We can decide to let any (user)domain automatic transition to the irssi application domain once the user executes the irssi executable or we can decide that the source domain executes irssi in its own domain instead.
I have chosen for an option where we make the above decision tunable by way of a boolean. The result is that by default domains will not transition to the irssi app domain unless a boolean for that particular domain is set.
That boolean is called irssi_confine_$1, where $1 stands for the user domain prefix. The administrator can set a boolean for the particular user domain if he want that domain to run in the irssi application domain.
First we declare our userdomain specific boolean in the declaration section of our irssi_per_role template and in the local policy bit of our template we write policy for this tunable.

Now that we have declared a local boolean we can decide to make some other possibilities optional. For example, maybe we want to enable optional support for NFS or SAMBA home directories. Since these are global booleans, we do not have to declare these booleans but we jut have to write policy for them.

New Chapter. Networking:
Irssi connect to a irc server on usually port 6667. This port is already declared as port ircd_port_t in refpolicy and so we can use that policy to let irssi connect to irc servers. however we should declare a network port range for Irssi IRC DCC server facility. We declare a port ircdcc_port_t for tcp 4990-5000. Irssi will use that as its ports for a DCC server or in a single instance mode also for connecting to DCC ports. In case we are not hosting but downloading from another DCC server.

Now that we have declared irssi's DCC server port range we should also set up the rest of irssi networking policy. We simply add a interface to allow connect and send and receive irc client packets from the ircd_port_t port. Plus some other corenetwork module interfaces that are used as defaults.

Next it is decision making time again. also lets first recap: by default users do not transition to the irssi domain. We choose to make this decision tunable by boolean. If this bool is set than the user runs irssi in its domain. As it stands now irssi may only connect to ports with type irc_port_t which is tcp 6667. irssi will not be able to connect to any other ports. Also the irc_dcc_t port we declared for irssi DCC SERVER is not yet allowed.
We can decide to make this bit tunable or default behaviour. In this example i chose to make iRC DCC tunable and disabled by default unless set (least privilege model), and so we have to create a tunable_policy block again to allow irssi either connect or bind to its dcc port range (tcp 4990-5000)


So again theres four modes: 1. Disabled unless enabled. 2. Strict (can only connect to port 6667) 3. Single instance mode( can connect to 6667 and connect and bind to 4990-5000) and mass hosting mode ( can connect and bind to any unreserved port plus at of the above)


This next part goes into local* policy that defines how our domain may interact. This is usually the first piece of policy in the local policy block of your module and in this case it is user domain specific and thus should this be in the interface file irssi.if.
This piece of policy i split into 3 parts, Part 1 is policy that governs how our domain can interact with its own process (allow $1_irssi_t self). Part 2 is policy that governs how user domains may interact with the application domain e.g. allow $2 $1_irssi_t. Part 3 is policy that governs how our application domain may interact with the userdomain or allow $1_irssi_t $2)

Now i will deal with our domains objects and how our domain can interact with these objects. First you may remember that we declared a type irssi_etc_t in our irssi.te file. This is a global configuration file that irssi should be able to read,.and so we should give our domain access to search /etc, and we should allow our domain read and get attribute access to files with type irssi_etc_t. This will allow irssi to read the global config file.
Next we must ensure that irssi can manage its userdomain specific objects in the user space. We must ensure that the userdomain can also manage irssi objects in the user home location.
Third we should ensure that the userdomain is able to relabel irssi domain objects in his or her home dir. So that a user can move objects in and out of the irssi domain in his or her home location.

Also note the optional_policy block for nis_use_ypbind. The optional policy block means that the policy is only enabled when NIS is available. This option was added to add NIS support to our module.


Now i have to copy my project to my desktop and archive it with exactly the same name as the serepolicy-3.3.1.tgz we extracted and prepared earlier.

Next we should create our personal rpmbuild root

In this part we are going to copy the contents of the folder that we have extracted from our source rpm in our Download location to the newly created SOURCES location in our ~/rpmbuild root.
we will remove the copied *.patch and serefpolicy-3.3.1.tgz from our ~/rpmbuild/SOURCES location and copy the selinux-policy.spec that is is also located there to ~/rpmbuild/SPECS/.
Next we will copy our modified serefpolicy-3.3.1.tgz from our desktop to the ~/.rpmbuild/SOURCES/ location.

Now we should edit our spec file located in ~/rpmbuild/SPECS/selinux-policy-spec. We have to bump up the version number to avoid difficulties. We also have to comment out any patch entries (this is because we already applied the included patches manually in the beginning of our exercise.)



Finally we should add our new module to the modules-targeted.conf file in ~/rpmbuild/SOURCES/ if we want our module to be active in the selinux-policy-targeted package.

Now we can execute rpmbuild -ba ~/rpmbuild/SPECS/selinux-policy.spec and let her rip.

If all (would) go well than you'd get your freshly brewed set of rpms.

But all did not went go well in this example as i made a mistake. The image below shows my mistake corrected. If you have any questions or comments please ping me at #fedora-selinux on freenode
You can find a copy of my irssi policy here http://pastebin.ca/768256?srch=irssi_exec_t it also includes policy for eggdrop and manual pages but it may need some work.
