Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /tags/htdocs/index.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 28 - (hide annotations) (download) (as text)
Sat May 19 08:46:36 2012 UTC (11 years, 10 months ago) by kumaneko
File MIME type: text/html
File size: 168232 byte(s)


1 kumaneko 10 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2     <html lang="en-US">
3     <head>
4     <meta http-equiv="content-type" content="text/html; charset=UTF-8">
5 kumaneko 15 <meta http-equiv="content-style-type" content="text/css">
6     <link rel="stylesheet" href="media/caitsith.css" media="all" type="text/css">
7 kumaneko 10 <title>CaitSith Documentation</title>
8     </head>
9     <body>
10    
11     <h1>CaitSith -- A simplified access restriction module for system protection.</h1>
12    
13     <p>CaitSith is an access restriction module for Linux systems. This module gives you ability to restrict access (e.g. opening files, executing programs) at the kernel level. This module is designed for ease of use.</p>
14    
15     <p>Below is documentation and policy syntax but is under construction. Sorry.</p>
16    
17     <hr>
18    
19     <h1><a href="#how_to_use">How to use</a></h1>
20    
21 kumaneko 15 <p><a href="#difference_with_tomoyo">1. Difference with TOMOYO (for existing TOMOYO users)</a></p>
22    
23 kumaneko 10 <ul>
24 kumaneko 15 <li><a href="#1.1">1.1. About pathnames and management programs</a></li>
25     <li><a href="#1.2">1.2. About policy syntax</a></li>
26 kumaneko 10 </ul>
27    
28 kumaneko 15 <p><a href="#how_to_install">2. How to install</a></p>
29    
30     <ul>
31     <li><a href="#2.1">2.1. Install dependencies</a></li>
32     <li><a href="#2.2">2.2. Download and patch the kernel</a></li>
33     <li><a href="#2.3">2.3. Configure the kernel</a></li>
34     <li><a href="#2.4">2.4. Compile and install the kernel</a></li>
35     <li><a href="#2.5">2.5. Install the userspace tools</a></li>
36     <li><a href="#2.6">2.6. Initializing configuration</a></li>
37     <li><a href="#2.7">2.7. Configuring your bootloader</a></li>
38     <li><a href="#2.8">2.8. Rebooting your system</a></li>
39     <li><a href="#2.9">2.9. How can I disable/uninstall CaitSith?</a></li>
40     </ul>
41    
42     <p><a href="#how_to_develop_policy">3. How to develop policy</a></p>
43    
44 kumaneko 16 <ul>
45     <li><a href="#3.1">3.1. Policy file structure</a></li>
46     <li><a href="#3.2">3.2. Updating policy configuration</a></li>
47     <li><a href="#3.3">3.3. Example of simple access restriction rule</a></li>
48 kumaneko 20 <li><a href="#3.4">3.4. Understanding two viewpoints</a></li>
49     <li><a href="#3.5">3.5. Using string arguments in conditions</a></li>
50     <li><a href="#3.6">3.6. Using numeric arguments in conditions</a></li>
51     <li><a href="#3.7">3.7. Using process's information in conditions</a></li>
52     <li><a href="#3.8">3.8. Using IP address arguments in conditions</a></li>
53 kumaneko 16 </ul>
54    
55 kumaneko 10 <h1><a href="#policy_specification">Policy Specification</a></h1>
56    
57     <ul>
58     <li><a href="#available_parameters">1. About parameters which can be handled via policy</a></li>
59     <li><a href="#string_expression">1.1. String parameters representation rule</a></li>
60     <li><a href="#numeric_expression">1.2. Numeric parameters representation rule</a></li>
61     <li><a href="#ipaddress_expression">1.3. IP address parameters representation rule</a></li>
62     <li><a href="#conditions">2. About conditional expressions</a></li>
63     <li><a href="#string_comparison">2.1. Conditional expressions which handle string parameters</a></li>
64     <li><a href="#integer_comparison">2.2. Conditional expressions which handle numeric parameters</a></li>
65     <li><a href="#ipaddr_comparison">2.3. Conditional expressions which handle IP address parameters</a></li>
66     <li><a href="#task_attributes_comparison">2.4. Conditional expressions which handle current thread's attributes</a></li>
67     <li><a href="#argv_comparison">2.5. Conditional expressions which handle command line arguments</a></li>
68     <li><a href="#envp_comparison">2.6. Conditional expressions which handle environment variable arguments</a></li>
69     <li><a href="#dac_permission_comparison">2.7. Conditional expressions which handle file's DAC permissions</a></li>
70     <li><a href="#file_type_comparison">2.8. Conditional expressions which handle file's type</a></li>
71     <li><a href="#file_attributes_comparison">2.9. Conditional expressions which handle file's attributes</a></li>
72     <li><a href="#syntax_list">3. List of syntaxes sorted by operations</a></li>
73     <li><a href="#policy_syntaxes">4. Policy syntaxes</a></li>
74     <li><a href="#policy_structure_definition">4.1. Definition</a></li>
75     <li><a href="#policy_examples">4.2. Examples</a></li>
76     </ul>
77    
78     <hr>
79    
80     <h1><a name="how_to_use">How to use</a></h1>
81    
82     <h2><a name="difference_with_tomoyo">1. Difference with TOMOYO (for existing TOMOYO users)</a></h2>
83    
84 kumaneko 15 <p>CaitSith was derived from TOMOYO Linux, but usage of CaitSith would be too different to imagine that CaitSith was derived from TOMOYO Linux. If you are already using TOMOYO Linux, please read the difference described below.</p>
85 kumaneko 10
86 kumaneko 15 <h3><a name="1.1">1.1. About pathnames and management programs</a></h3>
87 kumaneko 10
88 kumaneko 22 <p><code>/proc/ccs/domain_policy</code>, <code>/proc/ccs/exception_policy</code>, <code>/proc/ccs/profile</code>, <code>/proc/ccs/manager</code> and <code>/proc/ccs/stat</code> have been aggregated into <code>/proc/caitsith/policy</code>.</p>
89 kumaneko 10
90 kumaneko 22 <p><code>/etc/ccs/policy/current/domain_policy.conf</code>, <code>/etc/ccs/policy/current/exception_policy.conf</code>, <code>/etc/ccs/policy/current/profile.conf</code>, <code>/etc/ccs/policy/current/manager.conf</code> and <code>/etc/ccs/policy/current/stat.conf</code> have been aggregated into <code>/etc/caitsith/policy/current</code>.</p>
91 kumaneko 10
92 kumaneko 22 <p>Built-in policy files which are located under kernel source directory as <code>security/ccsecurity/policy/domain_policy.conf</code>, <code>security/ccsecurity/policy/exception_policy.conf</code>, <code>security/ccsecurity/policy/profile.conf</code>, <code>security/ccsecurity/policy/manager.conf</code> and <code>security/ccsecurity/policy/stat.conf</code> have been aggregated into <code>security/caitsith/policy/policy.conf</code>.</p>
93 kumaneko 10
94 kumaneko 22 <p>Only <code>/sbin/caitsith-init</code>, <code>/usr/sbin/caitsith-auditd</code>, <code>/usr/sbin/caitsith-loadpolicy</code>, <code>/usr/sbin/caitsith-notifyd</code>, <code>/usr/sbin/caitsith-pstree</code>, <code>/usr/sbin/caitsith-queryd</code>, <code>/usr/sbin/caitsith-savepolicy</code>, <code>/usr/lib/caitsith/audit-exec-param</code>, <code>/usr/lib/caitsith/caitsith-agent</code> and <code>/usr/lib/caitsith/init_policy</code> are provided for managing policy. (In other words, programs such as <code>/usr/sbin/ccs-editpolicy</code> and <code>/usr/sbin/ccs-setprofile</code> have been removed.)</p>
95 kumaneko 10
96 kumaneko 28 <p>Command line arguments for specifying type of policy to load/save have been removed from <code>/usr/sbin/caitsith-loadpolicy</code> and <code>/usr/sbin/caitsith-savepolicy</code>.</p>
97 kumaneko 10
98 kumaneko 28 <p>Command line arguments for specifying profile type have been removed from <code>/usr/lib/caitsith/init_policy</code>.</p>
99 kumaneko 10
100 kumaneko 15 <h3><a name="1.2">1.2. About policy syntax</a></h3>
101 kumaneko 10
102 kumaneko 28 <p>Policy syntax has been drastically changed. TOMOYO Linux uses process's domainname as a key for grouping permissions to do some operations. In other words, TOMOYO Linux's policy is collection of "which domain can do ..." rules. On the other hand, CaitSith uses operation as a key for checking permission. In other words, CaitSith's policy is collection of "which operation can be done by ..." rules. This change is intended for allowing users to protect resources using blacklisting approach. In CaitSith, process's domainname is nothing but one of optional parameters that can be used for controlling whether to grant or deny specific operations. Users can write rules without managing domainnames unless needed.</p>
103 kumaneko 10
104     <p>Process's domainname representation has changed from space delimited multiple words (e.g. "&lt;kernel&gt; /sbin/init /etc/rc.d/rc.sysinit") to a single word (e.g. "/sbin/init").</p>
105    
106     <p>Domain transitions no longer happen unless explicitly specified by policy.</p>
107    
108     <p>Distinction of disabled/learning/permissive/enforcing mode has been removed.</p>
109    
110     <p>"path_group" keyword has been renamed to "string_group", and "address_group" keyword has been renamed to "ip_group".</p>
111    
112     <p>Representation of \ character has been changed from \\ to \134.</p>
113    
114 kumaneko 28 <p>Distinction between directory's pathname and non-directory's pathname has been removed by removing trailing / character from pathname.</p>
115 kumaneko 10
116     <p>A new wildcard /\(dir\)/ has been introduced for helping converting from (e.g.) "/tmp/\{\*\}/" to "/tmp/\(\*\)/\*", for directory's pathname (except the root directory itself) no longer ends with / character which previously matched /\{\*\}/ wildcard.</p>
117    
118     <p>Category keywords (i.e. "file", "network", "ipc", "misc", "capability", "task") have been removed because access control levels which was specified using profile has been removed. Some of operation keywords have been renamed (e.g. "network inet stream connect" became "inet_stream_connect", "misc env" became "environ").</p>
119    
120     <p>"task auto_execute_handler" keyword has been renamed to "handler=" argument of "execute" keyword. This is intended for using execute handler for preprocessing purpose when executing specific programs rather than when executing from specific domains. "task denied_execute_handler" keyword has been removed.</p>
121    
122     <p>Domain argument has been removed from permission to send signals (i.e. "signal" directive), for kill() system call accepts negative number for specifying multiple processes. It is impossible to selectively deny sending signals because it is not permitted to sleep while sending signals.</p>
123    
124     <p>Restriction granularity for ptrace operation has changed from boolean (i.e. "capability SYS_PTRACE") to command number + domainname.</p>
125    
126     <p>Restriction granularity for environment variables has changed from name only to both name and values.</p>
127    
128     <p>Several variables for referencing file's attributes have been added.</p>
129    
130     <p>Local port reserve functionality (i.e. "deny_autobind" keyword) has been removed.</p>
131    
132     <h2><a name="how_to_install">2. How to install</a></h2>
133    
134 kumaneko 15 <p>Since CaitSith is a kernel component, you will have to compile your own kernel.</p>
135 kumaneko 10
136 kumaneko 15 <h3><a name="2.1">2.1. Install dependencies</a></h3>
137 kumaneko 10
138 kumaneko 15 <p>These packages are required for compiling the kernel and the userspace tools:</p>
139 kumaneko 10
140 kumaneko 15 <ul>
141     <li><strong>wget</strong>: to download sources</li>
142     <li><strong>patch</strong>: to patch the kernel</li>
143     <li><strong>gcc</strong>: to build the kernel and tools</li>
144     <li><strong>make</strong>: to build the kernel and tools</li>
145     <li><strong>ncurses-devel</strong> or <strong>libncurses-dev</strong>: to build the tools</li>
146     </ul>
147    
148     <p>These can be installed with the following commands:</p>
149    
150     <p><strong>RedHat distributions</strong></p>
151     <pre class="command">
152     # yum -y install wget patch gcc make ncurses-devel
153     </pre>
154     <p><strong>Debian distributions</strong></p>
155     <pre class="command">
156     # apt-get -y install wget patch gcc make libncurses-dev
157     </pre>
158     <p><strong>SUSE distributions</strong></p>
159     <pre class="command">
160     # yast -i wget patch gcc make ncurses-devel
161     </pre>
162    
163     <h3><a name="2.2">2.2. Download and patch the kernel</a></h3>
164    
165     <p>Download the kernel source from <a href="http://www.kernel.org/pub/linux/kernel/v2.6/">linux-2.6</a> or <a href="http://www.kernel.org/pub/linux/kernel/v3.0/">linux-3</a>.<br>
166     Linux kernel 2.6.27 and later are supported from the linux-2.6 tree.<br>
167     Linux kernel 3.0 and later are supported from the linux-3 tree.</p>
168    
169     <p>Extract the kernel source and go to the extracted directory.<br>
170 kumaneko 28 In the operations below, "$VERSION" should be replaced with appropriate kernel version. For example "3.3" if using Linux kernel 3.3.6, "2.6.27" if using Linux kernel 2.6.27.62.<br>
171     Also, there are several patches which can be applied to distributor's latest kernels. For example "2.6.32-centos-6.2" if using CentOS 6.2's latest kernel:</p>
172 kumaneko 15
173     <pre class="command">
174 kumaneko 27 $ wget -O caitsith-patch-0.1-20120505.tar.gz 'http://sourceforge.jp/frs/redir.php?m=jaist&amp;f=/caitsith/55464/caitsith-patch-0.1-20120505.tar.gz'
175     $ wget -O caitsith-patch-0.1-20120505.tar.gz.asc 'http://sourceforge.jp/frs/redir.php?m=jaist&amp;f=/caitsith/55464/caitsith-patch-0.1-20120505.tar.gz.asc'
176 kumaneko 15 $ wget http://I-love.SAKURA.ne.jp/kumaneko-key
177     $ gpg --import kumaneko-key
178 kumaneko 27 $ gpg caitsith-patch-0.1-20120505.tar.gz.asc
179     $ tar -zxf caitsith-patch-0.1-20120505.tar.gz
180 kumaneko 22 $ sed -i -e 's/CCSECURITY/CAITSITH/g' -e 's/ccsecurity/caitsith/g' -- patches/ccs-patch-*.diff
181 kumaneko 28 $ patch -sp1 &lt; patches/ccs-patch-$VERSION.diff
182 kumaneko 15 </pre>
183 kumaneko 10
184 kumaneko 15 <h3><a name="2.3">2.3. Configure the kernel</a></h3>
185 kumaneko 10
186 kumaneko 15 <pre class="command">
187     $ make -s menuconfig
188     </pre>
189 kumaneko 10
190 kumaneko 15 <p>Choose the following options in "Security options" section:</p>
191 kumaneko 10
192 kumaneko 15 <ul>
193     <li>[*] CaitSith support</li>
194     <li>[ ] &nbsp;&nbsp;Compile as loadable kernel module</li>
195     <li>[ ] &nbsp;&nbsp;Disable by default</li>
196     <li>[ ] &nbsp;&nbsp;Do not modify 'struct task_struct' in order to keep KABI</li>
197     <li>[ ] &nbsp;&nbsp;Activate without calling userspace policy loader.</li>
198 kumaneko 22 <li>(<code>/sbin/caitsith-init</code>) Location of userspace policy loader</li>
199     <li>(<code>/sbin/init</code>) Trigger for calling userspace policy loader</li>
200 kumaneko 15 <li>[*] &nbsp;&nbsp;Enable readdir operation restriction.</li>
201     <li>[*] &nbsp;&nbsp;Enable getattr operation restriction.</li>
202     <li>[*] &nbsp;&nbsp;Enable socket operation restriction.</li>
203     <li>[*] &nbsp;&nbsp;Enable non-POSIX capability operation restriction.</li>
204     <li>[*] &nbsp;&nbsp;Enable ptrace operation restriction.</li>
205     <li>[*] &nbsp;&nbsp;Enable kill operation restriction.</li>
206     <li>[*] &nbsp;&nbsp;Enable environment variable names/values restriction.</li>
207     <li>[*] &nbsp;&nbsp;Enable execute handler functionality.</li>
208     <li>[*] &nbsp;&nbsp;Enable domain transition without program execution request.</li>
209     <li>[*] &nbsp;&nbsp;Enable automatic domain transition.</li>
210     </ul>
211    
212     <p><em>"Compile as loadable kernel module"</em> is useful when there is a file size limitation for vmlinux (e.g. embedded systems).</p>
213    
214     <p><em>"Disable by default"</em> will enable CaitSith only when "caitsith=on" is passed to the kernel's command line options. If this option is not selected, "caitsith=off" will disable CaitSith.</p>
215    
216     <p><em>"Do not modify 'struct task_struct' in order to keep KABI"</em> will manage "struct task_struct" variables outside "struct task_struct" in order to avoid Kernel Application Binary Interface (KABI) breakage. Choose this option if wanting to patch against distributor's kernels without breaking KABI. However, since "struct caitsith_operations" must be exported to loadable kernel modules (LKMs) in order to allow them to call CaitSith's functions, build scripts may still print warning messages.</p>
217    
218 kumaneko 22 <p>There are two types of CaitSith's policy configuration. The former is embedded into the kernel and the latter is saved as files on the filesystems (e.g. <code>/etc/caitsith/</code> directory). You will need to rebuild the kernel whenever updating the former, but allows you to load policy without using userspace policy loader (e.g. <code>/sbin/caitsith-init</code>). The latter is loaded by executing userspace policy loader when the access control by CaitSith is about to be activated (e.g. when <code>/sbin/init</code> starts). <em>Activate without calling userspace policy loader.</em> allows you to activate access control by CaitSith as soon as the former is loaded. This option is useful when it is difficult to call policy loader (e.g. embedded systems).</p>
219 kumaneko 15
220     <p><em>Location of userspace policy loader</em> is available only when <em>Activate without calling userspace policy loader.</em> is not selected. This option specifies the default pathname of the userspace policy loader. You can override this setting via the "CCS_loader=" kernel command-line option.</p>
221    
222 kumaneko 22 <p><em>Trigger for calling userspace policy loader</em> is available only when <em>Activate without calling userspace policy loader.</em> is not selected. This option specifies the default pathname of the activation trigger. You can override this setting via the "CCS_trigger=" kernel command-line option. For example, if you pass "init=<code>/bin/systemd</code>" option, you may also want to pass "CCS_trigger=<code>/bin/systemd</code>" option.</p>
223 kumaneko 15
224     <h3><a name="2.4">2.4. Compile and install the kernel</a></h3>
225    
226 kumaneko 22 <p>The policy configuration which will be embedded into the kernel needs to exist as <code>security/caitsith/policy/policy.conf</code>. But you can proceed without creating that file because you don't have the policy configuration to embed as of this step. (You may come back here after you developed policy configuration to embed.)</p>
227 kumaneko 15
228     <p>Once the kernel has been configured, compile and install the kernel with the following commands:</p>
229    
230     <pre class="command">
231     $ make -s
232     $ su
233     # make -s modules_install install
234     </pre>
235    
236     <p>Create initrd/initramfs if required.</p>
237    
238     <h3><a name="2.5">2.5. Install the userspace tools</a></h3>
239    
240     <p>Make sure the dependencies described above have been installed. Compile and install the tools with the following commands:</p>
241    
242     <pre class="command">
243 kumaneko 27 $ wget -O caitsith-tools-0.1-20120505.tar.gz 'http://sourceforge.jp/frs/redir.php?m=jaist&amp;f=/caitsith/55465/caitsith-tools-0.1-20120505.tar.gz'
244     $ wget -O caitsith-tools-0.1-20120505.tar.gz.asc 'http://sourceforge.jp/frs/redir.php?m=jaist&amp;f=/caitsith/55465/caitsith-tools-0.1-20120505.tar.gz.asc'
245     $ gpg caitsith-tools-0.1-20120505.tar.gz.asc
246     $ tar -zxf caitsith-tools-0.1-20120505.tar.gz
247 kumaneko 10 $ cd caitsith-tools/
248 kumaneko 15 $ make -s USRLIBDIR=/usr/lib
249     $ su
250     # make -s USRLIBDIR=/usr/lib install
251     </pre>
252 kumaneko 10
253 kumaneko 22 <p>Please change USRLIBDIR=<code>/usr/lib</code> to USRLIBDIR=<code>/usr/lib64</code> (for 64bits userspace) or USRLIBDIR=<code>/usr/lib32</code> (for 32bits userspace) if needed.</p>
254 kumaneko 10
255 kumaneko 15 <p>Programs listed below are main userspace tools used for administrating CaitSith.</p>
256 kumaneko 10
257 kumaneko 15 <ul>
258 kumaneko 22 <li><code>/sbin/caitsith-init</code></li>
259     <li><code>/usr/sbin/caitsith-auditd</code></li>
260     <li><code>/usr/sbin/caitsith-loadpolicy</code></li>
261     <li><code>/usr/sbin/caitsith-notifyd</code></li>
262     <li><code>/usr/sbin/caitsith-pstree</code></li>
263     <li><code>/usr/sbin/caitsith-queryd</code></li>
264     <li><code>/usr/sbin/caitsith-savepolicy</code></li>
265 kumaneko 15 </ul>
266    
267 kumaneko 22 <p>You will probably want to add <code>/usr/sbin</code> to your PATH so that the commands can be run easily. If you are using <code>/bin/bash</code>, append the following line to <code>~/.bashrc</code>:</p>
268 kumaneko 15
269     <pre>
270     export PATH=$PATH:/usr/sbin
271     </pre>
272    
273     <h3><a name="2.6">2.6. Initializing configuration</a></h3>
274    
275 kumaneko 22 <p>Before you can make use of CaitSith, an initialization procedure must take place. This prepares the files in which policy information will be stored. All policy files are <strong>stored in the "<code>/etc/caitsith/</code>" directory</strong>.</p>
276 kumaneko 15
277     <p>Run the following command as root user to initialize:</p>
278    
279     <pre class="command">
280     # /usr/lib/caitsith/init_policy
281     </pre>
282     <pre class="output">
283     Creating policy directory... OK
284     Creating configuration directory... OK
285     Creating default policy... OK.
286     Creating module loader... OK.
287     Creating configuration file for caitsith-auditd ... OK.
288     Creating configuration file for caitsith-notifyd ... OK.
289     </pre>
290    
291 kumaneko 22 <p>CaitSith can generate audit logs and allows you to read them via <code>/proc/caitsith/audit</code> interface. To save <code>/proc/caitsith/audit</code> automatically, start <code>/usr/sbin/caitsith-auditd</code> from somewhere. Default setting (specified in <code>/etc/caitsith/tools/auditd.conf</code>) sends access allowed logs to <code>/dev/null</code>, access unmatched logs to <code>/var/log/caitsith/unmatched.log</code>, access denied logs to <code>/var/log/caitsith/denied.log</code>. (The meaning and example of allowed/unmatched/denied will be explained in <a href="#3.3">Example of simple access restriction rule</a>.)</p>
292 kumaneko 15
293 kumaneko 22 <p>CaitSith can ask for your decision about access requests which will be denied unless you grant them via <code>/proc/caitsith/query</code> interface. To notify immediately the occurrence of access requests which CaitSith is about to deny, start <code>/usr/sbin/caitsith-notifyd</code> from somewhere. Default setting (specified in <code>/etc/caitsith/tools/notifyd.conf</code>) sends mails to root@localhost with subject "Notification from caitsith-notifyd" up to once per a minute.</p>
294 kumaneko 15
295 kumaneko 22 <p>Below example launches <code>/usr/sbin/caitsith-auditd</code> and <code>/usr/sbin/caitsith-notifyd</code> from <code>/etc/rc.local</code> script:</p>
296 kumaneko 15
297     <pre>
298     #!/bin/sh
299     #
300     # This script will be executed *after* all the other init scripts.
301     # You can put your own initialization stuff in here if you don't
302     # want to do the full Sys V style init stuff.
303    
304     touch /var/lock/subsys/local
305     /usr/sbin/caitsith-auditd
306     /usr/sbin/caitsith-notifyd
307     </pre>
308    
309     <h3><a name="2.7">2.7. Configuring your bootloader</a></h3>
310    
311     <p>Now edit your bootloader (e.g. GRUB) to include the kernel you have just compiled. If the <em>"Disable by default"</em> option was selected during kernel configuration, remember to include "caitsith=on" in the kernel boot options. Consult the documentation for your distribution and bootloader to find out how to boot your CaitSith kernel.</p>
312    
313 kumaneko 22 <p>CaitSith supports the kernel boot option "CCS_trigger". This is useful for systems that run a program other than <code>/sbin/init</code> on startup, for example when booting using systemd which uses <code>/bin/systemd</code>. In this case, you should include "CCS_trigger=<code>/bin/systemd</code>" in the kernel boot options.</p>
314 kumaneko 15
315 kumaneko 16 <pre>
316     # grub.conf generated by anaconda
317     #
318     # Note that you do not have to rerun grub after making changes to this file
319     # NOTICE: You do not have a /boot partition. This means that
320     # all kernel and initrd paths are relative to /, eg.
321     # root (hd0,0)
322     # kernel /boot/vmlinuz-version ro root=/dev/sda1
323     # initrd /boot/initrd-[generic-]version.img
324     #boot=/dev/sda
325     default=1
326     timeout=5
327     splashimage=(hd0,0)/boot/grub/splash.xpm.gz
328     #hiddenmenu
329     title CentOS (3.2.14-caitsith)
330     root (hd0,0)
331     kernel /boot/vmlinuz-3.2.14-caitsith ro root=UUID=cc8371f3-bb2c-47b4-bd8f-318124f523df rd_NO_LUKS rd_NO_LVM rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=jp106 crashkernel=auto
332     initrd /boot/initramfs-3.2.14-caitsith.img
333     title CentOS (2.6.32-220.7.1.el6.i686)
334     root (hd0,0)
335     kernel /boot/vmlinuz-2.6.32-220.7.1.el6.i686 ro root=UUID=cc8371f3-bb2c-47b4-bd8f-318124f523df rd_NO_LUKS rd_NO_LVM rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=jp106 crashkernel=auto
336     initrd /boot/initramfs-2.6.32-220.7.1.el6.i686.img
337     </pre>
338    
339 kumaneko 15 <h3><a name="2.8">2.8. Rebooting your system</a></h3>
340    
341 kumaneko 16 <p>Now you have finished all preparation. Reboot your system and choose the entry with CaitSith kernel at the GRUB screen, or at whatever other bootloader you have installed:</p>
342 kumaneko 15
343 kumaneko 16 <img src="media/grub-screen.png" alt="grub-screen.png" title="Select CaitSith enabled kernel" width="640" height="480">
344 kumaneko 15
345     <p>If everything was installed properly and the bootloader was correctly configured, the kernel should boot as normal and CaitSith should be activated:</p>
346    
347 kumaneko 16 <img src="media/caitsith-activated.png" alt="caitsith-activated.png" title="CaitSith activated" width="720" height="400">
348 kumaneko 15
349     <h3><a name="2.9">2.9. How can I disable/uninstall CaitSith?</a></h3>
350    
351 kumaneko 28 <p>If your system becomes unable to boot during the course of this guide or any time in the future, it may be due to policy configuration or something related to CaitSith. If this is the case, it is possible that the kernel can still be booted by disabling CaitSith. This can be done by appending "caitsith=off" at the kernel's command line options.</p>
352 kumaneko 15
353     <p>CaitSith fortunately does not require the modification of any existing Linux binaries, libraries or applications. Thus, uninstalling CaitSith is very easy. It is simply a matter of uninstalling the kernel and userspace tools that you installed above. You can reboot with the kernel provided by your distribution and then remove the entry from your bootloader.</p>
354    
355 kumaneko 10 <h2><a name="how_to_develop_policy">3. How to develop policy</a></h2>
356    
357 kumaneko 16 <h3><a name="3.1">3.1. Policy file structure</a></h3>
358 kumaneko 10
359 kumaneko 16 <p>CaitSith's policy file consists with "Header part" and "ACL part".</p>
360 kumaneko 10
361 kumaneko 17 <h4><a name="3.1.1">3.1.1. Header part of policy file</a></h4>
362    
363 kumaneko 16 <p>Header part consists with below lines.</p>
364 kumaneko 10
365 kumaneko 16 <pre>
366     POLICY_VERSION=20120401
367 kumaneko 17 stat $stat_name $stat_value
368 kumaneko 16 quota memory policy $max_byte_for_policy
369     quota memory audit $max_byte_for_audit_logs
370     quota memory query $max_byte_for_query
371     quota audit[$audit_index] allowed=$max_logs_for_allowed_request unmatched=$max_logs_for_unmatched_request denied=$max_logs_for_denied_request
372     string_group $string_group_name $string_group_member
373     number_group $number_group_name $number_group_member
374     ip_group $ip_group_name $ip_group_member
375     </pre>
376 kumaneko 10
377 kumaneko 16 <ul>
378     <li>POLICY_VERSION line defines policy version.</li>
379 kumaneko 17 <li>stat lines are for showing statistics information such as memory usage. $stat_name and $stat_value are simply ignored.</li>
380 kumaneko 16 <li>$max_byte_for_policy is max amount of memory in byte which can be allocated for policy. Default is unlimited.</li>
381     <li>$max_byte_for_audit_logs is max amount of memory in byte which can be allocated for audit logs. Default is unlimited. $max_byte_for_audit_logs=16777216 should be sufficient.</li>
382     <li>$max_byte_for_query is max amount of memory in byte which can be allocated for interactive enforcement. Default is unlimited. $max_byte_for_audit_logs=1048576 should be sufficient.</li>
383     <li>quota audit[$audit_index] lines (0 &lt;= $audit_index &lt;= 255) are max number of audit logs which can be held in the kernel space. $max_logs_for_allowed_request is for allowed requests. $max_logs_for_unmatched_request is for unmatched requests. $max_logs_for_denied_request is for denied requests. Default is 0. Unless you have special reasons, you should set 0 to $max_logs_for_allowed_request. Regarding $max_logs_for_unmatched_request and $max_logs_for_denied_request, 1024 should be sufficient.</li>
384     <li>string_group $string_group_name lines define group of strings. $string_group_member is a member for $string_group_name group.</li>
385     <li>number_group $number_group_name lines define group of numbers. $number_group_member is a member for $number_group_name group.</li>
386     <li>ip_group $ip_group_name lines define group of IP addresses. $ip_group_member is a member for $ip_group_name group.</li>
387     </ul>
388 kumaneko 10
389 kumaneko 17 <h4><a name="3.1.2">3.1.2. ACL part of policy file</a></h4>
390 kumaneko 16
391 kumaneko 17 <p>ACL part consists with 0 or more repetitions of below block.</p>
392    
393 kumaneko 16 <pre>
394     $acl_priority acl $operation $conditions_to_filter
395     audit $audit_index
396     $cond_priority $decision $conditions_to_allow_or_deny
397     </pre>
398    
399     <ul>
400     <li>A block which starts with $acl_priority determines whether to evaluate rules in this block or not.</li>
401     <li>Blocks which start with $acl_priority can be defined as many as you need.</li>
402     <li>$acl_priority is a priority (an integer between 0 and 65535) which controls which block should be evaluated first (among all blocks defined in the policy).</li>
403     <li>Blocks are evaluated from smaller $acl_priority values to larger $acl_priority values.</li>
404     <li>If two blocks have same $acl_priority value, the block which is defined first is evaluated first.</li>
405     <li>$operation is "operation".</li>
406     <li>$conditions_to_filter is "conditional expressions" which can be applied to "operation". Omit $conditions_to_filter to evaluate this block unconditionally.</li>
407     <li>Access requests will be denied if one of deny lines (among all blocks defined in the policy) matches.</li>
408     </ul>
409    
410     <p>$decision lines in a block is evaluated only when the block's $acl_priority line matched.</p>
411    
412     <ul>
413     <li>A line which starts with $cond_priority determines whether to grant the access request or not.</li>
414     <li>Lines which start with $cond_priority can be defined as many as you need.</li>
415     <li>$cond_priority is a priority (an integer between 0 and 65535) which controls which line should be checked first (among all lines defined in the block).</li>
416     <li>Lines are checked from smaller $cond_priority values to larger priority values.</li>
417     <li>If two lines have same $cond_priority value, the line which is defined first is checked first.</li>
418     <li>$decision is either allow or deny.</li>
419     <li>$conditions_to_allow_or_deny is "conditional expressions" which can be applied to "operation". Omit $conditions_to_allow_or_deny to match this line unconditionally.</li>
420     </ul>
421    
422     <p>Checking of $decision lines in a block lasts until it matches a $decision line or it reaches to the end of block.</p>
423    
424     <ul>
425     <li>If $conditions_to_allow_or_deny of a deny line matches, the access request is denied. At the same time, access denied log is generated if memory used for audit logs is smaller than $max_byte_for_audit_logs bytes and number of denied logs which is in the kernel is smaller than $max_logs_for_denied_request of quota audit[$audit_index] line where $audit_index is specified by audit line of this block.</li>
426     <li>If $conditions_to_allow_or_deny of an allow line matches, the evaluation of this block ends and proceeds to next block. At the same time, access allowed log is generated if memory used for audit logs is smaller than $max_byte_for_audit_logs bytes and number of allowed logs which is in the kernel is smaller than $max_logs_for_allowed_request of quota audit[$audit_index] line where $audit_index is specified by audit line of this block.</li>
427     <li>If none of $conditions_to_allow_or_deny matches, the evaluation of this block ends and proceeds to next block. At the same time, access unmatched log is generated if memory used for audit logs is smaller than $max_byte_for_audit_logs bytes and number of unmatched logs which is in the kernel is smaller than $max_logs_for_unmatched_request of quota audit[$audit_index] line where $audit_index is specified by audit line of this block.</li>
428     </ul>
429    
430     <p>Access requests will be denied only when "deny" line of "acl" block matched. (There are two exceptions which will be explained later.)</p>
431    
432     <p>$acl_priority and $cond_priority values are used for two purposes. One is for selectively deny operations using "deny" lines. For example,</p>
433    
434     <pre>
435     10 acl read path.fsmagic=0x9FA0
436     audit 0
437     10 deny path="proc:/cmdline"
438     20 allow
439     </pre>
440    
441 kumaneko 22 <p>denies opening <code>/proc/cmdline</code> on the proc filesystem (proc filesystem's magic number is 0x9FA0) for reading while allowing opening all other files.</p>
442 kumaneko 16
443     <p>The other is for controlling which "transition=" and "handler=" arguments should be used when these arguments matched more than once. This will be explained later.</p>
444    
445 kumaneko 17 <h4><a name="3.1.3">3.1.3. An example policy file</a></h4>
446    
447 kumaneko 22 <p>Below is an example of <code>/etc/caitsith/policy/current</code> file on CentOS. The content of this file varies depending on environments you are using, and will be updated as you develop policy.</p>
448 kumaneko 16
449     <pre>
450     POLICY_VERSION=20120401
451    
452     quota memory audit 16777216
453     quota memory query 1048576
454     quota audit[1] allowed=0 denied=1024 unmatched=1024
455    
456     10000 acl execute
457     audit 0
458     10 allow path="/sbin/modprobe" transition="/sbin/modprobe"
459     10 allow path="/sbin/init" transition="/sbin/init"
460     10 allow path="/sbin/mingetty" transition="/sbin/mingetty"
461     10 allow path="/sbin/udevd" transition="/sbin/udevd"
462     10 allow path="/usr/sbin/anacron" transition="/usr/sbin/anacron"
463     10 allow path="/usr/sbin/crond" transition="/usr/sbin/crond"
464     10 allow path="/usr/sbin/httpd" transition="/usr/sbin/httpd"
465     10 allow path="/usr/sbin/logrotate" transition="/usr/sbin/logrotate"
466     10 allow path="/usr/sbin/nmbd" transition="/usr/sbin/nmbd"
467     10 allow path="/usr/sbin/smbd" transition="/usr/sbin/smbd"
468     10 allow path="/usr/sbin/sshd" transition="/usr/sbin/sshd"
469     10 allow path="/etc/rc.d/init.d/ntpd" transition="/etc/rc.d/init.d/ntpd"
470     10 allow path="/etc/rc.d/init.d/single" transition="/etc/rc.d/init.d/single"
471     10 allow path="/etc/rc.d/init.d/killall" transition="/etc/rc.d/init.d/killall"
472     10 allow path="/etc/rc.d/init.d/ip6tables" transition="/etc/rc.d/init.d/ip6tables"
473     10 allow path="/etc/rc.d/init.d/halt" transition="/etc/rc.d/init.d/halt"
474     10 allow path="/etc/rc.d/init.d/netfs" transition="/etc/rc.d/init.d/netfs"
475     10 allow path="/etc/rc.d/init.d/messagebus" transition="/etc/rc.d/init.d/messagebus"
476     10 allow path="/etc/rc.d/init.d/sandbox" transition="/etc/rc.d/init.d/sandbox"
477     10 allow path="/etc/rc.d/init.d/rsyslog" transition="/etc/rc.d/init.d/rsyslog"
478     10 allow path="/etc/rc.d/init.d/smb" transition="/etc/rc.d/init.d/smb"
479     10 allow path="/etc/rc.d/init.d/sshd" transition="/etc/rc.d/init.d/sshd"
480     10 allow path="/etc/rc.d/init.d/cgconfig" transition="/etc/rc.d/init.d/cgconfig"
481     10 allow path="/etc/rc.d/init.d/udev-post" transition="/etc/rc.d/init.d/udev-post"
482     10 allow path="/etc/rc.d/init.d/firstboot" transition="/etc/rc.d/init.d/firstboot"
483     10 allow path="/etc/rc.d/init.d/ntpdate" transition="/etc/rc.d/init.d/ntpdate"
484     10 allow path="/etc/rc.d/init.d/crond" transition="/etc/rc.d/init.d/crond"
485     10 allow path="/etc/rc.d/init.d/restorecond" transition="/etc/rc.d/init.d/restorecond"
486     10 allow path="/etc/rc.d/init.d/httpd" transition="/etc/rc.d/init.d/httpd"
487     10 allow path="/etc/rc.d/init.d/rdisc" transition="/etc/rc.d/init.d/rdisc"
488     10 allow path="/etc/rc.d/init.d/postfix" transition="/etc/rc.d/init.d/postfix"
489     10 allow path="/etc/rc.d/init.d/saslauthd" transition="/etc/rc.d/init.d/saslauthd"
490     10 allow path="/etc/rc.d/init.d/netconsole" transition="/etc/rc.d/init.d/netconsole"
491     10 allow path="/etc/rc.d/init.d/network" transition="/etc/rc.d/init.d/network"
492     10 allow path="/etc/rc.d/init.d/avahi-daemon" transition="/etc/rc.d/init.d/avahi-daemon"
493     10 allow path="/etc/rc.d/init.d/auditd" transition="/etc/rc.d/init.d/auditd"
494     10 allow path="/etc/rc.d/init.d/nmb" transition="/etc/rc.d/init.d/nmb"
495     10 allow path="/etc/rc.d/init.d/iptables" transition="/etc/rc.d/init.d/iptables"
496     10 allow path="/etc/rc.d/init.d/cgred" transition="/etc/rc.d/init.d/cgred"
497    
498     0 acl modify_policy
499     audit 1
500     1 deny task.uid!=0
501     1 deny task.euid!=0
502     100 allow task.exe="/usr/sbin/caitsith-loadpolicy"
503     100 allow task.exe="/usr/sbin/caitsith-queryd"
504     10000 deny
505     </pre>
506    
507     <h3><a name="3.2">3.2. Updating policy configuration</a></h3>
508    
509     <p>There are two ways to update policy configuration.</p>
510    
511 kumaneko 22 <p>One is to use <code>/sbin/caitsith-init</code> which is automatically called when <code>/sbin/init</code> starts. <code>/sbin/caitsith-init</code> reads policy from <code>/etc/caitsith/policy/current</code> and writes to <code>/proc/caitsith/policy</code> interface. Therefore, you can update policy configuration by updating <code>/etc/caitsith/policy/current</code> and rebooting your system.</p>
512 kumaneko 16
513 kumaneko 22 <p>The other is to use <code>/usr/sbin/caitsith-loadpolicy</code> which is defined for loading policy after your system has booted. <code>/usr/sbin/caitsith-loadpolicy</code> reads policy from standard input and writes to <code>/proc/caitsith/policy</code> interface. Therefore, you can update policy configuration without updating <code>/etc/caitsith/policy/current</code> and rebooting your system. For example, if you want to append a "string_group mygroup1 /" line to <code>/proc/caitsith/policy</code> interface, run below command:</p>
514 kumaneko 16
515     <pre class="command">
516     # echo 'string_group mygroup1 /' | /usr/sbin/caitsith-loadpolicy
517     </pre>
518    
519 kumaneko 22 <p>If you want to delete the "string_group mygroup1 /" line from <code>/proc/caitsith/policy</code> interface, run below command:</p>
520 kumaneko 16
521     <pre class="command">
522     # echo 'delete string_group mygroup1 /' | /usr/sbin/caitsith-loadpolicy
523     </pre>
524    
525 kumaneko 22 <p>The contents in <code>/proc/caitsith/policy</code> will be lost when your system shuts down or reboots. To save <code>/proc/caitsith/policy</code> as <code>/etc/caitsith/policy/current</code>, run below command:</p>
526 kumaneko 16
527     <pre class="command">
528     # /usr/sbin/caitsith-savepolicy
529     </pre>
530    
531     <h3><a name="3.3">3.3. Example of simple access restriction rule</a></h3>
532    
533 kumaneko 17 <p>Let's experience how CaitSith restricts access using simple examples.</p>
534    
535     <h4><a name="3.3.1">3.3.1. Telling CaitSith which access requests should be checked</a></h4>
536    
537     <p>By default, CaitSith does not deny access requests. To restrict access requests, you need to tell CaitSith which access requests should be denied.</p>
538    
539 kumaneko 22 <p>Below rule will check access requests which open <code>/tmp/file1</code> for reading.</p>
540 kumaneko 17
541     <pre>
542     100 acl read path="/tmp/file1"
543     audit 1
544     </pre>
545    
546 kumaneko 22 <p>Append above rule using <code>/usr/sbin/caitsith-loadpolicy</code>. Since <code>/usr/sbin/caitsith-loadpolicy</code> reads policy from standard input, you can use ^D (Ctrl-D) to indicate end of input:</p>
547 kumaneko 17
548     <pre class="command">
549     # /usr/sbin/caitsith-loadpolicy
550     </pre>
551     <pre>
552     100 acl read path="/tmp/file1"
553     audit 1
554     ^D
555     </pre>
556    
557     <p>You may use a temporary file if you worry typos.</p>
558    
559     <pre class="command">
560     # cat &gt; ~/policy.tmp
561     </pre>
562     <pre>
563     100 acl read path="/tmp/file1"
564     audit 1
565     ^D
566     </pre>
567     <pre class="command">
568     # /usr/sbin/caitsith-loadpolicy &lt; ~/policy.tmp
569     # rm ~/policy.tmp
570     </pre>
571    
572 kumaneko 22 <p>You can confirm that above rule is appended to <code>/proc/caitsith/policy</code> by reading <code>/proc/caitsith/policy</code>.</p>
573 kumaneko 17
574     <pre class="command">
575     # cat /proc/caitsith/policy
576     </pre>
577     <pre>
578     POLICY_VERSION=20120401
579     stat Policy updated: 7 (Last: 2012/04/08 04:56:45)
580     stat Requests denied: 0
581     stat Memory used by policy: 6048
582     stat Memory used by audit: 0
583     stat Memory used by query: 0
584     quota memory audit 16777216
585     quota memory query 1048576
586     quota audit[1] allowed=0 denied=1024 unmatched=1024
587    
588     10000 acl execute
589     audit 0
590     10 allow path="/sbin/modprobe" transition="/sbin/modprobe"
591     10 allow path="/sbin/init" transition="/sbin/init"
592     10 allow path="/sbin/mingetty" transition="/sbin/mingetty"
593     10 allow path="/sbin/udevd" transition="/sbin/udevd"
594     10 allow path="/usr/sbin/anacron" transition="/usr/sbin/anacron"
595     10 allow path="/usr/sbin/crond" transition="/usr/sbin/crond"
596     10 allow path="/usr/sbin/httpd" transition="/usr/sbin/httpd"
597     10 allow path="/usr/sbin/logrotate" transition="/usr/sbin/logrotate"
598     10 allow path="/usr/sbin/nmbd" transition="/usr/sbin/nmbd"
599     10 allow path="/usr/sbin/smbd" transition="/usr/sbin/smbd"
600     10 allow path="/usr/sbin/sshd" transition="/usr/sbin/sshd"
601     10 allow path="/etc/rc.d/init.d/ntpd" transition="/etc/rc.d/init.d/ntpd"
602     10 allow path="/etc/rc.d/init.d/single" transition="/etc/rc.d/init.d/single"
603     10 allow path="/etc/rc.d/init.d/killall" transition="/etc/rc.d/init.d/killall"
604     10 allow path="/etc/rc.d/init.d/ip6tables" transition="/etc/rc.d/init.d/ip6tables"
605     10 allow path="/etc/rc.d/init.d/halt" transition="/etc/rc.d/init.d/halt"
606     10 allow path="/etc/rc.d/init.d/netfs" transition="/etc/rc.d/init.d/netfs"
607     10 allow path="/etc/rc.d/init.d/messagebus" transition="/etc/rc.d/init.d/messagebus"
608     10 allow path="/etc/rc.d/init.d/sandbox" transition="/etc/rc.d/init.d/sandbox"
609     10 allow path="/etc/rc.d/init.d/rsyslog" transition="/etc/rc.d/init.d/rsyslog"
610     10 allow path="/etc/rc.d/init.d/smb" transition="/etc/rc.d/init.d/smb"
611     10 allow path="/etc/rc.d/init.d/sshd" transition="/etc/rc.d/init.d/sshd"
612     10 allow path="/etc/rc.d/init.d/cgconfig" transition="/etc/rc.d/init.d/cgconfig"
613     10 allow path="/etc/rc.d/init.d/udev-post" transition="/etc/rc.d/init.d/udev-post"
614     10 allow path="/etc/rc.d/init.d/firstboot" transition="/etc/rc.d/init.d/firstboot"
615     10 allow path="/etc/rc.d/init.d/ntpdate" transition="/etc/rc.d/init.d/ntpdate"
616     10 allow path="/etc/rc.d/init.d/crond" transition="/etc/rc.d/init.d/crond"
617     10 allow path="/etc/rc.d/init.d/restorecond" transition="/etc/rc.d/init.d/restorecond"
618     10 allow path="/etc/rc.d/init.d/httpd" transition="/etc/rc.d/init.d/httpd"
619     10 allow path="/etc/rc.d/init.d/rdisc" transition="/etc/rc.d/init.d/rdisc"
620     10 allow path="/etc/rc.d/init.d/postfix" transition="/etc/rc.d/init.d/postfix"
621     10 allow path="/etc/rc.d/init.d/saslauthd" transition="/etc/rc.d/init.d/saslauthd"
622     10 allow path="/etc/rc.d/init.d/netconsole" transition="/etc/rc.d/init.d/netconsole"
623     10 allow path="/etc/rc.d/init.d/network" transition="/etc/rc.d/init.d/network"
624     10 allow path="/etc/rc.d/init.d/avahi-daemon" transition="/etc/rc.d/init.d/avahi-daemon"
625     10 allow path="/etc/rc.d/init.d/auditd" transition="/etc/rc.d/init.d/auditd"
626     10 allow path="/etc/rc.d/init.d/nmb" transition="/etc/rc.d/init.d/nmb"
627     10 allow path="/etc/rc.d/init.d/iptables" transition="/etc/rc.d/init.d/iptables"
628     10 allow path="/etc/rc.d/init.d/cgred" transition="/etc/rc.d/init.d/cgred"
629    
630     100 acl read path="/tmp/file1"
631     audit 1
632    
633     0 acl modify_policy
634     audit 1
635     1 deny task.uid!=0
636     1 deny task.euid!=0
637     100 allow task.exe="/usr/sbin/caitsith-loadpolicy"
638     100 allow task.exe="/usr/sbin/caitsith-queryd"
639     10000 deny
640     </pre>
641    
642     <h4><a name="3.3.2">3.3.2. Access requests which will be implicitly allowed by CaitSith</a></h4>
643    
644 kumaneko 22 <p>Make sure that <code>/usr/sbin/caitsith-auditd</code> is running.</p>
645 kumaneko 17
646     <pre class="command">
647     # pidof caitsith-auditd
648     </pre>
649     <pre>
650     3627
651     </pre>
652    
653 kumaneko 22 <p>Now, create <code>/tmp/file1</code> file.</p>
654 kumaneko 17
655     <pre class="command">
656     # touch /tmp/file1
657     </pre>
658    
659 kumaneko 22 <p>Then, open <code>/tmp/file1</code> for reading.</p>
660 kumaneko 17
661     <pre class="command">
662     # cat /tmp/file1
663     </pre>
664    
665 kumaneko 22 <p>Check <code>/var/log/caitsith/unmatched.log</code> for access unmatched log of this access request. You will find an entry like below:</p>
666 kumaneko 17
667     <pre class="command">
668     # grep /tmp/file1 /var/log/caitsith/unmatched.log
669     </pre>
670     <pre>
671     #2012/04/08 04:58:40# global-pid=3678 result=unmatched priority=100 / read path="/tmp/file1" task.pid=3678 task.ppid=3653 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=0 path.ino=2113451 path.major=8 path.minor=1 path.perm=0644 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=2097153 path.parent.major=8 path.parent.minor=1 path.parent.perm=01777 path.parent.type=directory path.parent.fsmagic=0xEF53
672     </pre>
673    
674 kumaneko 19 <p>Note the <strong>result=unmatched</strong> part of the entry. This indicates that access request was checked but matched neither "allow" nor "deny" rule.</p>
675 kumaneko 17
676 kumaneko 19 <p>Note the <strong>priority=100</strong> part of the entry. This indicates that this entry was generated by rules which have 100 as priority.</p>
677 kumaneko 17
678 kumaneko 22 <p>Note the <strong>read path="<code>/tmp/file1</code>"</strong> part of the entry. This indicates that this entry was generated by access request of opening <code>/tmp/file1</code> for reading.</p>
679 kumaneko 17
680     <h4><a name="3.3.3">3.3.3. Access requests which will be explicitly denied by CaitSith</a></h4>
681    
682     <p>Now, let's add a rule to explicitly deny this request.</p>
683    
684     <pre>
685     100 acl read path="/tmp/file1"
686     1000 deny
687     </pre>
688    
689 kumaneko 22 <p>Append above rule using <code>/usr/sbin/caitsith-loadpolicy</code>:</p>
690 kumaneko 17
691     <pre class="command">
692     # /usr/sbin/caitsith-loadpolicy
693     </pre>
694     <pre>
695     100 acl read path="/tmp/file1"
696     1000 deny
697     ^D
698     </pre>
699    
700 kumaneko 22 <p>Rules that have same priority (in this rule, 100) and same operation (in this rule, read) and same condition (in this rule, path="<code>/tmp/file1</code>") are automatically merged. Therefore, you will find</p>
701 kumaneko 17
702     <pre>
703     100 acl read path="/tmp/file1"
704     audit 1
705     1000 deny
706     </pre>
707    
708     <p>rather than</p>
709    
710     <pre>
711     100 acl read path="/tmp/file1"
712     audit 1
713    
714     100 acl read path="/tmp/file1"
715     1000 deny
716     </pre>
717    
718 kumaneko 22 <p>when you read <code>/proc/caitsith/policy</code>.</p>
719 kumaneko 17
720 kumaneko 22 <p>Then, open <code>/tmp/file1</code> for reading.</p>
721 kumaneko 17
722     <pre class="command">
723     # cat /tmp/file1
724     </pre>
725     <pre>
726     cat: /tmp/file1: Operation not permitted
727     </pre>
728    
729     <p>This time, access request was denied by CaitSith.</p>
730    
731 kumaneko 22 <p>Check <code>/var/log/caitsith/denied.log</code> for access denied log of this access request. You will find an entry like below:</p>
732 kumaneko 17
733     <pre class="command">
734     # grep /tmp/file1 /var/log/caitsith/denied.log
735     </pre>
736     <pre>
737     #2012/04/08 04:59:53# global-pid=3682 result=denied priority=100 / read path="/tmp/file1" task.pid=3682 task.ppid=3653 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=0 path.ino=2113451 path.major=8 path.minor=1 path.perm=0644 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=2097153 path.parent.major=8 path.parent.minor=1 path.parent.perm=01777 path.parent.type=directory path.parent.fsmagic=0xEF53
738     </pre>
739    
740 kumaneko 19 <p>Note the <strong>result=denied</strong> part of the entry. This indicates that access request was checked and matched "deny" rule.</p>
741 kumaneko 17
742 kumaneko 22 <p>If <code>/usr/sbin/ccs-notifyd</code> is running, you will receive a notification mail. The content is same with access denied logs.</p>
743 kumaneko 17
744     <pre class="command">
745     # mail
746     </pre>
747     <pre>
748     Heirloom Mail version 12.4 7/29/08. Type ? for help.
749     "/var/spool/mail/root": 1 message 1 new
750     &gt;N 1 root Sun Apr 8 13:59 20/1231 "Notification from caitsith-notifyd"
751     &amp;
752     Message 1:
753     From root@ccsecurity.localdomain Sun Apr 8 13:59:53 2012
754     Return-Path: &lt;root@ccsecurity.localdomain&gt;
755     X-Original-To: root@localhost
756     Delivered-To: root@localhost.localdomain
757     Date: Sun, 08 Apr 2012 13:59:53 +0900
758     To: root@localhost.localdomain
759     Subject: Notification from caitsith-notifyd
760     User-Agent: Heirloom mailx 12.4 7/29/08
761     Content-Type: text/plain; charset=us-ascii
762     From: root@caitsith.localdomain (root)
763     Status: R
764    
765     Q0-0
766     #2012/04/08 04:59:53# global-pid=3682 result=denied priority=100 / read path="/tmp/file1" task.pid=3682 task.ppid=3653 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=0 path.ino=2113451 path.major=8 path.minor=1 path.perm=0644 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=2097153 path.parent.major=8 path.parent.minor=1 path.parent.perm=01777 path.parent.type=directory path.parent.fsmagic=0xEF53
767     </pre>
768    
769     <p>Now, let's remove a rule to explicitly deny this request.</p>
770    
771     <pre>
772     100 acl read path="/tmp/file1"
773     delete 1000 deny
774     </pre>
775    
776 kumaneko 22 <p>Append above rule using <code>/usr/sbin/caitsith-loadpolicy</code>:</p>
777 kumaneko 17
778     <pre class="command">
779     # /usr/sbin/caitsith-loadpolicy
780     </pre>
781     <pre>
782     100 acl read path="/tmp/file1"
783     delete 1000 deny
784     ^D
785     </pre>
786    
787     <p>You will find</p>
788    
789     <pre>
790     100 acl read path="/tmp/file1"
791     audit 1
792     </pre>
793    
794     <p>rather than</p>
795    
796     <pre>
797     100 acl read path="/tmp/file1"
798     audit 1
799     1000 deny
800     delete 1000 deny
801     </pre>
802    
803 kumaneko 22 <p>when you read <code>/proc/caitsith/policy</code>.</p>
804 kumaneko 17
805     <h4><a name="3.3.4">3.3.4. Filtering audit logs</a></h4>
806    
807 kumaneko 22 <p>Now, open <code>/tmp/file1</code> for reading.</p>
808 kumaneko 17
809     <pre class="command">
810     # cat /tmp/file1
811     </pre>
812    
813 kumaneko 22 <p>Check <code>/var/log/caitsith/unmatched.log</code> for access unmatched log of this access request. You will find entries like below:</p>
814 kumaneko 17
815     <pre class="command">
816     # grep /tmp/file1 /var/log/caitsith/unmatched.log
817     </pre>
818     <pre>
819     #2012/04/08 04:58:40# global-pid=3678 result=unmatched priority=100 / read path="/tmp/file1" task.pid=3678 task.ppid=3653 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=0 path.ino=2113451 path.major=8 path.minor=1 path.perm=0644 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=2097153 path.parent.major=8 path.parent.minor=1 path.parent.perm=01777 path.parent.type=directory path.parent.fsmagic=0xEF53
820     #2012/04/08 05:01:00# global-pid=3695 result=unmatched priority=100 / read path="/tmp/file1" task.pid=3695 task.ppid=3653 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=0 path.ino=2113451 path.major=8 path.minor=1 path.perm=0644 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=2097153 path.parent.major=8 path.parent.minor=1 path.parent.perm=01777 path.parent.type=directory path.parent.fsmagic=0xEF53
821     </pre>
822    
823     <p>The former entry was generated before adding explicit "deny" rule. The latter entry was generated after removing explicit "deny" rule. You might want to filter the output using tail command:</p>
824    
825     <pre class="command">
826     # grep /tmp/file1 /var/log/caitsith/unmatched.log | tail -n 1
827     </pre>
828     <pre>
829     #2012/04/08 05:01:00# global-pid=3695 result=unmatched priority=100 / read path="/tmp/file1" task.pid=3695 task.ppid=3653 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=0 path.ino=2113451 path.major=8 path.minor=1 path.perm=0644 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=2097153 path.parent.major=8 path.parent.minor=1 path.parent.perm=01777 path.parent.type=directory path.parent.fsmagic=0xEF53
830     </pre>
831    
832     <h4><a name="3.3.5">3.3.5. Access requests which will be explicitly allowed by CaitSith</a></h4>
833    
834     <p>Next, let's see audit logs with explicitly matching "allow" rules.</p>
835    
836     <p>By default CaitSith does not generate audit logs with explicitly matching "allow" rules. Change policy configuration to generate such logs.</p>
837    
838     <pre>
839     quota audit[1] allowed=1024
840     </pre>
841    
842 kumaneko 22 <p>Append above rule using <code>/usr/sbin/caitsith-loadpolicy</code>:</p>
843 kumaneko 17
844     <pre class="command">
845     # echo 'quota audit[1] allowed=1024' | /usr/sbin/caitsith-loadpolicy
846     </pre>
847    
848     <p>Preferences that have same name (in this rule, audit[1]) are automatically merged. Therefore, you will find</p>
849    
850     <pre>
851     quota audit[1] allowed=1024 denied=1024 unmatched=1024
852     </pre>
853    
854     <p>rather than</p>
855    
856     <pre>
857     quota audit[1] allowed=0 denied=1024 unmatched=1024
858     quota audit[1] allowed=1024
859     </pre>
860    
861 kumaneko 22 <p>when you read <code>/proc/caitsith/policy</code>.</p>
862 kumaneko 17
863     <pre>
864     100 acl read path="/tmp/file1"
865     1000 allow
866     </pre>
867    
868 kumaneko 22 <p>Append above rule using <code>/usr/sbin/caitsith-loadpolicy</code>:</p>
869 kumaneko 17
870     <pre class="command">
871     # /usr/sbin/caitsith-loadpolicy
872     </pre>
873     <pre>
874     100 acl read path="/tmp/file1"
875     1000 allow
876     ^D
877     </pre>
878    
879 kumaneko 22 <p>Since audit logs with explicitly matching "allow" rules tend to grow rapidly, by default <code>/usr/sbin/caitsith-auditd</code> discards such logs by writing to <code>/dev/null</code> (specified in <code>/etc/caitsith/tools/auditd.conf</code>).
880     Therefore, temporarily stop <code>/usr/sbin/caitsith-auditd</code> process in order to read audit logs from <code>/proc/caitsith/audit</code> interface.</p>
881 kumaneko 17
882     <pre class="command">
883     # killall -KILL caitsith-auditd
884     </pre>
885    
886 kumaneko 22 <p>Then, open <code>/tmp/file1</code> for reading.</p>
887 kumaneko 17
888     <pre class="command">
889     # cat /tmp/file1
890     </pre>
891    
892 kumaneko 22 <p>Check <code>/proc/caitsith/audit</code> for audit log of this access request. This time, you will find an entry like below:</p>
893 kumaneko 17
894     <pre class="command">
895     # cat -v /proc/caitsith/audit
896     </pre>
897     <pre>
898     #2012/04/08 05:03:03# global-pid=3720 result=allowed priority=100 / read path="/tmp/file1" task.pid=3720 task.ppid=3653 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=0 path.ino=2113451 path.major=8 path.minor=1 path.perm=0644 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=2097153 path.parent.major=8 path.parent.minor=1 path.parent.perm=01777 path.parent.type=directory path.parent.fsmagic=0xEF53
899     ^@
900     </pre>
901    
902 kumaneko 19 <p>Note the <strong>result=allowed</strong> part of the entry. This indicates that access request was checked and matched "allow" rule.</p>
903 kumaneko 17
904 kumaneko 22 <p>Restart <code>/usr/sbin/caitsith-auditd</code> process.</p>
905 kumaneko 17
906     <pre class="command">
907     # /usr/sbin/caitsith-auditd
908     </pre>
909    
910     <p>Also, restore the audit logs configuration:</p>
911    
912     <pre>
913     quota audit[1] allowed=0
914     </pre>
915    
916 kumaneko 22 <p>Append above rule using <code>/usr/sbin/caitsith-loadpolicy</code>:</p>
917 kumaneko 17
918     <pre class="command">
919     # echo 'quota audit[1] allowed=0' | /usr/sbin/caitsith-loadpolicy
920     </pre>
921    
922 kumaneko 20 <h3><a name="3.4">3.4. Understanding two viewpoints</a></h3>
923 kumaneko 18
924 kumaneko 20 <p>CaitSith supports writing access restriction rules from two viewpoints. One is from the point of view of "subject" (a resource which requests access on object). The other is from the point of view of "object" (a resource which subject requests access).</p>
925    
926     <p>The advantage of the former approach is that the rules clearly explains and restricts what each subject is allowed to access which object.
927     This approach is powerful when you can afford identifying all possible subjects and defining the rules for each subject.
928     But the disadvantage is that it is difficult to identify all possible subjects and define the rules for each subject.
929     Therefore, in reality, this approach tends to restrict only specific subjects.
930     If one of subjects which is not restricted by this approach is cracked or misbehaved, nothing can protect objects you want to protect.</p>
931    
932     <p>The advantage of the latter approach is that the rules clearly explains and restricts what object might be accessed by which subject.
933     This approach is powerful when you can afford identifying objects you want to protect and defining rules for each object.
934     This approach can compensate for the disadvantage of the former approach because this approach can restrict access even it is difficult to
935     identify all possible subjects and define the rules for each possible subjects.</p>
936    
937     <h4><a name="3.4.1">3.4.1. Writing access restriction rules from the point of view of "subject".</a></h4>
938    
939 kumaneko 22 <p>Below entry is an example of restricting programs which can be executed from <code>/usr/sbin/httpd</code> program.</p>
940 kumaneko 20
941     <pre>
942     0 acl execute task.exe="/usr/sbin/httpd"
943     audit 1
944     1 allow path="/var/www/cgi-bin/counter.cgi"
945     100 deny
946     </pre>
947    
948 kumaneko 22 <p>The <strong>0 acl execute task.exe="<code>/usr/sbin/httpd</code>"</strong> line means check rules for executing programs from <code>/usr/sbin/httpd</code> program. Since <strong>task.exe="<code>/usr/sbin/httpd</code>"</strong> is specified in this line, this line tells CaitSith <strong>check rules for executing programs only if current thread's program name is <code>/usr/sbin/httpd</code></strong>.</p>
949 kumaneko 20
950 kumaneko 22 <p>The line <strong>1 allow path="<code>/var/www/cgi-bin/counter.cgi</code>"</strong> means that allow if the pathname of the program to execute is <code>/var/www/cgi-bin/counter.cgi</code>. This line tells CaitSith "allow execution of <code>/var/www/cgi-bin/counter.cgi</code>".</p>
951 kumaneko 20
952     <p>The line <strong>100 deny</strong> means deny unconditionally. This tells CaitSith "unconditionally deny execution of programs".</p>
953    
954 kumaneko 22 <p>Since the line starting with <strong>1 allow</strong> has higher priority than the line starting with <strong>100 deny</strong>, CaitSith will allow execution of <code>/var/www/cgi-bin/counter.cgi</code>.</p>
955 kumaneko 20
956 kumaneko 22 <p>To summarize this rule, <code>/usr/sbin/httpd</code> can execute <strong>only</strong> <code>/var/www/cgi-bin/counter.cgi</code>.</p>
957 kumaneko 20
958 kumaneko 22 <p>The line <strong>audit 1</strong> means that use audit rules defined in the <strong>quota audit[1]</strong> line. This line tells CaitSith generate audit logs up to entries defined in the <strong>quota audit[1]</strong> line. The default configuration generated by executing <code>/usr/lib/caitsith/init_policy</code> command is</p>
959 kumaneko 20
960     <pre>
961     quota audit[1] allowed=0 denied=1024 unmatched=1024
962     </pre>
963    
964 kumaneko 22 <p>which means do not generate audit logs if matched an "allow" line and generate audit logs up to 1024 entries if matched a "deny" line and generate audit logs up to 1024 lines if matched neither an "allow" line nor a "deny" line. Though, since the block starting with <strong>0 acl execute task.exe="<code>/usr/sbin/httpd</code>"</strong> is terminated with explicit <strong>100 deny</strong> line, this block shall match either an "allow" line or a "deny" line.</p>
965 kumaneko 20
966     <h4><a name="3.4.2">3.4.2. Writing access restriction rules from the point of view of "object".</a></h4>
967    
968 kumaneko 22 <p>Below entry is default configuration generated by executing <code>/usr/lib/caitsith/init_policy</code> command.</p>
969 kumaneko 20
970     <pre>
971     0 acl modify_policy
972     audit 1
973     1 deny task.uid!=0
974     1 deny task.euid!=0
975     100 allow task.exe="/usr/sbin/caitsith-loadpolicy"
976     100 allow task.exe="/usr/sbin/caitsith-queryd"
977     10000 deny
978     </pre>
979    
980 kumaneko 22 <p>The <strong>0 acl modify_policy</strong> line means check rules for modifying policy configuration via <code>/proc/caitsith/policy</code> interface. Since no additional conditions are specified in this line, this line tells CaitSith <strong>unconditionally check</strong> rules for modifying policy configuration via <code>/proc/caitsith/policy</code> interface.</p>
981 kumaneko 20
982 kumaneko 22 <p>The line <strong>1 deny task.uid!=0</strong> means that deny if current thread's user ID is not 0. This line tells CaitSith "deny modification of policy configuration via <code>/proc/caitsith/policy</code> interface if current thread's user ID is not 0".</p>
983 kumaneko 20
984 kumaneko 22 <p>The line <strong>1 deny task.euid!=0</strong> means that deny if current thread's effective user ID is not 0. This line tells CaitSith "deny modification of policy configuration via <code>/proc/caitsith/policy</code> interface if current thread's effective user ID is not 0".</p>
985 kumaneko 20
986     <p>Note the difference between</p>
987    
988     <pre>
989     1 deny task.uid!=0
990     1 deny task.euid!=0
991     </pre>
992    
993     <p>and</p>
994    
995     <pre>
996     1 deny task.uid!=0 task.euid!=0
997     </pre>
998    
999     <p>. The former conditions tell CaitSith "deny if current thread's user ID is not 0 <strong>or</strong> current thread's effective user ID is not 0", while the latter conditions tell CaitSith "deny if current thread's user ID is not 0 <strong>and</strong> current thread's effective user ID is not 0".</p>
1000    
1001 kumaneko 22 <p>The line <strong>100 allow task.exe="<code>/usr/sbin/caitsith-loadpolicy</code>"</strong> means that allow if current thread's program name is <code>/usr/sbin/caitsith-loadpolicy</code>. This tells CaitSith finish evaluation of this block starting with the <strong>0 acl modify_policy</strong> line if current thread's program name is <code>/usr/sbin/caitsith-loadpolicy</code>. If there are more blocks, CaitSith will evaluate them. If there are no more blocks, CaitSith will allow modifying policy configuration via <code>/proc/caitsith/policy</code> interface.</p>
1002 kumaneko 20
1003 kumaneko 22 <p>The line <strong>100 allow task.exe="<code>/usr/sbin/caitsith-queryd</code>"</strong> means that allow if current thread's program name is <code>/usr/sbin/caitsith-queryd</code>. This tells CaitSith finish evaluation of this block starting with the <strong>0 acl modify_policy</strong> line if current thread's program name is <code>/usr/sbin/caitsith-queryd</code>. The usage of <code>/usr/sbin/caitsith-queryd</code> will be explained later.</p>
1004 kumaneko 20
1005 kumaneko 22 <p>The line <strong>10000 deny</strong> means deny unconditionally. This tells CaitSith "unconditionally deny modification of policy configuration via <code>/proc/caitsith/policy</code> interface".</p>
1006 kumaneko 20
1007 kumaneko 22 <p>Since lines starting with <strong>1 deny</strong> have higher priority than lines starting with <strong>100 allow</strong>, CaitSith will deny modifying policy configuration via <code>/proc/caitsith/policy</code> interface if current thread's user ID is not 0 or current thread's effective user ID is not 0. In other words, only root user (where current thread's user ID and effective user ID are both 0) can modify policy configuration via <code>/proc/caitsith/policy</code> interface.</p>
1008 kumaneko 20
1009 kumaneko 22 <p>Since lines starting with <strong>100 allow</strong> have higher priority than a line starting with <strong>10000 deny</strong>, CaitSith will allow modifying policy configuration via <code>/proc/caitsith/policy</code> interface if current thread's program name is <code>/usr/sbin/caitsith-loadpolicy</code> or current thread's program name is <code>/usr/sbin/caitsith-queryd</code>. In other words, other programs such as <code>/bin/sh</code>, <code>/bin/echo</code>, <code>/bin/cat</code> are not allowed to modify policy configuration via <code>/proc/caitsith/policy</code> interface.</p>
1010 kumaneko 20
1011 kumaneko 22 <p>To summarize this rule, only <code>/usr/sbin/caitsith-loadpolicy</code> or <code>/usr/sbin/caitsith-queryd</code> command running as root user can modify policy configuration via <code>/proc/caitsith/policy</code> interface.</p>
1012 kumaneko 20
1013     <p>Note the difference between</p>
1014    
1015     <pre>
1016     0 acl execute task.exe="/usr/sbin/httpd"
1017     audit 1
1018     1 allow path="/var/www/cgi-bin/counter.cgi"
1019     100 deny
1020     </pre>
1021    
1022     <p>and</p>
1023    
1024     <pre>
1025     0 acl execute path="/var/www/cgi-bin/counter.cgi"
1026     audit 1
1027     1 allow task.exe="/usr/sbin/httpd"
1028     100 deny
1029     </pre>
1030    
1031 kumaneko 22 <p>. The former means "<code>/usr/sbin/httpd</code> can execute <strong>only</strong> <code>/var/www/cgi-bin/counter.cgi</code>", while the latter means "<strong>only</strong> <code>/usr/sbin/httpd</code> can execute <code>/var/www/cgi-bin/counter.cgi</code>".</p>
1032 kumaneko 20
1033     <p>CaitSith supports restricting other arguments such as command line arguments and environment variables. Syntax for restricting other arguments will be explained later.</p>
1034    
1035     <h4><a name="3.4.3">3.4.3. Writing access restriction rules from the point of view of both "subject" and "object".</a></h4>
1036    
1037     <p>It is possible to write access restriction rules like</p>
1038    
1039     <pre>
1040     0 acl execute task.exe="/usr/sbin/httpd" path="/var/www/cgi-bin/counter.cgi"
1041     audit 1
1042     1 allow task.uid!=0
1043     100 deny
1044     </pre>
1045    
1046     <p>and</p>
1047    
1048     <pre>
1049     0 acl execute task.uid!=0
1050     audit 1
1051     1 allow task.exe="/usr/sbin/httpd" path="/var/www/cgi-bin/counter.cgi"
1052     100 deny
1053     </pre>
1054    
1055 kumaneko 22 <p>. The former means "<code>/usr/sbin/httpd</code> is allowed to execute <code>/var/www/cgi-bin/counter.cgi</code> only if current thread's user ID is not 0", while the latter means "only execution of <code>/var/www/cgi-bin/counter.cgi</code> from <code>/usr/sbin/httpd</code> is allowed if current thread's user ID is not 0".</p>
1056 kumaneko 20
1057     <p>Also, it is possible to write access restriction rules like</p>
1058    
1059     <pre>
1060     0 acl execute
1061     audit 1
1062     1 allow task.exe="/usr/sbin/httpd" path="/var/www/cgi-bin/counter.cgi"
1063     100 deny
1064     </pre>
1065    
1066 kumaneko 22 <p>which means "any execute requests other than execution of <code>/var/www/cgi-bin/counter.cgi</code> from <code>/usr/sbin/httpd</code> are denied" (DO NOT TRY THIS EXAMPLE, or you will no longer be able to run any commands).</p>
1067 kumaneko 20
1068     <h3><a name="3.5">3.5. Using string arguments in conditions</a></h3>
1069    
1070 kumaneko 18 <p>Arguments such as file's pathnames and command line arguments and environment variables are handled as string argument.</p>
1071    
1072 kumaneko 20 <h4><a name="3.5.1">3.5.1. About string argument representation rule</a></h4>
1073 kumaneko 18
1074     <p>All ASCII printable characters other than \ character (i.e. from 33 to 91 and from 93 to 126) are represented as is.</p>
1075    
1076     <p>All other characters (i.e. from 0 to 32, 92 and from 127 to 255) are represented using \ooo style octal form.</p>
1077    
1078     <table border="1">
1079     <tr>
1080     <td>
1081     <table><tr><td></td><td>Lower 4 bits</td></tr><tr><td>Upper 4 bits</td><td></td></tr></table>
1082     </td>
1083     <th><p>0x0</p></th>
1084     <th><p>0x1</p></th>
1085     <th><p>0x2</p></th>
1086     <th><p>0x3</p></th>
1087     <th><p>0x4</p></th>
1088     <th><p>0x5</p></th>
1089     <th><p>0x6</p></th>
1090     <th><p>0x7</p></th>
1091     <th><p>0x8</p></th>
1092     <th><p>0x9</p></th>
1093     <th><p>0xA</p></th>
1094     <th><p>0xB</p></th>
1095     <th><p>0xC</p></th>
1096     <th><p>0xD</p></th>
1097     <th><p>0xE</p></th>
1098     <th><p>0xF</p></th>
1099     </tr>
1100     <tr>
1101     <th><p>0x0</p></th>
1102     <td><p>\000</p></td>
1103     <td><p>\001</p></td>
1104     <td><p>\002</p></td>
1105     <td><p>\003</p></td>
1106     <td><p>\004</p></td>
1107     <td><p>\005</p></td>
1108     <td><p>\006</p></td>
1109     <td><p>\007</p></td>
1110     <td><p>\010</p></td>
1111     <td><p>\011</p></td>
1112     <td><p>\012</p></td>
1113     <td><p>\013</p></td>
1114     <td><p>\014</p></td>
1115     <td><p>\015</p></td>
1116     <td><p>\016</p></td>
1117     <td><p>\017</p></td>
1118     </tr>
1119     <tr>
1120     <th><p>0x1</p></th>
1121     <td><p>\020</p></td>
1122     <td><p>\021</p></td>
1123     <td><p>\022</p></td>
1124     <td><p>\023</p></td>
1125     <td><p>\024</p></td>
1126     <td><p>\025</p></td>
1127     <td><p>\026</p></td>
1128     <td><p>\027</p></td>
1129     <td><p>\030</p></td>
1130     <td><p>\031</p></td>
1131     <td><p>\032</p></td>
1132     <td><p>\033</p></td>
1133     <td><p>\034</p></td>
1134     <td><p>\035</p></td>
1135     <td><p>\036</p></td>
1136     <td><p>\037</p></td>
1137     </tr>
1138     <tr>
1139     <th><p>0x2</p></th>
1140     <td><p>\040</p></td>
1141     <td><p>!</p></td>
1142     <td><p>"</p></td>
1143     <td><p>#</p></td>
1144     <td><p>$</p></td>
1145     <td><p>%</p></td>
1146     <td><p>&amp;</p></td>
1147     <td><p>'</p></td>
1148     <td><p>(</p></td>
1149     <td><p>)</p></td>
1150     <td><p>*</p></td>
1151     <td><p>+</p></td>
1152     <td><p>,</p></td>
1153     <td><p>-</p></td>
1154     <td><p>.</p></td>
1155     <td><p>/</p></td>
1156     </tr>
1157     <tr>
1158     <th><p>0x3</p></th>
1159     <td><p>0</p></td>
1160     <td><p>1</p></td>
1161     <td><p>2</p></td>
1162     <td><p>3</p></td>
1163     <td><p>4</p></td>
1164     <td><p>5</p></td>
1165     <td><p>6</p></td>
1166     <td><p>7</p></td>
1167     <td><p>8</p></td>
1168     <td><p>9</p></td>
1169     <td><p>:</p></td>
1170     <td><p>;</p></td>
1171     <td><p>&lt;</p></td>
1172     <td><p>=</p></td>
1173     <td><p>&gt;</p></td>
1174     <td><p>?</p></td>
1175     </tr>
1176     <tr>
1177     <th><p>0x4</p></th>
1178     <td><p>@</p></td>
1179     <td><p>A</p></td>
1180     <td><p>B</p></td>
1181     <td><p>C</p></td>
1182     <td><p>D</p></td>
1183     <td><p>E</p></td>
1184     <td><p>F</p></td>
1185     <td><p>G</p></td>
1186     <td><p>H</p></td>
1187     <td><p>I</p></td>
1188     <td><p>J</p></td>
1189     <td><p>K</p></td>
1190     <td><p>L</p></td>
1191     <td><p>M</p></td>
1192     <td><p>N</p></td>
1193     <td><p>O</p></td>
1194     </tr>
1195     <tr>
1196     <th><p>0x5</p></th>
1197     <td><p>P</p></td>
1198     <td><p>Q</p></td>
1199     <td><p>R</p></td>
1200     <td><p>S</p></td>
1201     <td><p>T</p></td>
1202     <td><p>U</p></td>
1203     <td><p>V</p></td>
1204     <td><p>W</p></td>
1205     <td><p>X</p></td>
1206     <td><p>Y</p></td>
1207     <td><p>Z</p></td>
1208     <td><p>[</p></td>
1209     <td><p>\134</p></td>
1210     <td><p>]</p></td>
1211     <td><p>^</p></td>
1212     <td><p>_</p></td>
1213     </tr>
1214     <tr>
1215     <th><p>0x6</p></th>
1216     <td><p>`</p></td>
1217     <td><p>a</p></td>
1218     <td><p>b</p></td>
1219     <td><p>c</p></td>
1220     <td><p>d</p></td>
1221     <td><p>e</p></td>
1222     <td><p>f</p></td>
1223     <td><p>g</p></td>
1224     <td><p>h</p></td>
1225     <td><p>i</p></td>
1226     <td><p>j</p></td>
1227     <td><p>k</p></td>
1228     <td><p>l</p></td>
1229     <td><p>m</p></td>
1230     <td><p>n</p></td>
1231     <td><p>o</p></td>
1232     </tr>
1233     <tr>
1234     <th><p>0x7</p></th>
1235     <td><p>p</p></td>
1236     <td><p>q</p></td>
1237     <td><p>r</p></td>
1238     <td><p>s</p></td>
1239     <td><p>t</p></td>
1240     <td><p>u</p></td>
1241     <td><p>v</p></td>
1242     <td><p>w</p></td>
1243     <td><p>x</p></td>
1244     <td><p>y</p></td>
1245     <td><p>z</p></td>
1246     <td><p>{</p></td>
1247     <td><p>|</p></td>
1248     <td><p>}</p></td>
1249     <td><p>~</p></td>
1250     <td><p>\177</p></td>
1251     </tr>
1252     <tr>
1253     <th><p>0x8</p></th>
1254     <td><p>\200</p></td>
1255     <td><p>\201</p></td>
1256     <td><p>\202</p></td>
1257     <td><p>\203</p></td>
1258     <td><p>\204</p></td>
1259     <td><p>\205</p></td>
1260     <td><p>\206</p></td>
1261     <td><p>\207</p></td>
1262     <td><p>\210</p></td>
1263     <td><p>\211</p></td>
1264     <td><p>\212</p></td>
1265     <td><p>\213</p></td>
1266     <td><p>\214</p></td>
1267     <td><p>\215</p></td>
1268     <td><p>\216</p></td>
1269     <td><p>\217</p></td>
1270     </tr>
1271     <tr>
1272     <th><p>0x9</p></th>
1273     <td><p>\220</p></td>
1274     <td><p>\221</p></td>
1275     <td><p>\222</p></td>
1276     <td><p>\223</p></td>
1277     <td><p>\224</p></td>
1278     <td><p>\225</p></td>
1279     <td><p>\226</p></td>
1280     <td><p>\227</p></td>
1281     <td><p>\230</p></td>
1282     <td><p>\231</p></td>
1283     <td><p>\232</p></td>
1284     <td><p>\233</p></td>
1285     <td><p>\234</p></td>
1286     <td><p>\235</p></td>
1287     <td><p>\236</p></td>
1288     <td><p>\237</p></td>
1289     </tr>
1290     <tr>
1291     <th><p>0xA</p></th>
1292     <td><p>\240</p></td>
1293     <td><p>\241</p></td>
1294     <td><p>\242</p></td>
1295     <td><p>\243</p></td>
1296     <td><p>\244</p></td>
1297     <td><p>\245</p></td>
1298     <td><p>\246</p></td>
1299     <td><p>\247</p></td>
1300     <td><p>\250</p></td>
1301     <td><p>\251</p></td>
1302     <td><p>\252</p></td>
1303     <td><p>\253</p></td>
1304     <td><p>\254</p></td>
1305     <td><p>\255</p></td>
1306     <td><p>\256</p></td>
1307     <td><p>\257</p></td>
1308     </tr>
1309     <tr>
1310     <th><p>0xB</p></th>
1311     <td><p>\260</p></td>
1312     <td><p>\261</p></td>
1313     <td><p>\262</p></td>
1314     <td><p>\263</p></td>
1315     <td><p>\264</p></td>
1316     <td><p>\265</p></td>
1317     <td><p>\266</p></td>
1318     <td><p>\267</p></td>
1319     <td><p>\270</p></td>
1320     <td><p>\271</p></td>
1321     <td><p>\272</p></td>
1322     <td><p>\273</p></td>
1323     <td><p>\274</p></td>
1324     <td><p>\275</p></td>
1325     <td><p>\276</p></td>
1326     <td><p>\277</p></td>
1327     </tr>
1328     <tr>
1329     <th><p>0xC</p></th>
1330     <td><p>\300</p></td>
1331     <td><p>\301</p></td>
1332     <td><p>\302</p></td>
1333     <td><p>\303</p></td>
1334     <td><p>\304</p></td>
1335     <td><p>\305</p></td>
1336     <td><p>\306</p></td>
1337     <td><p>\307</p></td>
1338     <td><p>\310</p></td>
1339     <td><p>\311</p></td>
1340     <td><p>\312</p></td>
1341     <td><p>\313</p></td>
1342     <td><p>\314</p></td>
1343     <td><p>\315</p></td>
1344     <td><p>\316</p></td>
1345     <td><p>\317</p></td>
1346     </tr>
1347     <tr>
1348     <th><p>0xD</p></th>
1349     <td><p>\320</p></td>
1350     <td><p>\321</p></td>
1351     <td><p>\322</p></td>
1352     <td><p>\323</p></td>
1353     <td><p>\324</p></td>
1354     <td><p>\325</p></td>
1355     <td><p>\326</p></td>
1356     <td><p>\327</p></td>
1357     <td><p>\330</p></td>
1358     <td><p>\331</p></td>
1359     <td><p>\332</p></td>
1360     <td><p>\333</p></td>
1361     <td><p>\334</p></td>
1362     <td><p>\335</p></td>
1363     <td><p>\336</p></td>
1364     <td><p>\337</p></td>
1365     </tr>
1366     <tr>
1367     <th><p>0xE</p></th>
1368     <td><p>\340</p></td>
1369     <td><p>\341</p></td>
1370     <td><p>\342</p></td>
1371     <td><p>\343</p></td>
1372     <td><p>\344</p></td>
1373     <td><p>\345</p></td>
1374     <td><p>\346</p></td>
1375     <td><p>\347</p></td>
1376     <td><p>\350</p></td>
1377     <td><p>\351</p></td>
1378     <td><p>\352</p></td>
1379     <td><p>\353</p></td>
1380     <td><p>\354</p></td>
1381     <td><p>\355</p></td>
1382     <td><p>\356</p></td>
1383     <td><p>\357</p></td>
1384     </tr>
1385     <tr>
1386     <th><p>0xF</p></th>
1387     <td><p>\360</p></td>
1388     <td><p>\361</p></td>
1389     <td><p>\362</p></td>
1390     <td><p>\363</p></td>
1391     <td><p>\364</p></td>
1392     <td><p>\365</p></td>
1393     <td><p>\366</p></td>
1394     <td><p>\367</p></td>
1395     <td><p>\370</p></td>
1396     <td><p>\371</p></td>
1397     <td><p>\372</p></td>
1398     <td><p>\373</p></td>
1399     <td><p>\374</p></td>
1400     <td><p>\375</p></td>
1401     <td><p>\376</p></td>
1402     <td><p>\377</p></td>
1403     </tr>
1404     </table>
1405    
1406     <p>Some examples are shown below.</p>
1407    
1408     <pre>
1409     /bin/sh
1410     /home/demo/Documents\040and\040Settings
1411     </pre>
1412    
1413 kumaneko 20 <h4><a name="3.5.2">3.5.2. Grouping string arguments using wildcard expressions.</a></h4>
1414 kumaneko 18
1415     <p>It is possible to use wildcards listed below in order to match string patterns.</p>
1416    
1417     <table border="1">
1418     <tr>
1419     <th><p>Wildcard</p></th>
1420     <th><p>Pattern match</p></th>
1421     <th><p>Examples</p></th>
1422     </tr>
1423     <tr>
1424     <td><p>\*</p></td>
1425     <td><p>0 or more repetitions of characters other than "/"</p></td>
1426     <td><p>/var/log/samba/\*</p></td>
1427     </tr>
1428     <tr>
1429     <td><p>\@</p></td>
1430     <td><p>0 or more repetitions of characters other than "/" or "."</p></td>
1431     <td><p>/var/www/html/\@.html</p></td>
1432     </tr>
1433     <tr>
1434     <td><p>\?</p></td>
1435     <td><p>1 byte character other than "/"</p></td>
1436     <td><p>/tmp/mail.\?\?\?\?\?\?</p></td>
1437     </tr>
1438     <tr>
1439     <td><p>\$</p></td>
1440     <td><p>1 or more repetitions of decimal digits</p></td>
1441     <td><p>/proc/\$/cmdline</p></td>
1442     </tr>
1443     <tr>
1444     <td><p>\+</p></td>
1445     <td><p>1 decimal digit</p></td>
1446     <td><p>/var/tmp/my_work.\+</p></td>
1447     </tr>
1448     <tr>
1449     <td><p>\X</p></td>
1450     <td><p>1 or more repetitions of hexadecimal digits</p></td>
1451     <td><p>/var/tmp/my-work.\X</p></td>
1452     </tr>
1453     <tr>
1454     <td><p>\x</p></td>
1455     <td><p>1 hexadecimal digit</p></td>
1456     <td><p>/tmp/my-work.\x</p></td>
1457     </tr>
1458     <tr>
1459     <td><p>\A</p></td>
1460     <td><p>1 or more repetitions of alphabet characters</p></td>
1461     <td><p>/var/log/my-work/\$-\A-\$.log</p></td>
1462     </tr>
1463     <tr>
1464     <td><p>\a</p></td>
1465     <td><p>1 alphabet character</p></td>
1466     <td><p>/home/users/\a/\*/public_html/\*.html</p></td>
1467     </tr>
1468     <tr>
1469     <td><p>\-</p></td>
1470     <td><p>Pathname subtraction operator (negative match)</p></td>
1471     <td>
1472     <p>/\*\-proc\-sys</p>
1473     <p>This will match /\* except "/proc" and "/sys".</p>
1474     </td>
1475     </tr>
1476     <tr>
1477     <td><p>/\{dir\}/</p></td>
1478     <td><p>Recursive directory matching operator.</p>
1479     <p>Matches "/" and 1 or more repetitions of "dir/".</p></td>
1480     <td>
1481     <p>/var/www/html/\{\*\}/\*.html</p>
1482     <p>This will match all *.html files in subdirectories under /var/www/html/ directory. Note that /var/www/html/\*.html will not match.</p>
1483     </td>
1484     </tr>
1485     <tr>
1486     <td><p>/({dir\)/</p></td>
1487     <td><p>Recursive directory matching operator.</p>
1488     <p>Matches "/" and 0 or more repetitions of "dir/".</p></td>
1489     <td>
1490     <p>/var/www/html/\(\*\)/\*.html</p>
1491     <p>This will match all *.html files under /var/www/html/ directory. Note that /var/www/html/\*.html will match.</p>
1492     </td>
1493     </tr>
1494     </table>
1495    
1496 kumaneko 20 <h4><a name="3.5.3">3.5.3. Grouping string arguments using string_group keyword.</a></h4>
1497 kumaneko 18
1498     <p>It is possible to define groups of string arguments using string_group keyword followed by $string_group_name and $string_group_member.</p>
1499    
1500     <pre>
1501     string_group TMPDIR /tmp
1502     string_group TMPDIR /tmp/\(\*\)/\*
1503     </pre>
1504    
1505 kumaneko 20 <h4><a name="3.5.4">3.5.4. Example of conditions that use string arguments.</a></h4>
1506 kumaneko 18
1507     <p>When string argument is specified in condition part, it is quoted by " character in order to clarify that the argument is a string argument rather than name of variable.</p>
1508    
1509     <table border="1">
1510     <tr><td>Conditions example</td><td>Value of variable "path"</td><td>Comparison result</td></tr>
1511     <tr><td rowspan="5">path="/tmp/\*"</td>
1512     <td>/</td><td>Does not match</td></tr>
1513     <tr><td>/tmp</td><td>Does not match</td></tr>
1514     <tr><td>/tmp/</td><td>Matches</td></tr>
1515     <tr><td>/tmp/rt6bh84t</td><td>Matches</td></tr>
1516     <tr><td>/tmp/349gy08t/y8024fgf</td><td>Does not match</td></tr>
1517     <tr><td rowspan="5">path!="/tmp/\*"</td>
1518     <td>/</td><td>Matches</td></tr>
1519     <tr><td>/tmp</td><td>Matches</td></tr>
1520     <tr><td>/tmp/</td><td>Does not match</td></tr>
1521     <tr><td>/tmp/rt6bh84t</td><td>Does not match</td></tr>
1522     <tr><td>/tmp/349gy08t/y8024fgf</td><td>Matches</td></tr>
1523     </table>
1524    
1525     <p>When string_group argument is specified in condition part, it is prefixed by @ character in order to clarify that the argument is a string_group argument rather than name of variable.</p>
1526    
1527     <table border="1">
1528     <tr><td>Conditions example</td><td>Value of variable "path"</td><td>Values in TMPDIR group</td><td>Comparison result</td></tr>
1529     <tr><td rowspan="4">path=@TMPDIR</td>
1530     <td>/</td><td rowspan="4">/tmp<br>/tmp/\(\*\)/\*</td><td>Does not match</td></tr>
1531     <tr><td>/tmp</td><td>Matches</td></tr>
1532     <tr><td>/tmp/rt6bh84t</td><td>Matches</td></tr>
1533     <tr><td>/tmp/349gy08t/y8024fgf</td><td>Matches</td></tr>
1534     <tr><td rowspan="4">path!=@TMPDIR</td>
1535     <td>/</td><td rowspan="4">/tmp<br>/tmp/\(\*\)/\*</td><td>Matches</td></tr>
1536     <tr><td>/tmp</td><td>Does not match</td></tr>
1537     <tr><td>/tmp/rt6bh84t</td><td>Does not match</td></tr>
1538     <tr><td>/tmp/349gy08t/y8024fgf</td><td>Does not match</td></tr>
1539     </table>
1540    
1541     <p>List of name of variables which reference string data is explained later.</p>
1542    
1543 kumaneko 20 <h3><a name="3.6">3.6. Using numeric arguments in conditions</a></h3>
1544 kumaneko 18
1545     <p>Arguments such as user ID and process ID are handled as numeric argument.</p>
1546    
1547 kumaneko 20 <h4><a name="3.6.1">3.6.1. About numeric argument representation rule</a></h4>
1548 kumaneko 18
1549     <p>Decimal form, octal form and hexadecimal form are supported. Octal form is prefixed with 0 and Hexadecimal form is prefixed with 0x. For example, 010 in octal form is equivalent with 8 in decimal form, 0x10 in hexadecimal form is equivalent with 16 in decimal form.</p>
1550    
1551     <p>Since numeric data is handled using C language's "unsigned long" type, minimal value is 0 and maximal value is 0xFFFFFFFF (for 32 bit environments) or 0xFFFFFFFFFFFFFFFF (for 64 bit environments).</p>
1552    
1553     <p>It is possible to specify numeric data ranges in $min_value-$max_value form. If specifying in range, $min_value has to be smaller or equals to $max_value. For example, 0-100 is valid but 100-0 is invalid.</p>
1554    
1555     <p>Some examples are shown below.</p>
1556    
1557     <pre>
1558     0
1559     100
1560     0xFFFF
1561     0777
1562     500-1000
1563     0x0-0xFFFFFFFF
1564     00-07777
1565     </pre>
1566    
1567 kumaneko 20 <h4><a name="3.6.2">3.6.2. Grouping numeric arguments using number_group keyword.</a></h4>
1568 kumaneko 18
1569     <p>It is possible to define groups of numeric arguments using number_group keyword followed by $number_group_name and $number_group_member.</p>
1570    
1571     <pre>
1572     number_group ID_GROUP 100
1573     number_group ID_GROUP 200-500
1574     </pre>
1575    
1576 kumaneko 20 <h4><a name="3.6.3">3.6.3. Example of conditions that use numeric arguments.</a></h4>
1577 kumaneko 18
1578     <p>Comparison with numeric value is defined as below.</p>
1579    
1580     <table border="1">
1581     <tr><td>Conditions example</td><td>Value of variable "task.uid"</td><td>Comparison result</td></tr>
1582     <tr><td rowspan="3">task.uid=0</td>
1583     <td>0</td><td>Matches</td></tr>
1584     <tr><td>100</td><td>Does not match</td></tr>
1585     <tr><td>500</td><td>Does not match</td></tr>
1586     <tr><td rowspan="3">task.uid!=0</td>
1587     <td>0</td><td>Does not match</td></tr>
1588     <tr><td>100</td><td>Matches</td></tr>
1589     <tr><td>500</td><td>Matches</td></tr>
1590     </table>
1591    
1592     <p>Comparison with numeric value range is defined as below.</p>
1593    
1594     <table border="1">
1595     <tr><td>Conditions example</td><td>Value of variable "task.gid"</td><td>Comparison result</td></tr>
1596     <tr><td rowspan="3">task.gid=0-100</td>
1597     <td>0</td><td>Matches</td></tr>
1598     <tr><td>100</td><td>Matches</td></tr>
1599     <tr><td>500</td><td>Does not match</td></tr>
1600     <tr><td rowspan="3">task.gid!=0-100</td><td>0</td><td>Does not match</td></tr>
1601     <tr><td>100</td><td>Does not match</td></tr>
1602     <tr><td>500</td><td>Matches</td></tr>
1603     </table>
1604    
1605     <p>It is possible to compare one variable which references numeric value with another variable which references numeric value.</p>
1606    
1607     <table border="1">
1608     <tr><td>Conditions example</td><td>Value of variable "task.uid"</td><td>Value of variable "task.gid"</td><td>Comparison result</td></tr>
1609     <tr><td rowspan="4">task.uid=task.gid</td>
1610     <td>0</td><td>0</td><td>Matches</td></tr>
1611     <tr><td>0</td><td>100</td><td>Does not match</td></tr>
1612     <tr><td>100</td><td>0</td><td>Does not match</td></tr>
1613     <tr><td>100</td><td>100</td><td>Matches</td></tr>
1614     <tr><td rowspan="4">task.uid!=task.gid</td>
1615     <td>0</td><td>0</td><td>Does not match</td></tr>
1616     <tr><td>0</td><td>100</td><td>Matches</td></tr>
1617     <tr><td>100</td><td>0</td><td>Matches</td></tr>
1618     <tr><td>100</td><td>100</td><td>Does not match</td></tr>
1619     </table>
1620    
1621     <p>When number_group argument is specified in condition part, it is prefixed by @ character in order to clarify that the argument is a number_group argument rather than name of variable.</p>
1622    
1623     <table border="1">
1624     <tr><td>Conditions example</td><td>Value of variable "task.uid"</td><td>Values in ID_GROUP group</td><td>Comparison result</td></tr>
1625     <tr><td rowspan="4">task.uid=@ID_GROUP</td>
1626     <td>0</td><td rowspan="4">100<br>200-500</td><td>Does not match</td></tr>
1627     <tr><td>100</td><td>Matches</td></tr>
1628     <tr><td>500</td><td>Matches</td></tr>
1629     <tr><td>1000</td><td>Does not match</td></tr>
1630     <tr><td rowspan="4">task.uid!=@ID_GROUP</td>
1631     <td>0</td><td rowspan="4">100<br>200-500</td><td>Matches</td></tr>
1632     <tr><td>100</td><td>Does not match</td></tr>
1633     <tr><td>500</td><td>Does not match</td></tr>
1634     <tr><td>1000</td><td>Matches</td></tr>
1635     </table>
1636    
1637     <p>List of name of variables which reference numeric data is explained later.</p>
1638    
1639 kumaneko 20 <h3><a name="3.7">3.7. Using process's information in conditions</a></h3>
1640 kumaneko 18
1641 kumaneko 19 <p>By using current thread's attributes as part of conditions, you can write complicated access restriction rules.</p>
1642 kumaneko 18
1643 kumaneko 20 <h4><a name="3.7.1">3.7.1. About available variables</a></h4>
1644 kumaneko 18
1645 kumaneko 19 <p>Below variables are available for referring current thread's attributes.</p>
1646 kumaneko 18
1647 kumaneko 19 <table border="1">
1648     <tr><td>Variable's name</td><td>Comparison method</td><td>Meaning</td><td></td></tr>
1649     <tr><td>task.uid</td><td><a href="#3.5">Numeric</a></td><td>Current thread's user ID</td></tr>
1650     <tr><td>task.gid</td><td><a href="#3.5">Numeric</a></td><td>Current thread's group ID</td></tr>
1651     <tr><td>task.euid</td><td><a href="#3.5">Numeric</a></td><td>Current thread's effective user ID</td></tr>
1652     <tr><td>task.egid</td><td><a href="#3.5">Numeric</a></td><td>Current thread's effective group ID</td></tr>
1653     <tr><td>task.suid</td><td><a href="#3.5">Numeric</a></td><td>Current thread's saved user ID</td></tr>
1654     <tr><td>task.sgid</td><td><a href="#3.5">Numeric</a></td><td>Current thread's saved group ID</td></tr>
1655     <tr><td>task.fsuid</td><td><a href="#3.5">Numeric</a></td><td>Current thread's filesystem user ID</td></tr>
1656     <tr><td>task.fsgid</td><td><a href="#3.5">Numeric</a></td><td>Current thread's filesystem group ID</td></tr>
1657     <tr><td>task.pid</td><td><a href="#3.5">Numeric</a></td><td>Current thread's process ID </td></tr>
1658     <tr><td>task.ppid</td><td><a href="#3.5">Numeric</a></td><td>Process ID of current thread's parent process</td></tr>
1659 kumaneko 22 <tr><td>task.exe</td><td><a href="#3.4">String</a></td><td>Current thread's program name (the content of <code>/proc/self/exe</code>)</td></tr>
1660     <tr><td>task.domain</td><td><a href="#3.4">String</a></td><td>Current thread's domainname (the content of <code>/proc/caitsith/self_domain</code>)</td></tr>
1661 kumaneko 19 <tr><td>task.type</td><td>Literal</td><td>Matches execute_handler if running as an execute handler, does not match execute_handler otherwise</td></tr>
1662     </table>
1663    
1664     <p>Details of task.domain and task.type are explained later.</p>
1665    
1666 kumaneko 20 <h3><a name="3.8">3.8. Using IP address arguments in conditions</a></h3>
1667 kumaneko 19
1668 kumaneko 18 <p>Any operation which handles IPv4/IPv6 network address can check IP address.</p>
1669    
1670 kumaneko 20 <h4><a name="3.8.1">3.8.1. About IP address argument representation rule</a></h4>
1671 kumaneko 18
1672     <p>It is possible to handle IPv4 address and IPv6 address. IPv4 address (32 bit) is represented using dot separated decimal form. and IPv6 address (128 bit) is represented using forms defined in RFC 2373.</p>
1673    
1674     <p>It is possible to specify IP address ranges in $min_address-$max_address form. If specifying in range, $min_address has to be smaller or equals to $max_address. For example, 1.2.3.4-5.6.7.8 is valid but 5.6.7.8-1.2.3.4 is invalid.</p>
1675    
1676     <p>Some examples are shown below.</p>
1677    
1678     <pre>
1679     127.0.0.1
1680     10.0.0.0-10.255.255.255
1681     ::1
1682     fd00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
1683     </pre>
1684    
1685 kumaneko 20 <h4><a name="3.8.2">3.8.2. Grouping IP address arguments using ip_group keyword.</a></h4>
1686 kumaneko 18
1687     <p>It is possible to define groups of IP address arguments using ip_group keyword followed by $ip_group_name and $ip_group_member.</p>
1688    
1689     <pre>
1690     ip_group PRIVATE_ADDRESS 10.0.0.0-10.255.255.255
1691     ip_group PRIVATE_ADDRESS 172.16.0.0-172.31.255.255
1692     ip_group PRIVATE_ADDRESS 192.168.0.0-192.168.255.255
1693     ip_group PRIVATE_ADDRESS fd00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
1694     </pre>
1695    
1696 kumaneko 20 <h4><a name="3.8.3">3.8.3. Example of conditions that use IP address arguments.</a></h4>
1697 kumaneko 18
1698     <p>Comparison with IP address value is defined as below. Note that comparison between an IPv4 address and an IPv6 address does not match.</p>
1699    
1700     <table border="1">
1701     <tr><td>Conditions example</td><td>Value of variable "ip"</td><td>Comparison result</td></tr>
1702     <tr><td rowspan="4">ip=127.0.0.1</td><td>127.0.0.1</td><td>Matches</td></tr>
1703     <tr><td>0.0.0.0</td><td>Does not match</td></tr>
1704     <tr><td>::1</td><td>Does not match</td></tr>
1705     <tr><td>::ffff:127.0.0.1</td><td>Does not match</td></tr>
1706     <tr><td rowspan="4">ip!=127.0.0.1</td><td>127.0.0.1</td><td>Does not match</td></tr>
1707     <tr><td>0.0.0.0</td><td>Matches</td></tr>
1708     <tr><td>::1</td><td>Does not match</td></tr>
1709     <tr><td>::ffff:127.0.0.1</td><td>Does not match</td></tr>
1710     <tr><td rowspan="4">ip=::1</td><td>127.0.0.1</td><td>Does not match</td></tr>
1711     <tr><td>0.0.0.0</td><td>Does not match</td></tr>
1712     <tr><td>::1</td><td>Matches</td></tr>
1713     <tr><td>::ffff:127.0.0.1</td><td>Does not match</td></tr>
1714     <tr><td rowspan="4">ip!=::1</td><td>127.0.0.1</td><td>Does not match</td></tr>
1715     <tr><td>0.0.0.0</td><td>Does not match</td></tr>
1716     <tr><td>::1</td><td>Does not match</td></tr>
1717     <tr><td>::ffff:127.0.0.1</td><td>Matches</td></tr>
1718     </table>
1719    
1720     <p>Comparison with IP address range is defined as below.</p>
1721    
1722     <table border="1">
1723     <tr><td>Conditions example</td><td>Value of variable "ip"</td><td>Comparison result</td></tr>
1724     <tr><td rowspan="3">ip=127.0.0.0-127.255.255.255</td>
1725     <td>127.0.0.1</td><td>Matches</td></tr>
1726     <tr><td>10.0.0.1</td><td>Does not match</td></tr>
1727     <tr><td>::ffff:127.0.0.1</td><td>Does not match</td></tr>
1728     <tr><td rowspan="3">ip!=127.0.0.0-127.255.255.255</td>
1729     <td>127.0.0.1</td><td>Does not match</td></tr>
1730     <tr><td>10.0.0.1</td><td>Matches</td></tr>
1731     <tr><td>::ffff:127.0.0.1</td><td>Does not match</td></tr>
1732     <tr><td rowspan="3">ip=::-::1</td><td>::ffff:127.0.0.1</td><td>Does not match</td></tr>
1733     <tr><td>127.0.0.1</td><td>Does not match</td></tr>
1734     <tr><td>::1</td><td>Matches</td></tr>
1735     <tr><td rowspan="3">ip!=::-::1</td><td>::ffff:127.0.0.1</td><td>Matches</td></tr>
1736     <tr><td>127.0.0.1</td><td>Does not match</td></tr>
1737     <tr><td>::1</td><td>Does not match</td></tr>
1738     </table>
1739    
1740     <p>When ip_group argument is specified in condition part, it is prefixed by @ character in order to clarify that the argument is an ip_group argument rather than name of variable.</p>
1741    
1742     <table border="1">
1743     <tr><td>Conditions example</td><td>Value of variable "ip"</td><td>Values in PRIVATE_ADDRESS group</td><td>Comparison result</td></tr>
1744     <tr><td rowspan="5">ip=@PRIVATE_ADDRESS</td>
1745     <td>127.0.0.1</td><td rowspan="5">10.0.0.0-10.255.255.255<br>172.16.0.0-172.31.255.255<br>192.168.0.0-192.168.255.255<br>fd00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff</td><td>Does not match</td></tr>
1746     <tr><td>10.0.0.1</td><td>Matches</td></tr>
1747     <tr><td>192.168.0.1</td><td>Matches</td></tr>
1748     <tr><td>::ffff:172.16.0.1</td><td>Does not match</td></tr>
1749     <tr><td>fd01::</td><td>Matches</td></tr>
1750     <tr><td rowspan="5">ip!=@PRIVATE_ADDRESS</td><td>127.0.0.1</td><td rowspan="5">10.0.0.0-10.255.255.255<br>172.16.0.0-172.31.255.255<br>192.168.0.0-192.168.255.255<br>fd00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff</td><td>Matches</td></tr>
1751     <tr><td>10.0.0.1</td><td>Does not match</td></tr>
1752     <tr><td>::ffff:192.168.0.1</td><td>Matches</td></tr>
1753     <tr><td>::ffff:127.0.0.1</td><td>Matches</td></tr>
1754     <tr><td>fd01::</td><td>Does not match</td></tr>
1755     </table>
1756    
1757     <p>List of operations which handles IP address is explained later.</p>
1758    
1759 kumaneko 16 <hr>
1760 kumaneko 19 <p>Below part is under construction. Some of below part is already explained in above part.</p>
1761     <hr>
1762 kumaneko 16
1763     <p>Please read <a href="#policy_specification">Policy Specification</a> before continue.</p>
1764    
1765 kumaneko 10 <p>Then, decide conditions to restrict access. Below example restricts opening /etc/shadow for reading.</p>
1766    
1767     <table border="1">
1768     <tr><td>
1769     100 acl read path="/etc/shadow"<br>
1770     &nbsp;&nbsp;&nbsp;&nbsp;audit 1
1771     </td></tr>
1772     </table>
1773    
1774     <p>By operating the system, access unmatched logs are generated and spooled in /proc/caitsith/audit interface when access request of opening /etc/shadow for reading happens. If /usr/sbin/caitsith-auditd is running , access unmatched logs will be moved to /var/log/caitsith/unmatched.log .</p>
1775    
1776     <table border="1">
1777     <tr><td>
1778     #2012/03/02 08:11:51# global-pid=2826 result=unmatched priority=100 / read path="/etc/shadow" task.pid=2826 task.ppid=2814 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/usr/bin/passwd" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=42 path.ino=33708 path.major=8 path.minor=1 path.perm=0640 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=32769 path.parent.major=8 path.parent.minor=1 path.parent.perm=0755 path.parent.type=directory path.parent.fsmagic=0xEF53
1779     </td></tr>
1780     </table>
1781    
1782     <p>Examine the log and decide whether to grant this access request or not. To grant this request, add an allow line. Below example grants this request to /usr/bin/passwd program.</p>
1783    
1784     <table border="1">
1785     <tr><td>
1786     100 acl read path="/etc/shadow"<br>
1787     &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
1788     &nbsp;&nbsp;&nbsp;&nbsp;100 allow task.exe="/usr/bin/passwd"
1789     </td></tr>
1790     </table>
1791    
1792     <p>Operate the system again. For example, /usr/sbin/sshd program and /bin/cat program have requested opening /etc/shadow for reading.</p>
1793    
1794     <table border="1">
1795     <tr><td>
1796     #2012/03/02 08:13:06# global-pid=2831 result=unmatched priority=100 / read path="/etc/shadow" task.pid=2831 task.ppid=2691 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/usr/sbin/sshd" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=42 path.ino=33716 path.major=8 path.minor=1 path.perm=0640 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=32769 path.parent.major=8 path.parent.minor=1 path.parent.perm=0755 path.parent.type=directory path.parent.fsmagic=0xEF53<br>
1797     #2012/03/02 08:13:12# global-pid=2837 result=unmatched priority=100 / read path="/etc/shadow" task.pid=2837 task.ppid=2833 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=42 path.ino=33716 path.major=8 path.minor=1 path.perm=0640 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=32769 path.parent.major=8 path.parent.minor=1 path.parent.perm=0755 path.parent.type=directory path.parent.fsmagic=0xEF53
1798     </td></tr>
1799     </table>
1800    
1801     <p>Add an allow line with /usr/sbin/sshd program in order to allow access by /usr/sbin/sshd program. Also, add a deny line with /bin/cat program in order to deny access by /bin/cat program. Give higher priority (i.e. smaller $cond_priority value) to deny line than allow line so that deny lines are checked before allow lines are checked.</p>
1802    
1803     <table border="1">
1804     <tr><td>
1805     100 acl read path="/etc/shadow"<br>
1806     &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
1807     &nbsp;&nbsp;&nbsp;&nbsp;10 deny task.exe="/bin/cat"<br>
1808     &nbsp;&nbsp;&nbsp;&nbsp;100 allow task.exe="/usr/bin/passwd"<br>
1809     &nbsp;&nbsp;&nbsp;&nbsp;100 allow task.exe="/usr/sbin/sshd"
1810     </td></tr>
1811     </table>
1812    
1813     <p>From now on, attempt to read /etc/shadow using /bin/cat should be denied and access denied logs should be generated. If /usr/sbin/caitsith-auditd is running , access denied logs will be moved to /var/log/caitsith/denied.log .</p>
1814    
1815     <table border="1">
1816     <tr><td>
1817     #2012/03/02 08:14:38# global-pid=2842 result=denied priority=100 / read path="/etc/shadow" task.pid=2842 task.ppid=2833 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=42 path.ino=33716 path.major=8 path.minor=1 path.perm=0640 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=32769 path.parent.major=8 path.parent.minor=1 path.parent.perm=0755 path.parent.type=directory path.parent.fsmagic=0xEF53
1818     </td></tr>
1819     </table>
1820    
1821     <p>After you have finished enumerating all allow lines and deny lines, add a deny line with lowest priority (i.e. largest $cond_priority value within this block).</p>
1822    
1823     <table border="1">
1824     <tr><td>
1825     100 acl read path="/etc/shadow"<br>
1826     &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
1827     &nbsp;&nbsp;&nbsp;&nbsp;10 deny task.exe="/bin/cat"<br>
1828     &nbsp;&nbsp;&nbsp;&nbsp;100 allow task.exe="/usr/bin/passwd"<br>
1829     &nbsp;&nbsp;&nbsp;&nbsp;100 allow task.exe="/usr/sbin/sshd"<br>
1830     &nbsp;&nbsp;&nbsp;&nbsp;10000 deny
1831     </td></tr>
1832     </table>
1833    
1834     <p>A rule for restricting /etc/shadow for opening is now completed.</p>
1835    
1836     <p>Note that the rule explained above alone cannot prevent diverted accesses such as creating a hard link of /etc/shadow . If the resource to protect has characteristic attribute, it is recommended to utilize such attributes. On several distributions, /etc/shadow is owned by shadow group. In that case, this rule can be modified to below. (Below example assumes that shadow group's group ID is 42.)</p>
1837    
1838     <table border="1">
1839     <tr><td>
1840     100 acl read path.gid=42<br>
1841     &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
1842     &nbsp;&nbsp;&nbsp;&nbsp;10 deny task.exe="/bin/cat"<br>
1843     &nbsp;&nbsp;&nbsp;&nbsp;100 allow task.exe="/usr/bin/passwd"<br>
1844     &nbsp;&nbsp;&nbsp;&nbsp;100 allow task.exe="/usr/sbin/sshd"<br>
1845     &nbsp;&nbsp;&nbsp;&nbsp;10000 deny
1846     </td></tr>
1847     </table>
1848    
1849     <p>On several distributions, /etc/shadow is owned by root user and root group and has DAC permissions 0400. In that case, you might want to use a rule like below. (You should check whether there are other files with such attributes.)</p>
1850    
1851     <table border="1">
1852     <tr><td>
1853     100 acl read path.uid=0 path.gid=0 path.perm=0400<br>
1854     &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
1855     &nbsp;&nbsp;&nbsp;&nbsp;10 deny task.exe="/bin/cat"<br>
1856     &nbsp;&nbsp;&nbsp;&nbsp;100 allow task.exe="/usr/bin/passwd"<br>
1857     &nbsp;&nbsp;&nbsp;&nbsp;100 allow task.exe="/usr/sbin/sshd"<br>
1858     &nbsp;&nbsp;&nbsp;&nbsp;10000 deny
1859     </td></tr>
1860     </table>
1861    
1862     <p>It is recommended to restrict other operations such as mount, link and rename. For example, a rule to deny creation of hard links which is not owned by the user would look like below. (Note that the variable which refers source pathname of link operation is "old_path" rather than "path" because the operation is "link".)</p>
1863    
1864     <table border="1">
1865     <tr><td>
1866     100 acl link old_path.uid!=task.uid<br>
1867     &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
1868     &nbsp;&nbsp;&nbsp;&nbsp;100 deny
1869     </td></tr>
1870     </table>
1871    
1872     <p>If you can split files into different filesystems or different partitions, you might be able to utilize more variables. For example, rules for denying creation of hard links on tmpfs filesystem (tmpfs filesystem's magic number is 0x01021994) would look like below.</p>
1873    
1874     <table border="1">
1875     <tr><td>
1876     100 acl link old_path.fsmagic=0x01021994<br>
1877     &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
1878     &nbsp;&nbsp;&nbsp;&nbsp;10 deny
1879     </td></tr>
1880     </table>
1881    
1882     <p>Splitting into different partitions and defining rules based on partition's attributes will help preventing diverted access via creating hard links, for hard links cannot be created across partitions. Separating /home partition from / partition will be useful when protecting resources in /home partition.</p>
1883    
1884     <hr>
1885    
1886     <h1><a name="policy_specification">Policy Specification</a></h1>
1887    
1888     <h2><a name="available_parameters">1. About parameters which can be handled via policy</a></h2>
1889    
1890     <p>Each entry in the policy has a keyword that specifies "operation", and can optionally have "conditional expressions".</p>
1891    
1892     <p>It is possible to check parameters which can be represented as string data or numeric data using "conditional expressions".</p>
1893    
1894     <h3><a name="string_expression">1.1. String parameters representation rule</a></h3>
1895    
1896     <p>Parameters such as file's pathnames and command line arguments and environment variables are handled as string data.</p>
1897    
1898     <p>All ASCII printable characters other than \ character (i.e. from 33 to 91 and from 93 to 126) are represented as is.</p>
1899    
1900     <p>All other characters (i.e. from 0 to 32, 92 and from 127 to 255) are represented using \ooo style octal form.</p>
1901    
1902     <table border="1">
1903     <tr>
1904     <td>
1905     <table><tr><td></td><td>Lower 4 bits</td></tr><tr><td>Upper 4 bits</td><td></td></tr></table>
1906     </td>
1907     <th><p>0x0</p></th>
1908     <th><p>0x1</p></th>
1909     <th><p>0x2</p></th>
1910     <th><p>0x3</p></th>
1911     <th><p>0x4</p></th>
1912     <th><p>0x5</p></th>
1913     <th><p>0x6</p></th>
1914     <th><p>0x7</p></th>
1915     <th><p>0x8</p></th>
1916     <th><p>0x9</p></th>
1917     <th><p>0xA</p></th>
1918     <th><p>0xB</p></th>
1919     <th><p>0xC</p></th>
1920     <th><p>0xD</p></th>
1921     <th><p>0xE</p></th>
1922     <th><p>0xF</p></th>
1923     </tr>
1924     <tr>
1925     <th><p>0x0</p></th>
1926     <td><p>\000</p></td>
1927     <td><p>\001</p></td>
1928     <td><p>\002</p></td>
1929     <td><p>\003</p></td>
1930     <td><p>\004</p></td>
1931     <td><p>\005</p></td>
1932     <td><p>\006</p></td>
1933     <td><p>\007</p></td>
1934     <td><p>\010</p></td>
1935     <td><p>\011</p></td>
1936     <td><p>\012</p></td>
1937     <td><p>\013</p></td>
1938     <td><p>\014</p></td>
1939     <td><p>\015</p></td>
1940     <td><p>\016</p></td>
1941     <td><p>\017</p></td>
1942     </tr>
1943     <tr>
1944     <th><p>0x1</p></th>
1945     <td><p>\020</p></td>
1946     <td><p>\021</p></td>
1947     <td><p>\022</p></td>
1948     <td><p>\023</p></td>
1949     <td><p>\024</p></td>
1950     <td><p>\025</p></td>
1951     <td><p>\026</p></td>
1952     <td><p>\027</p></td>
1953     <td><p>\030</p></td>
1954     <td><p>\031</p></td>
1955     <td><p>\032</p></td>
1956     <td><p>\033</p></td>
1957     <td><p>\034</p></td>
1958     <td><p>\035</p></td>
1959     <td><p>\036</p></td>
1960     <td><p>\037</p></td>
1961     </tr>
1962     <tr>
1963     <th><p>0x2</p></th>
1964     <td><p>\040</p></td>
1965     <td><p>!</p></td>
1966     <td><p>"</p></td>
1967     <td><p>#</p></td>
1968     <td><p>$</p></td>
1969     <td><p>%</p></td>
1970     <td><p>&amp;</p></td>
1971     <td><p>'</p></td>
1972     <td><p>(</p></td>
1973     <td><p>)</p></td>
1974     <td><p>*</p></td>
1975     <td><p>+</p></td>
1976     <td><p>,</p></td>
1977     <td><p>-</p></td>
1978     <td><p>.</p></td>
1979     <td><p>/</p></td>
1980     </tr>
1981     <tr>
1982     <th><p>0x3</p></th>
1983     <td><p>0</p></td>
1984     <td><p>1</p></td>
1985     <td><p>2</p></td>
1986     <td><p>3</p></td>
1987     <td><p>4</p></td>
1988     <td><p>5</p></td>
1989     <td><p>6</p></td>
1990     <td><p>7</p></td>
1991     <td><p>8</p></td>
1992     <td><p>9</p></td>
1993     <td><p>:</p></td>
1994     <td><p>;</p></td>
1995     <td><p>&lt;</p></td>
1996     <td><p>=</p></td>
1997     <td><p>&gt;</p></td>
1998     <td><p>?</p></td>
1999     </tr>
2000     <tr>
2001     <th><p>0x4</p></th>
2002     <td><p>@</p></td>
2003     <td><p>A</p></td>
2004     <td><p>B</p></td>
2005     <td><p>C</p></td>
2006     <td><p>D</p></td>
2007     <td><p>E</p></td>
2008     <td><p>F</p></td>
2009     <td><p>G</p></td>
2010     <td><p>H</p></td>
2011     <td><p>I</p></td>
2012     <td><p>J</p></td>
2013     <td><p>K</p></td>
2014     <td><p>L</p></td>
2015     <td><p>M</p></td>
2016     <td><p>N</p></td>
2017     <td><p>O</p></td>
2018     </tr>
2019     <tr>
2020     <th><p>0x5</p></th>
2021     <td><p>P</p></td>
2022     <td><p>Q</p></td>
2023     <td><p>R</p></td>
2024     <td><p>S</p></td>
2025     <td><p>T</p></td>
2026     <td><p>U</p></td>
2027     <td><p>V</p></td>
2028     <td><p>W</p></td>
2029     <td><p>X</p></td>
2030     <td><p>Y</p></td>
2031     <td><p>Z</p></td>
2032     <td><p>[</p></td>
2033     <td><p>\134</p></td>
2034     <td><p>]</p></td>
2035     <td><p>^</p></td>
2036     <td><p>_</p></td>
2037     </tr>
2038     <tr>
2039     <th><p>0x6</p></th>
2040     <td><p>`</p></td>
2041     <td><p>a</p></td>
2042     <td><p>b</p></td>
2043     <td><p>c</p></td>
2044     <td><p>d</p></td>
2045     <td><p>e</p></td>
2046     <td><p>f</p></td>
2047     <td><p>g</p></td>
2048     <td><p>h</p></td>
2049     <td><p>i</p></td>
2050     <td><p>j</p></td>
2051     <td><p>k</p></td>
2052     <td><p>l</p></td>
2053     <td><p>m</p></td>
2054     <td><p>n</p></td>
2055     <td><p>o</p></td>
2056     </tr>
2057     <tr>
2058     <th><p>0x7</p></th>
2059     <td><p>p</p></td>
2060     <td><p>q</p></td>
2061     <td><p>r</p></td>
2062     <td><p>s</p></td>
2063     <td><p>t</p></td>
2064     <td><p>u</p></td>
2065     <td><p>v</p></td>
2066     <td><p>w</p></td>
2067     <td><p>x</p></td>
2068     <td><p>y</p></td>
2069     <td><p>z</p></td>
2070     <td><p>{</p></td>
2071     <td><p>|</p></td>
2072     <td><p>}</p></td>
2073     <td><p>~</p></td>
2074     <td><p>\177</p></td>
2075     </tr>
2076     <tr>
2077     <th><p>0x8</p></th>
2078     <td><p>\200</p></td>
2079     <td><p>\201</p></td>
2080     <td><p>\202</p></td>
2081     <td><p>\203</p></td>
2082     <td><p>\204</p></td>
2083     <td><p>\205</p></td>
2084     <td><p>\206</p></td>
2085     <td><p>\207</p></td>