<?xml version="1.0" encoding="ascii"?>
<!DOCTYPE dmcrypt SYSTEM "cryptfs.dtd">

<!-- Use this file as a template and save the result
     as /etc/cryptfs.xml. -->

<dmcrypt>



    <!-- Shall the encrypted filesystems be fsck'ed? -->
    <option name="fsck" value="yes"/>  <!-- This is the default. -->
    
    <!-- Shall it be mounted automatically? -->
    <option name="mount" value="yes"/> <!-- This is the default. -->



    <!-- Here comes how it searches for a tty.

         cryptfs will try each tty element until
	 it finds a tty. There are the following types:
	 
	   "current"
	       Use the tty cryptfs is attached to (if
	       there is one).
	
	   "fixed"
	       Open the given block device and use it
	       as a tty.
	       
	   "vt"
	       Switch to a new virtual terminal.
	
	   "xterm"
	       Use an xterm.

	 Some types can have additional parameters.
	 
	   dev="file"
	       The device for the "fixed" tty.
	
	   min="number"
	       For "vt": smallest virtual terminal number to use.
	       (Default: "1")
	       
	   cmd="/usr/bin/X11/xterm"
	       Command for starting xterm. Can have additional
	       options for xterm. (Default: "xterm", this may
	       not work if xterm's directory is not in PATH.)
	    
	   display=":0"
		For "xterm": The display to connect to.
		(Default: The DISPLAY environment variable.)
	
	   authority=".Xauthority-file"
	        For "xterm": The .Xauthority for connecting
		to the given display. (Default: The
		XAUTHORITY environment variable.)
	
	 The elements can also have preexec and postexec elements
	 as explained later for the action element.
	 
	 If no tty elements are given the cryptfs first
	 tries "current" and then "vt".
    -->
	    
    <tty type="current"/> <!-- Should always be put first. -->
    <tty type="xterm" display=":0" authority="/var/lib/gdm/:0.Xauth"
		cmd="/usr/bin/X11/xterm -geometry +438-20">
		<!-- Using this it is possible to open an xterm and
		     ask for a passphrase on the gdm logon screen. -->

	<preexec>pidof X >/dev/null </preexec>
	<!-- The preexec command tests whether X is running.
	     If it fails cryptfs will not try to open an xterm. -->
    </tty>
    <tty type="vt" min="8"/> <!-- As a last resort open a virtual terminal. -->
    


    <!-- Now comes the description of the *encrypted* storage.

	 For each block device there's a list of
	 the encrypted filesystems it contains.
	 Each entry contains the name of the filesystem,
	 the cipher, the size of this filesystem block and
	 the start position within the entire device.
	 
	 If there's only one filesystem or for the last
	 filesystem the size can be omitted. It will then
	 fill the entire block device. The position
	 can always be omitted, if there are no gaps
	 between the filesystems.
	 
	 size and position are given in sectors (512 bytes).
    -->
	 
    <storage device="/dev/hda6">
	<!-- My home fills the entire /dev/hda6. -->
	<entry name="alex" cipher="twofish-cbc-essiv:sha256"/>
    </storage>
    
    <storage device="/dev/hdb2">
	<!-- The "start" tags are redundant. -->
	<entry name="backup" cipher="twofish-cbc-essiv:sha256" start="0"       size="4000000"/> <!-- 2 GB -->
	<entry name="music"  cipher="twofish-cbc-essiv:sha256" start="4000000" size="2000000"/> <!-- 1 GB -->
	
	<!-- Add an additional gigabyte to my backup partition... -->
	<entry name="backup" cipher="twofish-cbc-essiv:sha256" start="6000000" size="2000000"/> <!-- 1 GB -->
	
	<!-- If hdb2 has enough space left you can extend these filesystems
	     by adding additional entries with the same filesystem
	     name.
	-->
    </storage>
    
    <storage device="/dev/hda7">
	<!-- My swap partition is also encrypted. -->
	<entry name="swap" cipher="twofish-cbc-essiv:sha256"/>
    </storage>
    
    
    
    <!-- Now to the action definitions. The name of an action
         is arbitrary.
    -->
    
    <action name="usbstick"> <!-- My USB stick was plugged in. -->
    
	<!-- How to obtain the key?

	     cryptfs offers the following types:
	      
	       "passphrase"
		   Ask for a passphrase, which will then be hashed.
	
	       "file"
	           Take a file as the key.
	
	       "program"
	           Execute a program and hash the standard output.
	
	       "literal"
	           Take the contents of this element
		   and hash it.
	     
	       "composite"
	           XOR several keys together.

	     This will be specified in the key element, which
	     can have the following attributes:
	        
	       id="somename"
	           Can be omitted and is only for referencing it later
		   in another key-Element. (Then a <key id="name"/>
		   will suffice.)
		 
	       type="..."
	           One of the types above.
		   
	       length="key-length"
	            Gives the needed key length.

	       algo="hash-algorithm"
	           For "passphrase", "program" and "literal" this specifies
		   the hash algorithm to be used. Something like
		   "md5", "sha1", "rmd160", "sha256", "sha512" or "none".
		   Default is "sha256" (or if the key length is given
		   one of the SHA family that is long enough).
		
		newline="unchanged"
		   Can be "add", "remove" or "unchanged".
		   "add" adds a newline at the end of the passphrase
		   if there isn't one. "remove" removes (exactly) one
		   newline from the end of the passphrase.
		   (Default: "unchanged")
	
	       ignorestatus, uid, gid, needtty
		   Have for "program" the same meaning as in the
		   preexec and postexec elements.
	-->

	<key id="general" type="composite" length="256">
	    <!-- This is a two factor authentication.
	         You need an usbstick with one part of the key on it
		 and a password.
	    -->
	    
            <key type="file">

		<!-- You can give some commands to be executed before the file is read.
		     One command per <preexec> element. Each <action> and <map>
		     element can also contain <preexec> and <postexec> elements.
	     
	    	     preexec and postexec can have the following attributes:
    
        	       ignorestatus="yes"  
        	           The return status should be ignored. Otherwise
        		   a return state other than zero will be interpreted
        		   as an error and thus this action be aborted.
        		   Default: "no"
	
        	       uid="user"
        	           Execute this program under this uid.
		 
        	       gid="group"
        	           Execute this program under this gid.
		 
        	       needtty="yes"
        	           Make sure, that the program has a TTY connected
        		   to its input and output. As a last resort
        		   cryptfs will switch to a new virtual console
        		   und use it. Default: "no"
	
        	       retry="maximal number of retries"
			   If cryptfs detects that the given key is wrong,
                           it can try and ask again. The only way such a
			   situation can occur is because of a failed fsck,
			   mount or postexec command. Default is no retries.

		       vt100="number of lines to reserve"
                           If given cryptfs reserves the number of lines of
			   the bottom of the screen for showing the passphrase
			   prompt. Scrolling does then only happen in the
			   area above these lines (passphrase only). This
			   option requires a VT100 compliant terminal.

        	       onstate="success", "failure" or "always"
        	           This is particularly interesting for postexec
        		   and says, whether this command should be executed
        		   after a successful or aborted action.
        		   Default: "success"
        	-->
		
                <preexec>
                    mount /media/usbstick
                </preexec>

                /media/usbstick/hdkey

                <postexec onstate="always" ignorestatus="yes">
		    umount /media/usbstick
                </postexec>
            </key>
	    
	    <!-- Instead of "passphrase" I use the dialog or Xdialog
	         programs, because they look better... -->
	    <key type="program" needtty="yes" newline="remove">
		<!-- The newline="remove" is important, because
		     Xdialog appends a newline, dialog doesn't. -->
                if [ -n "$DISPLAY" ]; then
                    Xdialog --backtitle 'Encryption for Alex' \
                                --stdout \
                                --passwordbox 'Please enter the filesystem password:' 12 40
                else
                    dialog --backtitle 'Encryption for Alex' \
                           --clear --stdout \
                           --passwordbox 'Enter the filesystem password:' 8 50
                fi
	    </key>
	</key>

	<!-- Now we decrypt the filesystems.
	     Just a <map name="alex"/> is enough to
	     decrypt the "alex" filesystem specified above
	     (in the storage elements) with the key given above,
	     and to fsck and mount it.
	     
	     But the map element can have the following attributes:
	     
	       name="fsname"
	           The name of the filesystem (as in the storage elements).
		   A block device with this name will be put into
		   /dev/mapper, which will contain the decrypted
		   file system.
	
	       as="dname"
	           Specifies  the name which the resulting device should get
		   in the /dev/mapper directory. If omitted the value
		   of the name attribute is used.
		   
	       fsck="yes"
	           Overrides the general option and says whether
		   the filesystem should be fsck'ed.
		
	       mount="yes"
		   Overrides the general option and says whether
		   the filesystem should be mounted.
		    
	       point="/the/mount/point"
	           The mount point of this filesystem.
	           (Can be omitted, if it's in /etc/fstab.)
	
	       fs="filesystem"
		   The filesystem type ("ext3" etc.)
		    
	       options="mount options"
		   Mount options (as can be given with the -o option
		   of mount).
		
	       ro="yes"
	           The device will be set to read-only.
	
	       mode="0660"
	           The file mode of the block device.
		
	       uid="user", gid="group"
	           Sets the uid and gid of the block device.
		    
	    
	    The map element can also contain preexec and postexec
	    elements to execute commands. It can also have
	    an own key element to override the one given in the
	    action element.
	-->
	     
	<map name="alex">
	    <postexec ignorestatus="yes" uid="alex">
		fetchmail -f /home/alex/.fetchmailrc
	    </postexec>
	</map>
	<map name="music"/>
	<map name="backup"/>
    </action>

    <!-- Several other actions can follow... -->
    
    <!-- For example a swap partition: -->
    <action name="swap">
	<!-- Use a random key for the swap partion.
	     (Suspend-to-disk won't work with this.) -->

        <key type="composite">
	    <key type="file" length="256">/dev/hda5</key>
	    <key type="file" length="256">/dev/random</key>
	</key>
						
	<!-- It's not a filesystem, so no fsck and mount. -->
	<map name="swap" fsck="no" mount="no">
	    <!-- Set up the swap area.
	         WARNING: It destroys all data of this partition.
		          Make sure, it's the right one!
	    -->
	    <postexec onmode="map">
		/sbin/mkswap /dev/mapper/swap
		swapon /dev/mapper/swap
	    </postexec>
	</map>
    </action>

</dmcrypt>
