<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Little Impact</title>
	<atom:link href="http://blog.littleimpact.de/index.php/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.littleimpact.de</link>
	<description>Things that have more than zero impact (on my live)</description>
	<lastBuildDate>Sun, 16 Oct 2011 12:45:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Using BioLux NV microscope in Ubuntu Linux</title>
		<link>http://blog.littleimpact.de/index.php/2011/10/16/using-biolux-nv-on-ubuntu-linux/</link>
		<comments>http://blog.littleimpact.de/index.php/2011/10/16/using-biolux-nv-on-ubuntu-linux/#comments</comments>
		<pubDate>Sun, 16 Oct 2011 12:45:33 +0000</pubDate>
		<dc:creator>Henryk</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[GNU Linux]]></category>

		<guid isPermaLink="false">http://blog.littleimpact.de/?p=33</guid>
		<description><![CDATA[I recently got a Bresser BioLux NV microscope. Of course it is quite cheap and you get what you pay for. I&#039;m still very pleased with it because it is a fun toy, and I&#039;m not afraid to destroy something by not treating it properly. I&#039;m also happy that the cam works well with Linux. [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.littleimpact.de/wp-content/uploads/2011/10/cell.jpg" alt="A human cell" title="Cell" width="211" height="200" class="alignright size-full wp-image-34" /><br />
I recently got a <a href="http://www.365astronomy.com/bresser-biolux-al-microscope-kit-p-1731.html">Bresser BioLux NV</a> microscope. Of course it is quite cheap and you get what you pay for. I&#039;m still very pleased with it because it is a fun toy, and I&#039;m not afraid to destroy something by not treating it properly. I&#039;m also happy that the cam works well with Linux.</p>
<p><span id="more-33"></span><br />
The cam only has a VGA 640&#215;480 resolution but for me that&#039;s sufficient. It is recognized by my old Ubuntu 10.10:<br />
<code><br />
$ lsusb<br />
Bus 002 Device 004: ID 18ec:3366 Arkmicro Technologies Inc<br />
...<br />
</code><br />
It looks like there is a very similar model with a <a href="http://www.spurtikus.de/basteln/mikros/index.html">different cam</a>.<br />
So far I use <a href="http://projects.gnome.org/cheese/index">Cheese</a> to look at my objects of interest (the two programs i found so far seem not to be intended for my purpose; <a href="http://gxsm.sourceforge.net/">http://gxsm.sourceforge.net/</a>, <a href="http://valelab.ucsf.edu/~MM/MMwiki/index.php/Micro-Manager">http://valelab.ucsf.edu/~MM/MMwiki/index.php/Micro-Manager</a>).</p>
<p>To get an idea of the magnification, here are 2 mm in the lowest magnification (4x objective times cam optics):<br />
<a href='http://blog.littleimpact.de/wp-content/uploads/2011/10/scale.jpg'><img src="http://blog.littleimpact.de/wp-content/uploads/2011/10/scale.jpg" alt="" title="Scale magnified by 4x objective" width="500" height="375" class="aligncenter size-full wp-image-35" /></a></p>
<p>I looked at the obligatory leg of a fly:<br />
<a href='http://blog.littleimpact.de/wp-content/uploads/2011/10/fly_leg_x4.jpg'><img src="http://blog.littleimpact.de/wp-content/uploads/2011/10/fly_leg_x4.jpg" alt="Leg of a fly, 4x objective" title="Leg of a fly" width="500" height="375" class="aligncenter size-full wp-image-36" /></a><br />
<a href='http://blog.littleimpact.de/wp-content/uploads/2011/10/fly_leg_x10.jpg'><img src="http://blog.littleimpact.de/wp-content/uploads/2011/10/fly_leg_x10.jpg" alt="Leg of a fly, 10x objective" title="Leg of a fly" width="500" height="375" class="aligncenter size-full wp-image-37" /></a><br />
<a href='http://blog.littleimpact.de/wp-content/uploads/2011/10/fly_leg_x40.jpg'><img src="http://blog.littleimpact.de/wp-content/uploads/2011/10/fly_leg_x40.jpg" alt="Leg of a fly, x40 objective" title="Leg of a fly" width="500" height="375" class="aligncenter size-full wp-image-38" /></a><br />
The scale of the above image is 0.2mm (taken with 40x objective). At this scale you got to decide where to focus:<br />
<a href='http://blog.littleimpact.de/wp-content/uploads/2011/10/fly_leg_x40_2.jpg'><img src="http://blog.littleimpact.de/wp-content/uploads/2011/10/fly_leg_x40_2.jpg" alt="Leg of a fly, 40x objective" title="Leg of a fly" width="500" height="375" class="aligncenter size-full wp-image-39" /></a></p>
<p>And finally a riddle. Can you guess what&#039;s this?<br />
<a href='http://blog.littleimpact.de/wp-content/uploads/2011/10/2011-10-13-202518.jpg'><img src="http://blog.littleimpact.de/wp-content/uploads/2011/10/2011-10-13-202518.jpg" alt="Riddle" title="Riddle" width="500" height="375" class="aligncenter size-full wp-image-40" /></a><br />
<a href='http://blog.littleimpact.de/wp-content/uploads/2011/10/2011-10-13-202537.jpg'><img src="http://blog.littleimpact.de/wp-content/uploads/2011/10/2011-10-13-202537.jpg" alt="Riddle, x10 objective" title="Riddle2" width="500" height="375" class="aligncenter size-full wp-image-41" /></a><br />
<a href='http://blog.littleimpact.de/wp-content/uploads/2011/10/2011-10-13-202646.jpg'><img src="http://blog.littleimpact.de/wp-content/uploads/2011/10/2011-10-13-202646.jpg" alt="Riddle, 40x objective" title="Riddle 3" width="500" height="375" class="aligncenter size-full wp-image-42" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.littleimpact.de/index.php/2011/10/16/using-biolux-nv-on-ubuntu-linux/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ubuntu Linux 10.10 on Samsung NP-R540</title>
		<link>http://blog.littleimpact.de/index.php/2011/03/25/ubuntu-linux-1010-on-samsung-np-r540/</link>
		<comments>http://blog.littleimpact.de/index.php/2011/03/25/ubuntu-linux-1010-on-samsung-np-r540/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 14:41:20 +0000</pubDate>
		<dc:creator>Henryk</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[GNU Linux]]></category>

		<guid isPermaLink="false">http://blog.littleimpact.de/?p=30</guid>
		<description><![CDATA[I recently bought a cheap Samsung NP-R540 with an ATI Mobility Radeon HD 4500. Ubuntu 10.10 installed smoothly. I encountered two problems: The comercial ATI-video driver did not want to install, so I switched to the free driver and I&#039;m happy since. The Touchpad does not work well for me in multitouch-mode. Hardware Details # [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://blog.littleimpact.de/wp-content/uploads/2011/03/etracer.jpg'><img src="http://blog.littleimpact.de/wp-content/uploads/2011/03/etracer-300x202.jpg" alt="Extreme Tuxracer with free ATI-Driver" title="Extreme Tuxracer with free ATI-Driver" width="300" height="202" class="alignright size-medium wp-image-31" /></a><br />
I recently bought a cheap Samsung NP-R540 with an ATI Mobility Radeon HD 4500.<br />
Ubuntu 10.10 installed smoothly.  I encountered two problems:</p>
<ul>
<li> The comercial ATI-video driver did not want to install, so I switched to<br />
               the free driver and I&#039;m happy since.</li>
<li>The Touchpad does not work well for me in multitouch-mode.</li>
</ul>
<p><span id="more-30"></span></p>
<h2>Hardware Details</h2>
<p><code><br />
# lspci<br />
00:00.0 Host bridge: Intel Corporation Core Processor DRAM Controller (rev 02)<br />
00:01.0 PCI bridge: Intel Corporation Core Processor PCI Express x16 Root Port (rev 02)<br />
00:1a.0 USB Controller: Intel Corporation 5 Series/3400 Series Chipset USB2 Enhanced Host Controller (rev 05)<br />
00:1b.0 Audio device: Intel Corporation 5 Series/3400 Series Chipset High Definition Audio (rev 05)<br />
00:1c.0 PCI bridge: Intel Corporation 5 Series/3400 Series Chipset PCI Express Root Port 1 (rev 05)<br />
00:1c.2 PCI bridge: Intel Corporation 5 Series/3400 Series Chipset PCI Express Root Port 3 (rev 05)<br />
00:1c.3 PCI bridge: Intel Corporation 5 Series/3400 Series Chipset PCI Express Root Port 4 (rev 05)<br />
00:1d.0 USB Controller: Intel Corporation 5 Series/3400 Series Chipset USB2 Enhanced Host Controller (rev 05)<br />
00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev a5)<br />
00:1f.0 ISA bridge: Intel Corporation Mobile 5 Series Chipset LPC Interface Controller (rev 05)<br />
00:1f.2 SATA controller: Intel Corporation 5 Series/3400 Series Chipset 4 port SATA AHCI Controller (rev 05)<br />
00:1f.3 SMBus: Intel Corporation 5 Series/3400 Series Chipset SMBus Controller (rev 05)<br />
01:00.0 VGA compatible controller: ATI Technologies Inc M92 [Mobility Radeon HD 4500 Series]<br />
01:00.1 Audio device: ATI Technologies Inc RV710/730<br />
02:00.0 Network controller: Broadcom Corporation BCM4313 802.11b/g LP-PHY (rev 01)<br />
06:00.0 Ethernet controller: Marvell Technology Group Ltd. 88E8040 PCI-E Fast Ethernet Controller<br />
3f:00.0 Host bridge: Intel Corporation Core Processor QuickPath Architecture Generic Non-core Registers (rev 02)<br />
3f:00.1 Host bridge: Intel Corporation Core Processor QuickPath Architecture System Address Decoder (rev 02)<br />
3f:02.0 Host bridge: Intel Corporation Core Processor QPI Link 0 (rev 02)<br />
3f:02.1 Host bridge: Intel Corporation Core Processor QPI Physical 0 (rev 02)<br />
3f:02.2 Host bridge: Intel Corporation Core Processor Reserved (rev 02)<br />
3f:02.3 Host bridge: Intel Corporation Core Processor Reserved (rev 02)<br />
</code></p>
<p><code><br />
# lsusb<br />
Bus 002 Device 004: ID 0a5c:219c Broadcom Corp.<br />
Bus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub<br />
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub<br />
Bus 001 Device 003: ID 1210:25f4 DigiTech<br />
Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub<br />
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub<br />
</code></p>
<h2>Network</h2>
<p>Both ethernet and wifi worked out of the box.</p>
<h2>3D Acceleration</h2>
<p>I first downloaded the commercial <a href='http://support.amd.com/us/gpudownload/Pages/index.aspx'>ATI driver</a> from <a href="http://www2.ati.com/drivers/linux/ati-driver-installer-11-2-x86.x86_64.run">http://www2.ati.com/drivers/linux/ati-driver-installer-11-2-x86.x86_64.run</a><br />
And tried to install with:<br />
<code><br />
sudo ./ati-driver-installer-10-9-x86.x86_64.run --listpkg<br />
sudo ./ati-driver-installer-10-9-x86.x86_64.run --buildpkg Ubuntu/maverick<br />
ls fglrx*<br />
sudo dpkg -i fglrx*<br />
</code><br />
But this failed with some compilation error. So I decided to use the free driver (instructions <a href="https://help.ubuntu.com/community/RadeonDriver">here</a> and <a href="https://help.ubuntu.com/community/RadeonDriver">here</a>):<br />
<code><br />
  sudo /usr/share/ati/fglrx-uninstall.sh  # (if it exists)<br />
  sudo apt-get remove --purge fglrx*<br />
  sudo apt-get remove --purge xserver-xorg-video-ati xserver-xorg-video-radeon<br />
  sudo apt-get install xserver-xorg-video-ati<br />
  sudo apt-get install --reinstall libgl1-mesa-glx libgl1-mesa-dri xserver-xorg-core<br />
  sudo dpkg-reconfigure xserver-xorg<br />
</code><br />
The free driver works well for my needs (a bit of 3D visualisation and Tuxracer now and then).</p>
<h2>Multimedia</h2>
<p>Sound, microphone and webcam worked out of the box (don&#039;t forget to unmute your mic if you try it!). </p>
<h2>Touchpad</h2>
<p>The touchpad gives me the most headaches. In normal mode it works just fine but it does not offer a scrollbar on the right. In (Gnome) System/Preferences/Mouse/Touchpad I enabled two finger scrolling, but the experience is not satisfying.</p>
<h2>Special Keys</h2>
<p><strong>Fn-Volume up/down</strong> &#8211; works<br />
<strong>Fn-Brightness up/down</strong> &#8211; works<br />
<strong>Fn-ESC (Suspend to disk)</strong> &#8211; works<br />
<strong>Fn-F2 (Battery status)</strong> &#8211; works<br />
<strong>Fn-F3 (EUR)</strong> &#8211; does not work (but Alt Gr-e does)<br />
<strong>Fn-F4 (switch screen)</strong> &#8211; did not check yet<br />
<strong>Fn-F5 (Brightness???)</strong> &#8211; does not work<br />
<strong>Fn-F6 (Mute)</strong> &#8211; works<br />
<strong>Fn-F7 (???)</strong> &#8211; does not work<br />
<strong>Fn-F8 (???)</strong> &#8211; does not work<br />
<strong>Fn-F9 (Wifi on/off)</strong> &#8211; does not work<br />
<strong>Fn-F12 (???)</strong> &#8211; does not work</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.littleimpact.de/index.php/2011/03/25/ubuntu-linux-1010-on-samsung-np-r540/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>True is False</title>
		<link>http://blog.littleimpact.de/index.php/2010/07/21/true-is-false/</link>
		<comments>http://blog.littleimpact.de/index.php/2010/07/21/true-is-false/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 12:51:08 +0000</pubDate>
		<dc:creator>Henryk</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Sucks]]></category>

		<guid isPermaLink="false">http://blog.littleimpact.de/?p=25</guid>
		<description><![CDATA[Usually I prefer to rant about the oddities of ruby but this time it&#039;s python. Python 2.5.2 (r252:60911, Jan 20 2010, 21:48:48) [GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu3)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> True True >>> False False >>> True,False=False,True >>> True False >>> False True >>> False=True >>> True [...]]]></description>
			<content:encoded><![CDATA[<p>Usually I prefer to rant about the oddities of ruby but this time it&#039;s python.<br />
<span id="more-25"></span><br />
<code><br />
Python 2.5.2 (r252:60911, Jan 20 2010, 21:48:48)<br />
[GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu3)] on linux2<br />
Type "help", "copyright", "credits" or "license" for more information.<br />
>>> True<br />
True<br />
>>> False<br />
False<br />
>>> True,False=False,True<br />
>>> True<br />
False<br />
>>> False<br />
True<br />
>>> False=True<br />
>>> True = True is False<br />
>>> False = True is False<br />
>>> True<br />
True<br />
>>> False<br />
False<br />
</code></p>
<p>Well, if it was lisp I wouldn&#039;t be surprised&#8230;.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.littleimpact.de/index.php/2010/07/21/true-is-false/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Auto reload and poor man&#039;s http caching in PHP</title>
		<link>http://blog.littleimpact.de/index.php/2009/09/24/auto-reload-and-poor-mans-http-caching-in-php/</link>
		<comments>http://blog.littleimpact.de/index.php/2009/09/24/auto-reload-and-poor-mans-http-caching-in-php/#comments</comments>
		<pubDate>Thu, 24 Sep 2009 16:30:50 +0000</pubDate>
		<dc:creator>Henryk</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Sucks]]></category>

		<guid isPermaLink="false">http://blog.littleimpact.de/?p=23</guid>
		<description><![CDATA[I recently had a problem with my website zimmer69.de. Some not so nice fellow told his opera browser to reload a 300k page every 5 seconds, moved it to some tab and forgot about it for weeks. He caused 2 Gb of traffic per day. Time to implement some cache control. My first measure to [...]]]></description>
			<content:encoded><![CDATA[<p><strong>I recently had a problem with my website <a href="http://www.zimmer69.de">zimmer69.de</a>. Some not so nice fellow told his opera browser to reload a 300k page every 5 seconds, moved it to some tab and forgot about it for weeks. He caused  2 Gb of traffic per day. Time to implement some cache control. </strong><br />
<span id="more-23"></span><br />
My first measure to gain some time, was to delay the delivery of every page to  opera browsers by 30 seconds. After finding out about the feature that caused the trouble, I was close to just exclude opera from the site. But Firefox has the same functionality by some <a href="https://addons.mozilla.org/de/firefox/addon/115">add-on</a>. So I needed a different solution.</p>
<p>Some part of the fault was on my side, since i did not have any cache control implemented. Fortunally the &#034;reload every 5 seconds&#034;-feature supports caching. I finally implemented proper caching, but I want to show a quick and dirty solution, that would have reduced the load considerably without a proper solution.</p>
<h2>Caching</h2>
<p>There are different levels of caching in each layer starting from the browser cache, <a href="http://en.wikipedia.org/wiki/Web_cache">web cache</a>, <a href="http://en.wikipedia.org/wiki/Reverse_proxy">reverse proxies</a>, page-caches, <a href="http://ch2.php.net/apc/">code caches</a> and then you database has a query cache and your opperating system too down to the caching in your CPU. I&#039;m only intrested browser and web cache, since I want to reduce my bandwith usage.</p>
<p>You may read a  <a href="http://www.mnot.net/cache_docs/">good description of web caches</a> but you can also just read on.</p>
<h2>Poor man&#039;s cache</h2>
<p>A simple solution to aboves opera problem is to just pretend that the page does not change for a certain amount of time. That&#039;s what the following function does:</p>
<pre>
# Implements a fake cache control. Reads/sends headers so that the page will only get stale
# if it was deliverd more than $seconds seconds ago.
# If $ua_regexp is given and the user agent does not match it, then no fake caching takes place.
function fake_cache($seconds = 60, $ua_regexp = "") {
  $ims_epoch = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
  $now_epoch = time();
  if ($ua_regexp &#038;&#038; !eregi($ua_regexp, $_SERVER['HTTP_USER_AGENT'])) {
    return;
  }
  if ($now_epoch < $ims_epoch + $seconds) {
    #old version is still vald
    header("HTTP/1.0 304 Not Modified");
    exit;
  }
  $mod_gmt = gmdate("D, d M Y H:i:s", $now_epoch) ." GMT";
  $exp_gmt = gmdate("D, d M Y H:i:s", $now_epoch + $seconds) ." GMT";
  header("Expires: $exp_gmt");
  header("Last-Modified: $mod_gmt");
}
</pre>
<p>Now you can put</p>
<pre>
fake_cache();
</pre>
<p>in front of your big pages, so that they will be cached for 60 seconds or</p>
<pre>
fake_cache(600,"opera");
</pre>
<p>if you want to deliver your pages only every 10 minutes to unfriendly opera users.</p>
<p>Note that every first time visitor gets a current version of the page.</p>
<h2>Opera  is hammering my server, who is to blame?</h2>
<p>I think it is bad practice by opera to offer such a "reload every 5 seconds" feature to users not aware what this could mean. This feature makes opera a bot with a nice gui. But it does not check for robots.txt nor could a webmaster limit this stupidity through it.</p>
<p>Of course opera only does what the user tells it to do. But I really think that opera should warn him if he choses a short reload interval and there is no caching going on. At least after restart of opera it could stop reloading the page or nag the user about it. The command line utility <code>ping</code> made a better decision in this respect:</p>
<pre>
me@mybox$ ping -f www.opera.com
PING front.opera.com (195.189.143.147) 56(84) bytes of data.
ping: cannot flood; minimal interval, allowed for user, is 200ms
</pre>
<h2>References</h2>
<ul>
<li><a href="http://ontosys.com/php/cache.html">http://ontosys.com/php/cache.html</a></li>
<li><a href="http://www.developertutorials.com/tutorials/php/php-caching/page1.html">http://www.developertutorials.com/tutorials/php/php-caching/page1.html</a></li>
<li><a href="http://www.mnot.net/cache_docs/">http://www.mnot.net/cache_docs/</a></li>
<li><a href="http://www.sitepoint.com/article/caching-php-performance/">http://www.sitepoint.com/article/caching-php-performance/</a></li>
<li><a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9">http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.littleimpact.de/index.php/2009/09/24/auto-reload-and-poor-mans-http-caching-in-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automatic encryption of home directories using TrueCrypt 6.2a and pam_exec</title>
		<link>http://blog.littleimpact.de/index.php/2009/09/14/automatic-encryption-of-home-directories-using-truecrypt-62-and-pam_exec/</link>
		<comments>http://blog.littleimpact.de/index.php/2009/09/14/automatic-encryption-of-home-directories-using-truecrypt-62-and-pam_exec/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 21:06:21 +0000</pubDate>
		<dc:creator>Henryk</dc:creator>
				<category><![CDATA[GNU Linux]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[truecrypt]]></category>

		<guid isPermaLink="false">http://blog.littleimpact.de/?p=22</guid>
		<description><![CDATA[This post describes how to encrypt the home directory of your users on GNU Linux with the help of TrueCrypt and PAM using the login-password as encryption key. I wrote about Automatic encryption of home directories using TrueCrypt before. This time we&#039;ll use TrueCrypt 6.2a. Futhermore we&#039;ll use Ubuntu 9.04 Jaunty Jackalope and we replaced [...]]]></description>
			<content:encoded><![CDATA[<p><b>This post describes how to encrypt the home directory of your users on GNU Linux with the help of <a href="http://www.truecrypt.org/">TrueCrypt</a> and <a href="http://www.kernel.org/pub/linux/libs/pam/">PAM</a> using the login-password as encryption key.<br />
I wrote about <a href='http://blog.littleimpact.de/index.php/2008/08/19/automatic-encryption-of-home-directories-using-truecrypt-60a/'>Automatic encryption of home directories using TrueCrypt</a> before. This time we&#039;ll use TrueCrypt 6.2a. Futhermore we&#039;ll use <a href='https://wiki.ubuntu.com/JauntyJackalope'>Ubuntu 9.04 Jaunty Jackalope</a> and we replaced pam_mount by pam_exec. For convenience this post will be selfcontained (ie. I copy redundant parts from the old one).</b><br />
<span id="more-22"></span><br />
Using the method described below is no silver bullet and has some issues:</p>
<ul>
<li>Your user passwords may be weak.</li>
<li>If your computer gets stolen while turned on, the passwort may be easier to recover than you might think (see <a href="http://citp.princeton.edu/memory/">here</a>).</li>
<li>Changing the password requires to log in as root.</li>
<li>Some programs (e.g. qmail) rely on an accessible home directory.</li>
<li>The home may accidently stay mounted after logout until the next reboot.</li>
<li>Suspend to ram and suspend to disk are not treated carefully enough.</li>
<li>There may be glitches in my scripts.</li>
</ul>
<h3>Prequisites</h3>
<ul>
<li>GNU Linux (<a href='https://wiki.ubuntu.com/JauntyJackalope'>Ubuntu 9.04 Jacky Jackalope </a>)</li>
<li><a href="http://www.truecrypt.org/">TrueCrypt</a> (I used  6.2a)</li>
<li>a modern pam_exec.so (<a href="#pam_exec">see below</a>)</li>
</ul>
<h3>Setup</h3>
<p>We will create one file for each user to hold his encrypted home directory. To keep them we create a directory:</p>
<pre>mkdir /home/private</pre>
<p>For each user we have to create an encrypted file in /home/private. We start with the user bart (if you leave out the <code>--text</code> you&#039;ll get a graphical user interface).</p>
<pre>root@mybox:~# truecrypt  --text --create /home/private/bart.tc
Volume type:
1) Normal
2) Hidden
Select [1]: 1

Enter volume size (bytes - size/sizeK/sizeM/sizeG): 1G

Encryption algorithm:
 1) AES
 2) Serpent
 3) Twofish
 4) AES-Twofish
 5) AES-Twofish-Serpent
 6) Serpent-AES
 7) Serpent-Twofish-AES
 8 ) Twofish-Serpent
Select [1]: 1

Hash algorithm:
 1) RIPEMD-160
 2) SHA-512
 3) Whirlpool
Select [1]: 1

Filesystem:
 1) FAT
 2) None
Select [1]: 2

Enter password: *************
WARNING: Short passwords are easy to crack using brute force techniques!

We recommend choosing a password consisting of more than 20 characters. Are you sure you want to use a short password? (y=Yes/n=No) [No]: y

Re-enter password:*************

Enter keyfile path [none]:

Please type at least 320 randomly chosen characters and then press Enter:
dsglregmm;adsf;dsafdsasasadfdsafdsagfdsadsafdsafdsafadsfdsahfarweqasddsaglfdsakg;lrewqk;lggkqqqqqewrgsadgdsag....

Done: 100.000%  Speed: 18.0 MB/s  Left: 0 s

The TrueCrypt volume has been successfully created.
</pre>
<p>Then we assign the same password as the login password to bart:</p>
<pre>root@mybox:~# passwd bart
Enter new UNIX password:
Retype new UNIX password:
</pre>
<p>Next, we need to format the encrypted partition and move the old home directory into it:</p>
<pre>
root@mybox:~# truecrypt --text --filesystem=none /home/private/bart.tc
Enter password for /home/hgerlach/newcrypt.tc: *************
Enter keyfile [none]:
Protect hidden volume? (y=Yes/n=No) [No]:

root@mybox:~#  truecrypt --text -l
1: /home/private/bart.tc /dev/mapper/truecrypt1 -

root@mybox:~# mkfs.ext2 /dev/mapper/truecrypt1
root@mybox:~# mount /dev/mapper/truecrypt1 /mnt/
root@mybox:~# shopt -s dotglob #make dotfiles visible
root@mybox:~# mv /home/bart/* /mnt/
root@mybox:~# chown bart.users /mnt/
root@mybox:~# umount /mnt
root@mybox:~# truecrypt -d /dev/mapper/truecrypt1
</pre>
<p>Now we have to make sure the homedir gets mounted on login. Previously I used pam_mount but they dropped truecrypt support and <a href="http://pam-mount.git.sourceforge.net/git/gitweb.cgi?p=pam-mount/pam-mount;a=blob;f=doc/changelog.txt;h=429f6c221b418b93c573b37474b4dc6066d2128a;hb=2de22dc51f4daba5bef2c47f97e22567bb649096">sound somewhat angry on trucrypt</a> (because they changed their interface). I was not so happy with pam_mount myself and reported <a href="http://sourceforge.net/tracker/?func=detail&#038;aid=2802931&#038;group_id=41452&#038;atid=430593">a bug</a> which got fixed quickly but will take some time to appear downstream in Ubuntu or Debian. </p>
<p>This time I decided to roll my own mount/umount script. It relies on a <a href="http://osdir.com/ml/pam/2006-07/msg00027.html">&#034;modern&#034;</a> version  of <a href="http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/sag-pam_exec.html">pam_exec</a> that supports the <code>expose_authok</code> option. Unfortunally Ubuntu does not come with this modern version yet, so you <del datetime="2009-09-24T16:35:50+00:00">either</del> have to <del datetime="2009-09-24T16:35:50+00:00">download it from me (i386-32bit, no guarantees, infected with rootkit by now) or</del> <a href="#pam_exec">compile it yourself</a>. You should copy the lib to<br />
<code>/lib/security/pam_exec_UNSTABLE.so</code> so pam can find it.</p>
<p>To the file  &#039;/etc/pam.d/common-auth&#039; we add the line:<br />
<code>auth    optional     pam_exec_UNSTABLE.so  debug expose_authtok seteuid /bin/bash /bin/cryptmount.sh</code><br />
so it looks like</p>
<pre># /etc/pam.d/common-auth
# here are the per-package modules (the "Primary" block)
auth    [success=1 default=ignore]      pam_unix.so nullok_secure
# here's the fallback if no module succeeds
auth    requisite                       pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
auth    required                        pam_permit.so
# and here are more per-package modules (the "Additional" block)
# end of pam-auth-update config
auth    optional     pam_exec_UNSTABLE.so  debug expose_authtok seteuid /bin/bash /bin/cryptmount.sh
</pre>
<p>and to  &#039;/etc/pam.d/common-session&#039; we add the line<br />
<code>session optional     pam_exec_UNSTABLE.so seteuid /bin/bash /bin/cryptmount.sh</code><br />
so it looks like</p>
<pre>
# ...
# here are the per-package modules (the "Primary" block)
session [default=1]                     pam_permit.so
# here's the fallback if no module succeeds
session requisite                       pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
session required                        pam_permit.so
# and here are more per-package modules (the "Additional" block)
session required        pam_unix.so
session optional                        pam_ck_connector.so nox11
# end of pam-auth-update config
session optional     pam_exec_UNSTABLE.so seteuid /bin/bash /bin/cryptmount.sh
</pre>
<p>Everytime we log in or a new session starts the script <code>/bin/cryptmount.sh</code> gets executed.<br />
Thats what I propose it to look like:</p>
<pre>
#!/bin/bash
# /bin/cryptmount.sh

CRYPTVOLUME=/home/private/$PAM_USER.tc
MOUNTPOINT=/home/$PAM_USER

case "$PAM_USER" in
  root | lisa ) #homedirs of root and lisa are not encrypted
    exit 0
  ;;
esac

case "$PAM_TYPE" in
      auth )
         head -c -1 | truecrypt -t  --protect-hidden=no -k "" \
                      "$CRYPTVOLUME" "$MOUNTPOINT"
      ;;
      close_session )
         MOUNTS=$(mount | grep " $MOUNTPOINT ")
         if test -z $MOUNTS ; then
           echo MOUNTS  $MOUNTS > /tmp/debug
           exit 0
         fi
         OTHER=$(who | grep "^$PAM_USER " | grep -v " $PAM_TTY ")
         if test -z "$OTHER"; then
            echo truecrypt -d $MOUNTPOINT | at now + 1 minute
         fi
      ;;
esac
exit 0
</pre>
<p>It first checks whether root or lisa (adapt to your own needs) is calling it. Both of them do not have encrypted homedirs, so the script exits. In the second case clause it checks wheter it is called while authenticating and mounts the homdir using the login passphrase or if it is called for closing a session. In the latter case it schedules unmounting the homedir in one minute.</p>
<p>Now bart can login and use the encrypted home. One minute after logoff the homedir will be umounted and encrypted again.</p>
<h3><a name="pam_exec">How to roll your own pam_exec_UNSTABLE.so</a></h3>
<pre>
# get the source (after searching packages.debian.org)
wget http://ftp.de.debian.org/debian/pool/main/p/pam/pam_1.1.0.orig.tar.gz
tar xfzv pam_1.1.0.orig.tar.gz
cd Linux-PAM-1.1.0/
./configure

# install all packages needed for configure to run through
cd modules/pam_exec/
make
# yes this is dirty, but who cares.
sudo cp .libs/pam_exec.so /lib/security/pam_exec_UNSTABLE.so
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.littleimpact.de/index.php/2009/09/14/automatic-encryption-of-home-directories-using-truecrypt-62-and-pam_exec/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Usage of hg commit &#8211;date (mercurial)</title>
		<link>http://blog.littleimpact.de/index.php/2009/03/03/usage-of-hg-commit-date-mercurial/</link>
		<comments>http://blog.littleimpact.de/index.php/2009/03/03/usage-of-hg-commit-date-mercurial/#comments</comments>
		<pubDate>Tue, 03 Mar 2009 18:50:22 +0000</pubDate>
		<dc:creator>Henryk</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[GNU Linux]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://blog.littleimpact.de/index.php/2009/03/03/usage-of-hg-commit-date-mercurial/</guid>
		<description><![CDATA[Recently, I was trying to move some stuff from RCS to mercurial. There does not seem to exist a converter and since it was only a few revisions, I decided to do it by hand. The problem arose how to set the commit date manually and google yielded a nice blog post that answered my [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I was trying to move some stuff from <a href="http://www.cs.purdue.edu/homes/trinkle/RCS/">RCS</a> to <a href="http://www.selenic.com/mercurial/wiki/">mercurial</a>. There does not seem to exist a converter and since it was only a few revisions, I decided to do it by hand. The problem arose how to set the commit date manually and google yielded a nice <a href="http://linux.goeszen.com/mercurial-timestamp-on-commit-how-to-record-datecode-as-commit-date.html">blog post</a> that answered my question (refering to the formidable but less searchable <a href="http://hgbook.red-bean.com/hgbook.html">hgbook</a>).<br />
<span id="more-18"></span><br />
So its basically:</p>
<pre>
hg commit --date "1234567890 0"
</pre>
<p>where 1234567890 is the seconds since epoch and 0 is the timezone. Unfortunally I was unable to comment on the above blog posting, which triggered this posting.<br />
On unix (and bash) you can conveniently use the <tt>date</tt> command to do the conversion:</p>
<pre>
hg commit --date "$(date -u --date '2009-2-13 23:31:30' +'%s') 0"
</pre>
<p>The <tt>date</tt> command also solves the original posters question:</p>
<blockquote><p>
Actually, I regret that it isn’t possible to define a file that mercurial will use as date reference, something like hg commit -d date filexy.ext -m “commit with autodate from file xy” would be handy. This way, getting the filesystem metadata into a repository representation would be easier, but this might be a too specific request for a standard versioning system…
</p></blockquote>
<p>Just use:</p>
<pre>
hg commit -d "$(date -u -r filexy.ext +'%s') 0" -m “commit with autodate from file xy”
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.littleimpact.de/index.php/2009/03/03/usage-of-hg-commit-date-mercurial/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Makefiles for LaTeX</title>
		<link>http://blog.littleimpact.de/index.php/2009/02/24/makefiles-for-latex/</link>
		<comments>http://blog.littleimpact.de/index.php/2009/02/24/makefiles-for-latex/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 16:35:43 +0000</pubDate>
		<dc:creator>Henryk</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[GNU Linux]]></category>
		<category><![CDATA[LaTeX]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://blog.littleimpact.de/index.php/2009/02/24/makefiles-for-latex/</guid>
		<description><![CDATA[This entry was originally submitted to Debian Package of the day, but rejected because make is well known. Figure 1:The file In is used to produce InterM that is itself used to produce Out. Therefore Out depends directly on InterM and indirectly on In. I agree that most programmers and administrators know GNU make. Sadly, [...]]]></description>
			<content:encoded><![CDATA[<p>This entry was originally submitted to <a href="http://debaday.debian.net/">Debian Package of the day</a>, but rejected because <em>make</em> is well known.</p>
<div style="max-width:350px;" class="figure"><img src="/uploads/2009/02/figure1.png" alt="A directed Graph: In connects to InterM that connects to Out" /><br />
<b>Figure 1:</b>The file <code class="file">In</code> is used to produce <code class="file">InterM</code> that is itself<br />
used to produce <code class="file">Out</code>. Therefore <code class="file">Out</code> depends directly on <code class="file">InterM</code> and indirectly on <code class="file">In</code>.</div>
<p>I agree that most programmers and administrators know <a href="http://www.gnu.org/software/make/">GNU make</a>. Sadly, it is ignored by most others. GNU <code>make</code> solves a very common problem that everyone faces when processing more than one file with more than one programm. It keeps track which file has been changed and which files have to be regenerated.</p>
<p><span id="more-15"></span></p>
<p> Consider the abstract example of some output file <code class="file">Out</code> that is produced out of an intermediate file <code class="file">InterM</code> that itself is generated from some input file <code class="file">In</code> (see Figure 1). If <code class="file">In</code> is changed <code>make</code> will reproduce <code class="file">InterM</code> and finally <code class="file">Out</code>. But if you only tweak <code class="file">InterM</code> you don&#039;t want it to be overidden by the output of <code class="file">In</code>. <code>Make</code> will not do that unless <code class="file">In</code> is newer than <code class="file">InterM</code> (i.e. was changed after you tweaked with <code class="file">InterM</code>).
</p>
<p>We will take a short look at an example from the real-world of <a href="http://en.wikipedia.org/wiki/LaTeX">LaTeX</a>. LaTeX is a typesetting system that produces nicely typeset postscript-files or PDF-files out of files containing the text in a special markup language. Assume that your LaTeX file <code class="file">sample.tex</code> includes two postscript (ps) figures like Figure 1 and 2 (get the tarball of the example <a href="http://www.littleimpact.de/permanent/blog/2009/make-sample-tex.tgz">here</a>). These postscript files are generated from two description files by a software called <a href="http://www.graphviz.org/">graphviz</a>.</p>
<p>To compile <code class="file">sample.tex</code> you typically type</p>
<pre>
dot -Tps -o figure1.ps figure1.dot   # to produce Figure 1
dot -Tps -o figure2.ps figure2.dot   # to produce Figure 2
latex sample.tex                     # to compile using latex
dvips -o sample.ps sample.dvi        # to generate a postscript-file
</pre>
</p>
<p>While editing your document, you have to type the above over and over again. This is tedious and error-prone. You may easily forget to run <code>dot</code> after changing the figures or even forget what commands to use if you do not edit the text for a while. You may put the above in a shellscript, but then you have to add every figure to your shellscript and if you process a lot of figures it might take much longer than needed to compile your file, since all the figures are generated everytime you run your<br />
shellscript.</p>
<p> Make solves both of these problems. Figure 2 illustrates the dependencies of the files. The information which file depends on which and how to produce one from the other is stored in a so called <code class="file">Makefile</code>. For our case it might look like this:</p>
<pre>
FIGURES=figure1.ps figure2.ps

all: sample.ps                      # first rule

sample.dvi: sample.tex $(FIGURES)   # second rule
<img src="/uploads/2009/04/tab.png" alt="&lt;TAB&gt;" class="noborder"/> latex sample.tex

%.ps:%.dot                          # third rule
<img src="/uploads/2009/04/tab.png" alt="&lt;TAB&gt;" class="noborder"/> dot -Grankdir=LR -Tps -o $@ $&lt;

%.ps:%.dvi                          # fourth rule
<img src="/uploads/2009/04/tab.png" alt="&lt;TAB&gt;" class="noborder"> dvips -o $@ $&lt;
</pre>
<div style="max-width:620px;" class="figurenf"><img src="/uploads/2009/02/figure2.png" alt="The dependencies of sample.tex."><br/><br />
<b>Figure 2:</b>If <code>make</code> detects a change of a file (here the green <code class="file">figure1.dot</code>) it rebuilds all parents that depend on it (here all red nodes).</div>
<p>So what does this mean?</p>
<ul>
<li>The first line defines a variable <code>FIGURES</code>. If you want to include another figure in your build-process all you have to do is add it here.</li>
<li> The second paragraph is called a rule (we will refer to it as first rule). It requests <code>make</code> to produce the left output (here:all) out of the right input (here: sample.ps). For reasons that will become clear later, we do not tell <code>make</code> how to produce &#034;all&#034;. Everything behind a hash <code>#</code> is a comment.</li>
<li>In the second rule the output depends on <code class="file">sample.tex</code> and the figures. Note that the variable <code>FIGURES</code> has to be preceeded by a dollar sing and embraced by brackets.  To fullfill this rule <code>make</code> has to run <code>latex</code>. We tell it to do so by a line starting with a tab (here marked as &#034;<IMG src="/uploads/2009/04/tab.png" alt="&lt;TAB&gt;">&#034;; it is a very common beginners error to use spaces instead of tabs!). So whenever the dependencies are fullfilled but sample.dvi is not up to date, <code>make</code> will run <code>latex sample.tex</code>.</li>
<li>The third and fourth rule tell <code>make</code> how to produce a ps-file out of a dot-file or a dvi-file. The percentage sign <code>%</code> is a wildcard character (similar to <code>*</code> in the shell). The special variable <code>$@</code> contains the target of the rule (the filename, which matches the left side) while <code>$&lt;</code> contains the source or dependency of the rule (the right side).</li>
</ul>
<p>If you type <code>make</code>, the <code class="file">Makefile</code> in the current directory will be scanned. Without any further arguments <code>make</code> will try to build the target of the first rule in the <code class="file">Makefile</code> that is -in our case- <code>all</code>. The target <code>all</code> depends on <code class="file">sample.ps</code> that itself can be build from<br />
<code class="file">sample.dvi</code> by the last rule (<code>%.ps:%.dvi</code>).<br />
To build <code class="file">sample.dvi</code>, <code>make</code> needs to invoke the second rule, but first it must meet its dependencys: the figures. The third rule tells <code>make</code> how to produce the figures and the dependacy is met since the dot-files exist. Once the ps-files are produced, the dependencys of the second rule are fullfilled and <code>make</code> invokes <code>latex</code> to produce <code class="file">sample.dvi</code> that is then converted by the fourth rule to produce <code class="file">sample.ps</code>. Now <code>make</code> stops, since there is nothing to do for <code>all</code> (this is called a phony target). </p>
<p>If you run <code>make</code> again it will not do much but just say:</p>
<pre>
make: Nothing to be done for `all'.
</pre>
<p>Now change something in <code class="file">figure1.dot</code> and run <code>make</code> another time. This time <code>make</code> will rebuild  <code class="file">figure1.ps</code>, <code class="file">sample.dvi</code> and <code class="file">sample.ps</code> to incorporate your changes (see Figure 2).</p>
<h4>Target Users:</h4>
<p>Everyone who uses the command line to mangle several input files into some output files.</p>
<h4>Further reading:</h4>
<ul>
<li>The <a href="http://www.gnu.org/software/make/manual/">GNU Make Manual</a>.</li>
<li>There are <a href="http://www.google.com/search?q=make+tutorial">plenty of make-tutorials</a> on the internet        although very few focus on non-programmers.</li>
<li>An example of a sophisticated <a href="http://web.pdx.edu/~hegbloom/Aptitude/Makefile">Makefile for LaTeX</a>.</li>
<li><a href="http://www.tex.ac.uk/cgi-bin/texfaq2html?label=make">TeXFAQ about make</a></li>
</ul>
<h4>Other packages doing similar things:</h4>
<ul>
<li>
   <a href="http://www.di.unipi.it/~marcod/Tools/mktex.html">mktex</a> is a special tool that might be a handy replacement of <code>make</code> if you&#039;re only focused on LaTeX.
   </li>
<li>
   There exist <a href="http://www.linuxlinks.com/Software/Programming/Development/Tools/Make_Tools/">many other buildtools</a> avoiding some of <a href="http://freshmeat.net/articles/view/1702/">make&#039;s flaws</A>.
   </li>
</ul>
<p>You can find the most recent version of GNU make at <a href="ftp://ftp.gnu.org/gnu/make/">ftp://ftp.gnu.org/gnu/make/</a>.
</p>
<p>Make is available for Debian and Ubuntu (and any other Linux-distribution).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.littleimpact.de/index.php/2009/02/24/makefiles-for-latex/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Constantize in Python</title>
		<link>http://blog.littleimpact.de/index.php/2009/02/08/constantize-in-python/</link>
		<comments>http://blog.littleimpact.de/index.php/2009/02/08/constantize-in-python/#comments</comments>
		<pubDate>Sun, 08 Feb 2009 14:45:42 +0000</pubDate>
		<dc:creator>Henryk</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.littleimpact.de/index.php/2009/02/08/constantize-in-python/</guid>
		<description><![CDATA[Rails offers a nice function called constantize. It is easy to rebuild this (to some extend) in python. But the price is too high. I agree, it looks very sexy to write in rails: my_str = "MyClass" my_instance = my_str.constantize.new So how would you do this in python? We could just use the eval-function: import [...]]]></description>
			<content:encoded><![CDATA[<p><b>Rails offers a nice function called <a href="http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html#M001341"><code>constantize</code></a>. It is easy to rebuild this (to some extend) in python. But the price is too high.</b><br />
<span id="more-14"></span><br />
I agree, it looks very sexy to write in rails:</p>
<pre>my_str = "MyClass"
my_instance = my_str.constantize.new
</pre>
<p>So how would you do this in python? We could just use the <a href="http://docs.python.org/library/functions.html#eval"><code>eval</code></a>-function: </p>
<pre>import inspect, re

ClassRegex = re.compile("[a-zA-Z_][a-zA-Z0-9_]*")

class ConstantizeException(Exception):
  pass

def constantize(s):
  if not ClassRegex.match(s):
    raise ConstantizeException("`%s' contains illegal characters." % str(s))
  klass = eval(str(s))
  if not inspect.isclass(klass): raise ConstantizeException("`%s' does not refer to a class." % str(s))
  return klass
</pre>
<p>Compare it to the <a href="http://dev.rubyonrails.org/browser/trunk/activesupport/lib/active_support/inflector.rb">ruby implementation</a>:</p>
<pre>  def constantize(camel_cased_word)
    unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ camel_cased_word
      raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!"
    end

    Object.module_eval("::#{$1}", __FILE__, __LINE__)
  end
</pre>
<p>So let&#039;s try it:</p>
<pre>>>> class A:
...   def __repr__(self):
...     return "I'm A."
...
>>> klass=constantize("A")
>>> instance_of_a = klass()
>>> instance_of_a
I'm A.
</pre>
<p>Seems to work. The syntax is not as nice as in rails, since we can&#039;t just <a href="http://en.wikipedia.org/wiki/Monkey_patch">monkey patch</a> the string class.</p>
<h3>Security</h3>
<p>As noted in another post <a href="http://blog.littleimpact.de/index.php/2008/08/13/constantize-with-care/"> <code>constantize</code> is prone to code injections</a>. We have two protections built in. The regular expression makes sure that <code>eval</code> does not execute arbitrary code while the <a href="http://docs.python.org/library/inspect.html?highlight=isclass#inspect.isclass"><code>inspect.isclass</code></a> insures that only classes are constantized. Otherwise also functions could be returned:</p>
<pre>>>> def somefunc():
...   print "called somefunc"
...
>>> klass=constantize("somefunc")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in constantize
__main__.ConstantizeException: `somefunc' does not refer to a class.
</pre>
<p>It would be still reckless to use the above constantize on possibly malicious data. </p>
<p>You need to strongly limit the strings that your application may constantize. A straight forward solution would be:</p>
<pre>s = "MyClass"
if s in ["MyClass", "SomeOtherNiceClass"]: klass = constantize(s)
else: raise "Unexpected class `%s' " % s
</pre>
<h3>How should you do it?</h3>
<p>But then why don&#039;t you use some completely differrent method from the very begining? What about a dictionary?</p>
<pre>class A:
  def __repr__(self):
    return "I'm A."

class B:
  def __repr__(self):
    return "I'm B."

str2class = { "A": A, "B": B }
</pre>
<p>It is very easy to see which classes are allowed to be constantized and there is no room for security issues in your python code:</p>
<pre>>>> str2class = { "A":A, "B":B }
>>> s = "A"
>>> klass = str2class[s]
>>> a = klass()
>>> a
I'm A.
</pre>
<p>A nice side effect is the improved execution speed:</p>
<pre>>>>> import timeit
>>> t=timeit.Timer("""a=constantize("A")""","from __main__ import constantize")
>>> print t.timeit()
18.7163159847
>>>
>>> t=timeit.Timer("""a=str2class["A"]""","from __main__ import str2class")
>>> print t.timeit()
0.148332118988
</pre>
<p>If you are lazy you can use the following function to fill your dictionary:</p>
<pre>def build_str2class(lst):
  d = {}
  for klass in lst:
    d[klass.__name__]=klass
  return d

str2class = build_str2class([A,B])
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.littleimpact.de/index.php/2009/02/08/constantize-in-python/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Automatic encryption of home directories using TrueCrypt 6.0a</title>
		<link>http://blog.littleimpact.de/index.php/2008/08/19/automatic-encryption-of-home-directories-using-truecrypt-60a/</link>
		<comments>http://blog.littleimpact.de/index.php/2008/08/19/automatic-encryption-of-home-directories-using-truecrypt-60a/#comments</comments>
		<pubDate>Tue, 19 Aug 2008 15:45:24 +0000</pubDate>
		<dc:creator>Henryk</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[GNU Linux]]></category>
		<category><![CDATA[truecrypt]]></category>

		<guid isPermaLink="false">http://blog.littleimpact.de/index.php/2008/08/19/automatic-encryption-of-home-directories-using-truecrypt-60a/</guid>
		<description><![CDATA[This post describes how to encrypt the home directory of your users on GNU Linux with the help of TrueCrypt and PAM using the login-password as encryption key. I wrote about Automatic encryption of home directories using TrueCrypt before. This time we&#039;ll use TrueCrypt 6.0a which is a bit different from 4.3a used last time. [...]]]></description>
			<content:encoded><![CDATA[<p><b>This post describes how to encrypt the home directory of your users on GNU Linux with the help of <a href="http://www.truecrypt.org/">TrueCrypt</a> and <a href="http://www.kernel.org/pub/linux/libs/pam/">PAM</a> using the login-password as encryption key.<br />
I wrote about <a href='http://blog.littleimpact.de/index.php/2008/07/12/automatic-encryption-of-home-directories-using-truecrypt/'>Automatic encryption of home directories using TrueCrypt</a> before. This time we&#039;ll use TrueCrypt 6.0a which is a bit different from 4.3a used last time. Futhermore we&#039;ll use <a href='https://wiki.ubuntu.com/HardyHeron'>Ubuntu 8.04 Hardy Heron</a> instead of Debian Etch. For convenience this post will be selfcontained (ie. I copy redundant parts from the old one).</b><br />
<span id="more-13"></span></p>
<p><b>Update</b>: There is a more current version of this post dealing with TrueCrypt 6.2 and Ubuntu 9.04:<a href='http://blog.littleimpact.de/index.php/2009/09/14/automatic-encryption-of-home-directories-using-truecrypt-62-and-pam_exec/'>Automatic encryption of home directories using TrueCrypt 6.2 and pam_exec</a>.</p>
<p>Using the method described below is no silver bullet and has some issues:</p>
<ul>
<li>Your user passwords may be weak.</li>
<li>If your computer gets stolen while turned on, the passwort may be easier to recover than you might think (see <a href="http://citp.princeton.edu/memory/">here</a>).</li>
<li>Changing the password requires to log in as root.</li>
<li>Some programs (e.g. qmail) rely on an accessible home directory.</li>
<li>The home may stay mounted after logout until the next reboot.</li>
</ul>
<h3>Prequisites</h3>
<ul>
<li>GNU Linux (<a href='https://wiki.ubuntu.com/HardyHeron'>Ubuntu 8.04 Hardy Heron</a>)</li>
<li><a href="http://www.truecrypt.org/">TrueCrypt</a> (I used  6.0a)</li>
<li>pam_mount.so (for Ubuntu install the package libpam-mount)</li>
</ul>
<h3>Setup</h3>
<p>We will create one file for each user to hold his encrypted home directory. To keep them we create a directory:</p>
<pre>mkdir /home/private</pre>
<p>For each user we have to create an encrypted file in /home/private. We start with the user bart (if you leave out the <code>--text</code> you&#039;ll get a graphical user interface).</p>
<pre>root@mybox:~# truecrypt --create /home/private/bart.tc
Volume type:
1) Normal
2) Hidden
Select [1]: 1

Enter volume size (bytes - size/sizeK/sizeM/sizeG): 1G

Encryption algorithm:
 1) AES
 2) Serpent
 3) Twofish
 4) AES-Twofish
 5) AES-Twofish-Serpent
 6) Serpent-AES
 7) Serpent-Twofish-AES
 8 ) Twofish-Serpent
Select [1]: 1

Hash algorithm:
 1) RIPEMD-160
 2) SHA-512
 3) Whirlpool
Select [1]: 1

Filesystem:
 1) FAT
 2) None
Select [1]: 2

Enter password: *************
WARNING: Short passwords are easy to crack using brute force techniques!

We recommend choosing a password consisting of more than 20 characters. Are you sure you want to use a short password? (y=Yes/n=No) [No]: y

Re-enter password:*************

Enter keyfile path [none]:

Please type at least 320 randomly chosen characters and then press Enter:
dsglregmm;adsf;dsafdsasasadfdsafdsagfdsadsafdsafdsafadsfdsahfarweqasddsaglfdsakg;lrewqk;lggkqqqqqewrgsadgdsag....

Done: 100.000%  Speed: 18.0 MB/s  Left: 0 s

The TrueCrypt volume has been successfully created.
</pre>
<p>Then we assign the same password as the login password to bart:</p>
<pre>root@mybox:~# passwd bart
Enter new UNIX password:
Retype new UNIX password:
</pre>
<p>Next, we need to format the encrypted partition and move the old home directory into it:</p>
<pre>
root@mybox:~# truecrypt --text --filesystem=none /home/private/bart.tc
Enter password for /home/hgerlach/newcrypt.tc: *************
Enter keyfile [none]:
Protect hidden volume? (y=Yes/n=No) [No]:

root@mybox:~#  truecrypt --text -l
1: /home/private/bart.tc /dev/mapper/truecrypt1 -

root@mybox:~# mkfs.ext2 /dev/mapper/truecrypt1
root@mybox:~# mount /dev/mapper/truecrypt1 /mnt/
root@mybox:~# shopt -s dotglob #make dotfiles visible
root@mybox:~# mv /home/bart/* /mnt/
root@mybox:~# chown bart.users /mnt/
root@mybox:~# umount /mnt
root@mybox:~# truecrypt -d /dev/mapper/truecrypt1
</pre>
<p>Now we have to configure mount_pam.<br />
In  &#039;/etc/security/pam_mount.conf.xml&#039; edit the line<br />
<code>&lt;truecryptmount&gt;truecrypt %(VOLUME) %(MNTPT)&lt;/truecryptmount&gt;</code><br />
into<br />
<code>&lt;truecryptmount&gt;truecrypt-nl --text --protect-hidden=no --keyfiles=""  %(VOLUME) %(MNTPT)&lt;/truecryptmount&gt;</code><br />
and add the line:<br />
<code>&lt;volume fstype="truecrypt" path="/home/private/%(USER).tc" mountpoint="/home/%(USER)/" /&gt;</code><br />
Note that we use <code>truecrypt-nl</code> instead of  <code>truecrypt</code>. This is a shellscript, that we have to put into &#039;/usr/bin/&#039;:</p>
<pre>#!/bin/sh
# This is /usr/bin/truecrpyt-nl; append a newline to the password.
(cat; echo)| truecrypt $*
</pre>
<p>It is a workaround for some bug in either libpam-mount (version 0.32-4) or truecrypt. Libpam-mount sends the password to truecypt without newline. Then truecrypt does not recognize the password. The script above just inserts a newline after the password and makes things work fine.</p>
<p>To the file  &#039;/etc/pam.d/common-auth&#039; we add the line:<br />
<code>auth    optional        pam_mount.so try_first_pass</code><br />
so it looks like</p>
<pre># /etc/pam.d/common-auth
auth    requisite       pam_unix.so nullok_secure
auth    optional        pam_smbpass.so migrate missingok
auth    optional        pam_mount.so try_first_pass</pre>
<p>and to  &#039;/etc/pam.d/common-session&#039; we add the line<br />
<code>session optional        pam_mount.so</code><br />
so it looks like</p>
<pre>
# /etc/pam.d/common-session
session required        pam_unix.so
session optional        pam_mount.so
</pre>
<p>Now bart can login and use the encrypted home.</p>
<h3>Bibliography</h3>
<ul>
<li>Homepage of <a href="http://pam-mount.sourceforge.net/">pam_mount</a></li>
<li>A good <a href="http://www.linux-magazin.de/layout/set/print/content/view/full/5108">description of pam</a> (in german)</li>
<li>A similar howto for <a href="http://gentoo-wiki.com/HOWTO_Encrypt_Your_Home_Directory_Using_LUKS_and_pam_mount">LUKS and Gentoo<br />
</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.littleimpact.de/index.php/2008/08/19/automatic-encryption-of-home-directories-using-truecrypt-60a/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Constantize with Care</title>
		<link>http://blog.littleimpact.de/index.php/2008/08/13/constantize-with-care/</link>
		<comments>http://blog.littleimpact.de/index.php/2008/08/13/constantize-with-care/#comments</comments>
		<pubDate>Wed, 13 Aug 2008 15:10:39 +0000</pubDate>
		<dc:creator>Henryk</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://blog.littleimpact.de/index.php/2008/08/13/constantize-with-care/</guid>
		<description><![CDATA[The String#constantize method is a feature that makes rails fun to code with. This method converts a string to the constant that the string contains (or throws a NameError if there is no such constant). It makes it easy to store class-types in databases as strings and to code controllers that work with classes of [...]]]></description>
			<content:encoded><![CDATA[<p><b>The <code>String#constantize</code> method is a feature that makes rails fun to code with. This method converts a string to the constant that the string contains (or throws a <code>NameError</code> if there is no such constant). It makes it easy to store class-types in databases as strings and to code controllers that work with classes of the same <a href='http://en.wikipedia.org/wiki/Duck_typing'>duck type</a>.<br />
Most people know that <code>eval</code> on user data is dangerous, but noboddy seems to care about <code>constantize</code>. Beware, it is also dangerous and you should constantize with care!</b><br />
<span id="more-9"></span></p>
<p>If you want to turn a string into the corresponding class, you could just use  <a href='http://www.ruby-doc.org/core/classes/Kernel.html#M005948'><code>eval</code></a>:</p>
<pre>
  irb(main):001:0> s="Float"
  => "Float"
  irb(main):002:0> klass= eval(s)
  => Float
</pre>
<p>But <a href='http://www.ruby-forum.com/topic/96222'>everybody knows that this is dangerous</a> since you can embed arbitrary ruby-code into the string which might do nasty things to your system. Rails defines the <a href='http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html#M000488'><code>String#constantize</code></a> method which is less dangerous. But it is not save by any means. Consider the following controller:</p>
<pre>
  def vulnerable_basic_data_new
     klass=params[:class]
     obj=klass.constantize.new(params[:form])
     #...
  end
</pre>
<p>The <code>class</code> parameter is supposed to be Guest, User or  Admin. The posted form is supposed to contain a hash of data that initializes the common attributes of them. Using routes we could call <code>http://myapp/vulnerable_basic_data_new/User/</code>. That&#039;s nice. A <a href='http://www.google.com/search?q=params+constantize'>google search</a> reveals that <a href='http://svn.colivre.coop.br/svn/abelo/trunk/app/controllers/system_actors_controller.rb'>quite</a> <a href='http://www.developerunderground.com/content/view/16/50'>a lot</a> <a href='http://www.crudvision.com/2007/07/25/whats-better-than-crud/'>of people</a> <a href='http://hobocentral.net/forum/viewtopic.php?=&#038;p=5063'>write</a> <a href='http://www.pluitsolutions.com/2007/03/'>code</a> <a href='http://www.theartofrails.com/hello-world/'>like</a> <a href='http://www.pathf.com/blogs/2008/07/drying-up-rails-controllers-polymorphic-and-super-controllers/'>above</a>.</p>
<p>http://www.theartofrails.com/hello-world/</p>
<p>But wait! What happens if we open <code>http://myapp/vulnerable_basic_data_new/AnyClass/?form=somestring</code>? Then the application will execute <code>AnyClass.new "somestring"</code> (if AnyClass exists). We just injected a class into the application that the programmer didn&#039;t expect. A lazy programmer might argue that an attacker cannot control the method that is called, just the class. It is true, that the usual methods <code>new</code> and <code>find</code> don&#039;t sound too dangerous. But what if we called <code>create</code>? And don&#039;t forget that we can call any class that is installed on the system. Thanks to rails autoloading capabilities. So if you accidently installed MiniMagick which happens to have <a href='http://rubyforge.org/tracker/index.php?func=detail&#038;aid=21514&#038;group_id=1358&#038;atid=5365'>security issue</a> right now in version 1.2.3, we can exploit it:<br />
<code>http://myapp/vulnerable_basic_data_new/MiniMagic::Image/?form=-%20%7C%20xclock</code>.</p>
<p>This will execute <code>MiniMagic::Image.new("- | xclock")</code> which will launch a nice xclock on your server. We could have done worse&#8230;. Ooooops!</p>
<p>So we should constantize with care. For example, we could use the following method:</p>
<pre>
class String
  def constantize_with_care(list_of_klasses=[])
    list_of_klasses.each do |klass|
      return self.constantize if self == klass.to_s
    end
    raise "I'm not allowed to constantize #{self}!"
  end
end
</pre>
<p>And rewrite above controller code to:</p>
<pre>
  def vulnerable_basic_data_new
     klass=params[:class]
     obj=klass.constantize_with_care([Guest,User,Admin]).new(params[:form])
     #...
  end
</pre>
<p>There is a even more sopphisticated <a href='http://www.littleimpact.de/hg/constantize_with_care/'>constantize_with_care plugin</a> that you can <a href='http://www.littleimpact.de/hg/constantize_with_care/archive/tip.zip'>download</a> to use in your own projects.</p>
<p>P.S. In the above google search, I found a single person (Michael Schuerig)  warning that using constantize carelessly is dangerous and a single <a href='http://trac.streamlinedframework.org/changeset/837?format=diff&#038;new=837'>project</a> that tries to protect against class injection. Their <code>safe_to_instantiate?</code> makes me think about checking for class relationships in <code>constantize_with_care</code> too.</p>
<p><b>Update:</b><br />
I have to apologize to <a href='http://www.crudvision.com/2007/07/25/whats-better-than-crud/'>Lisa Seelye</a>. She constantizes <code>params[:controller]</code> which should be sanitized by the routing to contain only very few, save possibilites. At least as long as she does not create a <code>MiniMagickController</code>.</p>
<p><b>Update:</b> I also have some notes on <a href="http://blog.littleimpact.de/index.php/2009/02/08/constantize-in-python/"><code>Constantize</code> in Python</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.littleimpact.de/index.php/2008/08/13/constantize-with-care/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

