<?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>Full of BS &#187; Tutorials</title>
	<atom:link href="http://fullof.bs/category/tutorials/feed/" rel="self" type="application/rss+xml" />
	<link>http://fullof.bs</link>
	<description>He just never stops talking</description>
	<lastBuildDate>Thu, 15 Dec 2011 20:00:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>A Better Erlang TCP listening pattern: addressing the fast packet loss problem</title>
		<link>http://fullof.bs/a-better-erlang-tcp-listening-pattern-addressingthe-fast-packet-loss-problem/</link>
		<comments>http://fullof.bs/a-better-erlang-tcp-listening-pattern-addressingthe-fast-packet-loss-problem/#comments</comments>
		<pubDate>Thu, 01 Jan 2009 03:04:59 +0000</pubDate>
		<dc:creator>John Haugeland</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tools and Libraries]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[accept]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[defect]]></category>
		<category><![CDATA[erlang server]]></category>
		<category><![CDATA[fast packet loss problem]]></category>
		<category><![CDATA[fast packet problem]]></category>
		<category><![CDATA[gen_tcp]]></category>
		<category><![CDATA[idiom]]></category>
		<category><![CDATA[idiomatic]]></category>
		<category><![CDATA[listen]]></category>
		<category><![CDATA[listen loop]]></category>
		<category><![CDATA[listener]]></category>
		<category><![CDATA[listener loop]]></category>
		<category><![CDATA[listener pattern]]></category>
		<category><![CDATA[network server]]></category>
		<category><![CDATA[pattern]]></category>
		<category><![CDATA[scutil]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[server listen]]></category>
		<category><![CDATA[server listener]]></category>
		<category><![CDATA[tcp server]]></category>

		<guid isPermaLink="false">http://fullof.bs/?p=466</guid>
		<description><![CDATA[[digg-reddit-me]I&#8217;ve had mixed reactions to this when I&#8217;ve discussed it with people on IRC.  This may be well known to oldbear Erlang programmers.  I suppose it&#8217;s also possible that I&#8217;m wrong, though I&#8217;ve talked to several people I respect, and more than one of them have suggested that they were already aware of this problem.  [...]]]></description>
			<content:encoded><![CDATA[<p>[digg-reddit-me]I&#8217;ve had mixed reactions to this when I&#8217;ve discussed it with people on IRC.  This may be well known to oldbear Erlang programmers.  I suppose it&#8217;s also possible that I&#8217;m wrong, though I&#8217;ve talked to several people I respect, and more than one of them have suggested that they were already aware of this problem.  If I&#8217;m wrong, please let me know; I&#8217;m open to the possibility that there&#8217;s a better answer that I just don&#8217;t know about.  <span style="text-decoration: line-through">I&#8217;ve never seen it discussed on the web, at least.</span> <span style="color: #ff9900">Update: Serge Aleynikov points out that</span> <a title="TCP Server, OTP Principles" href="http://trapexit.org/Building_a_Non-blocking_TCP_server_using_OTP_principles" target="_blank">this TrapExit tutorial</a> <span style="color: #ff9900">documents this approach.</span></p>
<p>I think this is probably real.</p>
<p>I believe there is a significant defect in the idiomatic listener pattern as discussed by most Erlang websites and as provided by most Erlang example code, and which is found in many Erlang applications.  This defect is relatively easily repaired once noticed without significant impact on surrounding code, and I have added functionality to my <a title="The ScUtil Library" href="http://scutil.com/" target="_blank">ScUtil Library</a> to handle this automatically under the name <tt><a title="standard_listener documentation" href="http://scutil.com/docs/#standard_listener-3" target="_blank">standard_listener</a></tt>.</p>
<p>The fundamental problem is essentially a form of race condition.  The idiomatic listener is, roughly:</p>
<blockquote>
<pre><span style="color: #008000"><strong>do_listen(Port, Opts, Handler) -&gt;

    case gen_tcp:listen(Port, Opts) of

        { ok, ListeningSocket } -&gt;
            listen_loop(ListeningSocket, Handler);

        { error, E } -&gt;
            { error, E }

    end.

listen_loop(ListeningSocket, Handler) -&gt;

    case gen_tcp:accept(ListeningSocket) of

        { ok, ConnectedSocket } -&gt;
            spawn(node(), Handler, [ConnectedSocket]),
            listen_loop(ListeningSocket);

        { error, E } -&gt;
            { error, E }

    end.
</strong></span></pre>
</blockquote>
<p>Now consider the case of a server under very heavy load.  Further, consider that the listening socket is opened either <span style="color: #008000"><tt>{active,true}</tt></span> or <span style="color: #008000"><tt>{active,once}</tt></span>, which is true in the vast bulk of Erlang network applications, meaning that packets are delivered automatically to the socket owner.  The general pattern is that the listening socket accepts a connection, spawns a handling process, passes the connected socket to that handling process, and the handling process takes ownership of the socket.</p>
<p>The problem is that it takes time for that all to happen, and Erlang doesn&#8217;t specify or allow you to control its timeslicing behavior (as well it should not).  As active sockets are managed by a standalone process, this means that if the connecting client is fast and the network is fast, the first packet (even the first several under extreme circumstances) could be delivered before the socket has been taken over by the handling PID, meaning that its contents would be dispatched to the wrong process, with no indication of where they were meant to go.  This invalidates connections and fills a non-discarding mailbox, which is a potentially serious memory leak (especially given that erlang&#8217;s response to out of memory conditions is to abort an entire VM.)</p>
<p>Obviously, this is intolerable.  There are better answers, though, than to switch to <span style="color: #008000"><tt>{active,false}</tt></span>.  One suggestion I heard was to pre-spawn handlers in order to reduce the gap time, but that doesn&#8217;t solve the problem, it just makes it less likely.</p>
<p>The approach that I took is to lie.  <span style="color: #008000"><tt>standard_listener </tt></span>takes the following steps to resolve the problem:</p>
<ol>
<li>Add the default <span style="color: #008000"><tt>{active,true}</tt></span> to the inet options list, if it isn&#8217;t already present.</li>
<li>Strip out the <span style="color: #008000"><tt>{active,Foo}</tt></span> from the inet options list, and store it as <span style="color: #008000"><tt>ActiveStatus</tt></span>.</li>
<li>Add <span style="color: #008000"><tt>{active,false}</tt></span> to the inet options list, and use that options list to open the listener.</li>
<li>When spawning handler processes, pass a shunt as the starting function, taking the real handling function and the real <span style="color: #008000"><tt>ActiveStatus</tt></span> as arguments</li>
<li>The shunt sets the real <span style="color: #008000"><tt>ActiveStatus</tt></span> from inside the handler process, at which point the socket begins delivering messages</li>
</ol>
<p>This neatly closes the problem.  A free, MIT license implementation can be found in <a title="The ScUtil Library" href="http://scutil.com/" target="_blank">ScUtil</a> beginning in version 96.  A simplified, corrected example follows for immediate reference; the thing in ScUtil is more feature complete.</p>
<blockquote>
<pre><span><strong><span style="color: #008000"><strong>do_listen(Port, Opts) -&gt;

    ActiveStatus = case proplists:get_value(active, SocketOptions) of
        undefined -&gt; true;
        Other     -&gt; Other
    end,

    FixedOpts = proplists:delete(active, SocketOptions)
             ++ [{active, false}],

    case gen_tcp:listen(Port, FixedOpts) of

        { ok, ListeningSocket } -&gt;
            listen_loop(ActiveStatus, ListeningSocket);

        { error, E } -&gt;
            { error, E }

    end.

listen_loop(</strong></span></strong></span><span><strong><span><strong><span><strong><span style="color: #008000"><strong>ActiveStatus, </strong></span></strong></span></strong></span></strong></span><span><strong><span style="color: #008000"><strong>ListeningSocket, Handler) -&gt;

    case gen_tcp:accept(ListeningSocket) of

        { ok, ConnectedSocket } -&gt;
            spawn(?MODULE, shunt, [ActiveStatus,ConnectedSocket,</strong></span></strong></span><span><strong><span><strong><span><strong><span style="color: #008000"><strong>Handler</strong></span></strong></span></strong></span></strong></span><span><strong><span style="color: #008000"><strong>]),
            listen_loop(</strong></span></strong></span><span><strong><span><strong><span><strong><span style="color: #008000"><strong>ActiveStatus, </strong></span></strong></span></strong></span></strong></span><span><strong><span style="color: #008000"><strong>ListeningSocket, Handler</strong></span></strong></span><span><strong><span style="color: #008000"><strong>);

        { error, E } -&gt;
            { error, E }

    end.

shunt(ActiveStatus, ConnectedSocket, Handler) -&gt;

</strong></span></strong></span><span><strong><span style="color: #008000"><strong>    controlling_process(ConnectedSocket, self()),
    inet:setopts(ConnectedSocket, [{active, ActiveStatus}]),
    Handler(ConnectedSocket).</strong></span></strong></span></pre>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://fullof.bs/a-better-erlang-tcp-listening-pattern-addressingthe-fast-packet-loss-problem/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Moments, Skewness and Kurtosis (Statistics in Erlang part 8)</title>
		<link>http://fullof.bs/moments-skewness-and-kurtosis-statistics-in-erlang-part-8/</link>
		<comments>http://fullof.bs/moments-skewness-and-kurtosis-statistics-in-erlang-part-8/#comments</comments>
		<pubDate>Thu, 28 Aug 2008 02:43:28 +0000</pubDate>
		<dc:creator>John Haugeland</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Math]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Statistics]]></category>
		<category><![CDATA[Tools and Libraries]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[central moment]]></category>
		<category><![CDATA[kurtosis]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[moment]]></category>
		<category><![CDATA[skewness]]></category>
		<category><![CDATA[stats]]></category>

		<guid isPermaLink="false">http://fullof.bs/?p=365</guid>
		<description><![CDATA[[digg-reddit-me]So, it was pointed out to me that I had the central moments, but not the moments &#8211; ie, the ones not normalized against the input&#8217;s average.  Also, it was pointed out that most people don&#8217;t know that kurtosis and skewness are related to the central moments.  Furthermore, it turns out (and I didn&#8217;t know [...]]]></description>
			<content:encoded><![CDATA[<p>[digg-reddit-me]So, it was pointed out to me that I had the central moments, but not the moments &#8211; ie, the ones not normalized against the input&#8217;s average.  Also, it was pointed out that most people don&#8217;t know that kurtosis and skewness are related to the central moments.  Furthermore, it turns out (and I didn&#8217;t know this) that there are in fact meaningful uses of floating-point exponents in moments.</p>
<p>So, I implemented moments, I replaced my central moments implementation, and I gave name wrappers for skewness and kurtosis to make them easier to identify.</p>
<p>This closes issues <a title="Crunchy Development issue 132, Skewness" href="http://crunchyd.com/forum/project.php?issueid=169" target="_blank">169</a>, <a title="Crunchy Development issue 170, Kurtosis" href="http://crunchyd.com/forum/project.php?issueid=170" target="_blank">170</a>, <a title="Crunchy Development issue 171, Moments" href="http://crunchyd.com/forum/project.php?issueid=171" target="_blank">171</a>, <a title="Crunchy Development issue 172, Real valued moments" href="http://crunchyd.com/forum/project.php?issueid=172" target="_blank">172</a> and <a title="Crunchy Development issue 173, Real valued central moments" href="http://crunchyd.com/forum/project.php?issueid=173" target="_blank">173</a>.  As usual, this code is part of <a title="The ScUtil Library" href="http://scutil.com/" target="_blank">the ScUtil library</a>, which is free and MIT licensed, because the GPL is evil.</p>
<pre style="padding-left: 30px">moment(List, N) when is_list(List), is_number(N) -&gt;
    scutil:arithmetic_mean( [ pow(Item, N) || Item &lt;- List ] ).

moments(List) -&gt;
    moments(List, [2,3,4]).

moments(List, Moments) when is_list(Moments) -&gt;
    [ moment(List, M) || M &lt;- Moments ].

central_moment(List, N) when is_list(List), is_number(N) -&gt;
    ListAMean = scutil:arithmetic_mean(List),
    scutil:arithmetic_mean( [ pow(Item-ListAMean, N) || Item &lt;- List ] ).

central_moments(List) -&gt;
    central_moments(List, [2,3,4]).

central_moments(List, Moments) when is_list(Moments) -&gt;
    [ central_moment(List, M) || M &lt;- Moments ].

skewness(List) -&gt; central_moment(List, 3).
kurtosis(List) -&gt; central_moment(List, 4).</pre>
]]></content:encoded>
			<wfw:commentRss>http://fullof.bs/moments-skewness-and-kurtosis-statistics-in-erlang-part-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>As long as I&#8217;m posting random crap, how about eJabberD Install Docs</title>
		<link>http://fullof.bs/setting-up-ejabberd-from-scratch/</link>
		<comments>http://fullof.bs/setting-up-ejabberd-from-scratch/#comments</comments>
		<pubDate>Thu, 29 May 2008 02:15:28 +0000</pubDate>
		<dc:creator>John Haugeland</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Tools and Libraries]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[ejabberd]]></category>
		<category><![CDATA[jabber]]></category>
		<category><![CDATA[key]]></category>
		<category><![CDATA[openssl]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://blog.sc.tri-bit.com/?p=220</guid>
		<description><![CDATA[I had to write these for a colleague some months ago, and promptly forgot in classic fashion. Here&#8217;s something to mock my inability to write coherent install docs for posterity: Setting Up eJabberD From Scratch. A how to, of sorts, I guess. This was written for a Centos server, but is probably accurate for most [...]]]></description>
			<content:encoded><![CDATA[<p>I had to write these for a colleague some months ago, and promptly forgot in classic fashion.  Here&#8217;s something to mock my inability to write coherent install docs for posterity: <span style="text-decoration: underline"><strong>Setting Up eJabberD From Scratch</strong></span>.  A how to, of sorts, I guess.  This was written for a Centos server, but is probably accurate for most Unices (don&#8217;t really know for sure.)  <span id="more-200"></span></p>
<h1>Setting up eJabberD from scratch</h1>
<p>eJabberD is an erlang Jabber server written for high performance and long term stability.  It&#8217;s also pretty easy to set up. eJabberD has a number of serious advantages over other Jabber servers, important among       which is the ability to cluster servers, so that if one server goes       down, the service itself continues running.  Areas highlighted in red are areas where you&#8217;re expected to provide your       own values. I provided the values I used in setting up the codeboner        jabber server for comparison, but you can do as you see fit.  Please don&#8217;t       cut and paste several lines at once, even from series of instructions,        as some of the utility calls made (especially the OpenSSL stuff) ask       for user input (what&#8217;s the company&#8217;s domain, what&#8217;s the owner&#8217;s name, etc,       nothing particularly complex).  Please be careful to use the same number of days for expiration dates (the       365s), and be sure that the domain&#8217;s A and REV records are character for       character identical to what you use in the SSL certificate, or it will        appear to fail for no apparent reason.  If you&#8217;ve followed these instructions       and the thing just won&#8217;t let you connect, the SSL certificate may be the       cause.  These instructions are written assuming a single Unix server environment       and a requirement for TLS (ssl3) top to bottom, using yum, GCC, the       OpenSSL library and a self-signed certificate.  Because of dependencies,       it&#8217;s important that installation proceed in a specific order.  The steps,       in order, are as follows:</p>
<dl>
<dt>Install standard toolchain</dt>
<dd>yum install gcc gcc-g++ automake autoconf screen libtool which coreutils libstdc++ libgcc bind authconfig sudo tar zlib zlib-devel</dd>
<dt>Install OpenSSL ecology</dt>
<dd>yum install openssl openssl-clients openssl-server openssl-devel</dd>
<dt>Install Expat ecology</dt>
<dd>yum install expat expat-devel</dd>
<dt>Install Erlang r11b5</dt>
<dd>mkdir /erl-inst cd /erl-inst wget http://erlang.org/download/otp_src_R11B-5.tar.gz  mkdir /usr/local/erlang mkdir /usr/local/erlang/otp_r11b cd /usr/local/erlang/otp_r11b  gunzip -c /erl-inst/otp_src_R11B-5.tar.gz | tar xfp &#8211; cd otp_src_R11B-5 ./configure make make install  rm /erl-inst/otp_src_R11B-5.tar.gz rmdir /erl-inst/ </dd>
<dt>Create a self-signed PEM (or buy one)</dt>
<dd>openssl genrsa -des3 -out <span class="changeable">ca</span>.key 4096 openssl req -new -x509 -days <span class="changeable">365</span> -key <span class="changeable">ca</span>.key -out <span class="changeable">ca</span>.crt openssl genrsa -des3 -out <span class="changeable">server</span>.key 4096 openssl req -new -key <span class="changeable">server</span>.key -out <span class="changeable">server</span>.csr openssl x509 -req -days <span class="changeable">365</span> -in <span class="changeable">server</span>.csr -CA <span class="changeable">ca</span>.crt -CAkey <span class="changeable">ca</span>.key -set_serial <span class="changeable">01</span> -out <span class="changeable">server</span>.crt openssl rsa -in <span class="changeable">server</span>.key -out <span class="changeable">server</span>.key.stripped chmod 600 <span class="changeable">server</span>.key.stripped cat <span class="changeable">server</span>.crt <span class="changeable">server</span>.key <span class="changeable">ca</span>.crt &gt;<span class="changeable">server</span>.pem</dd>
<dt>Add erlang to your path</dt>
<dd>Varies per shell; in BASH, this is in .bash_profile or .bashrc; add :FOOPATH (not ;FOOPATH like dos) to the end of what&#8217;s there. Erlang is probably in /usr/local/bin/, but you can find it by: updatedb locate erlc</dd>
<dt>Install eJabberD</dt>
<dd>(make and change to some temporary installation directory) wget http://www.process-one.net/downloads/ejabberd/1.1.4/ejabberd-1.1.4.tar.gz tar -xvf ejabberd-1.1.4.tar.gz cd ejabberd-1.1.4/src ./configure make sudo make install</dd>
<dt>Configure eJabberD</dt>
<dd>nano -w /etc/ejabberd/ejabberd.cfg</dd>
<dt>In eJabberD.cfg line 89, set hosts to be served</dt>
<dd>{hosts, [<span class="changeable">"codeboner.com"</span>]}.</dd>
<dt>In eJabberD.cfg line 116, uncomment the {certfile} directive, and set the path to your self-signed PEM</dt>
<dd>{certfile, <span class="changeable">&#8220;codebonerssl/cbjk.pem&#8221;</span>}, starttls,</dd>
<dt>If you want to forbid non-TLS connections, in eJabberD.cfg line 116, change starttls to starttls_required</dt>
<dd>{certfile, &#8220;codebonerssl/cbjk.pem&#8221;}, <span class="changeable">starttls_required</span>,</dd>
<dt>In eJabberD.cfg line 152, make sure the HTTP administration interface is enabled</dt>
<dd>web_admin</dd>
<dt>In eJabberD.cfg line 311, annote one user as an administrator (so they can use the HTTP interface)</dt>
<dd>{acl, admin, {user, <span class="changeable">&#8220;john&#8221;</span>, <span class="changeable">&#8220;codeboner.com&#8221;</span>}}.</dd>
<dt>Start eJabberD</dt>
<dd>erl -pa /var/lib/ejabberd/ebin -name ejabberd -s ejabberd -ejabberd config \&#8221;/etc/ejabberd/ejabberd.cfg\&#8221;</dd>
<dt>Add users to eJabberD (REMEMBER TO ADD THE ADMIN USER FROM ABOVE)</dt>
<dd>ejabberdctl &#8211;node ejabberd@localhost register <span class="changeable">john codeboner.com 123changeMe</span></dd>
<dt>Set up system preferences such as user groups</dt>
<dd>Admin control panel is at http://yourserver.com:5280/admin/ Your username is <span class="changeable">john@codeboner.com</span></dd>
</dl>
<p>You should now be able to connect to Jabber on the port at the beginning of the c2s rule (5222 unless you changed it.)</p>
]]></content:encoded>
			<wfw:commentRss>http://fullof.bs/setting-up-ejabberd-from-scratch/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Should I be writing about Erlang?</title>
		<link>http://fullof.bs/should-i-be-writing-about-erlang/</link>
		<comments>http://fullof.bs/should-i-be-writing-about-erlang/#comments</comments>
		<pubDate>Thu, 01 Feb 2007 07:21:33 +0000</pubDate>
		<dc:creator>John Haugeland</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://blog.sc.tri-bit.com/archives/201</guid>
		<description><![CDATA[I&#8217;m becoming ever more convinced that the answer is yes. I&#8217;ve been playing, a bit, a game called Project Euler, a game for programmers wherein the object is to find solutions to deceptively simple problems. It&#8217;s surprisingly entertaining, and your score is a result of the function of programmers which have not succeeded in a [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m becoming ever more convinced that the answer is yes.  I&#8217;ve been playing, a bit, a game called <a href="http://projecteuler.net/" title="Project Euler">Project Euler</a>, a game for programmers wherein the object is to find solutions to deceptively simple problems.  It&#8217;s surprisingly entertaining, and your score is a result of the function of programmers which have not succeeded in a task.</p>
<p>There are people who take long roundabout approaches to get to <a href="http://montsamu.blogspot.com/2007/01/erlang-fizzbuzzery-project-euler.html" title="One approach">results like these</a>, when instead they could be doing things like</p>
<blockquote><p><tt>p1() -&gt; lists:sum(</tt></p>
<p><tt>&nbsp; &nbsp; [ X || X &lt;- lists:seq(1,10), </tt></p>
<p><tt>&nbsp; &nbsp; &nbsp; ((X rem 3) == 0) orelse ((X rem 5) == 0) ]</tt></p>
<p><tt>).</tt></p></blockquote>
<p>As a result, I&#8217;m starting to think that I need to start explaining things.  Anyone agree or disagree?</p>
]]></content:encoded>
			<wfw:commentRss>http://fullof.bs/should-i-be-writing-about-erlang/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Stone PHP SafeCrypt: Convenient, Secure and Typesafe Encryption (Tutorial, Library and Test Code)</title>
		<link>http://fullof.bs/stone-php-safecrypt-convenient-secure-and-typesafe-encryption-tutorial-library-and-test-code/</link>
		<comments>http://fullof.bs/stone-php-safecrypt-convenient-secure-and-typesafe-encryption-tutorial-library-and-test-code/#comments</comments>
		<pubDate>Sun, 10 Sep 2006 02:47:56 +0000</pubDate>
		<dc:creator>John Haugeland</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tools and Libraries]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://blog.sc.tri-bit.com/archives/101</guid>
		<description><![CDATA[When wandering around Das Intarweb one sees a lot of sad, sad code. In fact, people who should know better get busted on weak crypto all the time. Indeed, even the PHP manual examples have unacceptable security flaws. When one is writing encryption code for one&#8217;s own site, that turns into a problem. Here&#8217;s a [...]]]></description>
			<content:encoded><![CDATA[<p>When wandering around Das Intarweb one sees a lot of sad, sad code.  In fact, <a title="Yes, that Don of Dons" href="http://dsc.discovery.com/news/briefs/20060417/mafiaboss_tec.html?source=rss">people who should know better</a> get busted on weak crypto all the time.   Indeed, even the PHP manual examples have unacceptable security flaws. When one is writing encryption code for one&#8217;s own site, that turns into a problem.  Here&#8217;s a library to wrap and a little primer on using the standard encryption facilities in PHP safely and correctly.</p>
<p><span id="more-160"></span></p>
<p>See, there are a lot of subtle attacks one can bring to bear on even sound cryptological systems, if one doesn&#8217;t know what one is doing.  PHP does a pretty neat job of wrapping up these issues behind a <a title="Mcrypt encryption library" href="http://php.net/mcrypt">semi-generic library interface</a>, but it doesn&#8217;t do such a great job in the manual of detailing safe usage.  In particular, some of the user notes give conflicting, and frequently outright bad, advice; furthermore, the displayed methods for using the interface aren&#8217;t themselves particularly generic, and skip some particularly useful things they could do.  It also doesn&#8217;t help that there&#8217;s a distinct trend of more-than-one-way-itis in libmcrypt, including a lot of support for deprecated functionality.</p>
<p>So, what to do about it, but write a new tute?  Actually, this one&#8217;s pretty low-impact; might as well just release it almost as straight source. Still, it&#8217;s helpful to explain.</p>
<h1>The Quick Version</h1>
<p>It&#8217;s surprisingly simple.</p>
<p>If you just want to throw the library in and start working, follow <a href="http://sc.tri-bit.com/outgoing/StonePhpSafeCrypt.zip">this download link</a>, then throw the file in with the rest of your PHP project.  Change the define <strong>DEFAULT_MD5_SALT</strong> on line 36 of StonePhpSafeCrypt_config.php (the library will force you to do this) and fill it with some random string.  Really doesn&#8217;t matter, and you&#8217;ll never need to remember it; it&#8217;s just a &#8220;salt,&#8221; which is used to prevent dictionary attacks.  Don&#8217;t use a phrase someone can guess, and consider just mashing your hands all over the keyboard for a second instead of trying to make up something smart.</p>
<p>Next, <strong>require_once()</strong> the library, then use <strong>PackCrypt(<em>$data, $key</em> </strong><span style="font-size: 80%;color: #557799"><strong><em>[, $options]</em></strong></span><strong> )</strong> and <strong>UnpackCrypt(<em>$data, $ke</em></strong><strong><em>y </em></strong><span style="font-size: 80%;color: #557799"><strong><em>[, $options] </em></strong></span><strong>)</strong> on any serializable PHP datatype.  $key does not need to be secure, except against social engineering attacks like guessing according to the user&#8217;s behavior; it is hardened by the library, and salted by you.</p>
<p>As options, you may pass in an array containing up to four things as key/value pairs:</p>
<ul>
<li>&#8216;<tt><u>cipher</u></tt>&#8216;, which may take any value from the <a href="http://www.php.net/manual/en/ref.mcrypt.php">mcrypt cipher module list</a>, and which defaults to twofish</li>
<li>&#8216;<tt><u>mode</u></tt>&#8216;, which may take any <a href="http://www.php.net/manual/en/function.mcrypt-list-modes.php">cipher block type</a>, and which defaults to CBC</li>
<li>&#8216;<tt><u>compressor</u></tt>&#8216;, which may take any compressor listed in StonePhpSafeCrypt_compressors.php, and which defaults to off (the package comes with gzip, gzip deflate and bzip2 defined, but you may add others)</li>
<li>&#8216;<u><tt>salt</tt></u>&#8216;, which allows you to override the default salt with a salt of your own choice.</li>
</ul>
<p>All four of these options are reflexive: if you use them during encryption, you must use them identically during decryption, or the process will not allow you to unpack the data.  All functions other than PackCrypt() and UnpackCrypt() in the library are for internal support, and should not be used directly.</p>
<p>Here&#8217;s a minimalist example, to show you what you&#8217;re doing:</p>
<blockquote><p><tt><strong>require_once('StonePhpSafeCrypt.php');</strong></tt></p>
<p><tt><strong>$sourcedata = array('Hello', 1, 2, 3=&gt;4, 'Goodbye');<br />
$packed     = PackCrypt($sourcedata, 'Password');<br />
</strong></tt></p>
<p><tt><strong>if ($packed['state'] === false) { die('Error: ' . $packed['reason']); }<br />
</strong></tt></p>
<p><tt><strong>echo 'Packed: ', $packed['output'], '&lt;br /&gt;';<br />
</strong></tt></p>
<p><tt><strong>$unpacked = UnpackCrypt($packed, 'Password');<br />
echo 'Unpacked: ', print_r($unpacked);<br />
</strong></tt></p></blockquote>
<p>And that&#8217;s all there is to it.  <img src='http://fullof.bs/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<h1>The Fundamentals</h1>
<p>The first thing we need is a way to wrap the encryption and decryption process, without actually forcing a choice of which method is used.  This is important because some machines may not have some algorithms available, because algorithms get broken and replaced, and so on.  The user really needs to be able to select the algorithm.  Even so, the actual process of encryption is fairly ridiculously cumbersome, and can be wrapped.</p>
<p>That said, there&#8217;s a lot to PHP.  One thing that&#8217;s really nice about PHP is its automatic data munging.  Of particular utility is the concept of serialization; objects even have a magic stub they can provide to implement serialization magically.  It can be argued that a high quality wrapper for encryption should magically handle the packing and unpacking of a PHP data type, be it a scalar, an array or even a correctly made object.  Serialize is the appropriate means by which to do so, and so we&#8217;ll build that into our encryptor.</p>
<p>Another important thing for an encryption wrapper is that the user shouldn&#8217;t actually need to know a whole lot to use it safely.  The actual data to be packed and the password by which to do so are sort of common-sense minimums; ideally, a function should be flexible enough to allow more customization, but should require nothing more than these and still be safe.  Importantly, this function <em><strong>must not</strong></em> require the user to know how to make safe passwords.  We will do that for them.  In order to keep that mindset, we will begin referring to two passwords: the user&#8217;s password, which we&#8217;ll call the Weak Key, and the password we derive therefrom, called the Strong Key.  Only the strong key is reliable, or used in any way in the transmitted cipher.  (Weak keys are still subject to social engineering attacks, so end users should still be advised of rules they refuse to follow, but this at least protects the data stream itself.)</p>
<p>To that end, we will create two basic functions: PackCrypt() and UnpackCrypt().  These functions will take two mandatory and two optional arguments each: the data, the weak password, and if the user wants to, they may also override the default choice of encryption algorithms (which is something best reserved for those who are familiar with the advantages and disadvantages of the various algorithms.)</p>
<h2>The workhorses: PackCrypt() and UnpackCrypt()</h2>
<p>PackCrypt and UnpackCrypt are the two functions you actually use in this library.</p>
<h3>PackCrypt(&amp;$Data, &amp;$WeakKey, $options)</h3>
<p>PackCrypt takes any serializable data structure for $Data, any string for $WeakKey, and if you like, some extra commands in $options. $Data can be a nested array full of objects, all sorts of creepy stuff, whatever.  If it&#8217;s a correct and complete PHP class which follows the rules for <a href="http://www.php.net/serialize">serialize()</a>, then it should be safe for PackCrypt().</p>
<p>It&#8217;s really just that simple. Make some horribly complex data structure, and do</p>
<blockquote><p><tt>$packed = PackCrypt($someData, 'my key sucks');</tt></p></blockquote>
<p>and then look at $packed['output'].  Bang: safe, clean serialized secure encryption.</p>
<h3>Why $packed['output']?  Why not just $packed?</h3>
<p>This library (like most of John&#8217;s libraries) returns a state tuple for its operations.  This is a behavior that&#8217;s common in some languages, particularly Erlang/OTP, and which PHP can support quite easily.  It&#8217;s also a very important and powerful technique: it makes concurrent message tracking very easy, it makes keeping track of parallel error states very easy, and it makes complex returns with ancillary information not only possible but quite natural.</p>
<p>PackCrypt returns an array with ['status'], ['reason'] and ['output'] set.  Status is a boolean which represents whether things proceeded correctly.  Reason is a textual description which explains what error set status to <strong>false</strong> when something broke; if status is <strong>true</strong>, which is to say if things went well, it just says &#8220;Successfully encrypted.&#8221; or whatever is appropriate.  Output contains the actual results, or <strong>false</strong> if something failed.</p>
<ul>
<li>If everything goes correctly,</li>
<ul>
<li>['status'] will be <strong>true</strong>,</li>
<li>['output'] will contain your encrypted result, and</li>
<li>['reason'] will say &#8216;Successful Pack&#8217;.</li>
</ul>
<li>If there is a problem,</li>
<ul>
<li>['status'] will be <strong>false</strong>,</li>
<li>['output'] will be <strong>false</strong>, and</li>
<li>['reason'] will contain a message explaining the problem, which will most likely be that the encryption algorithm chosen or the compressor chosen is unavailable on this system</li>
</ul>
</ul>
<h3>Okay, so how does it work</h3>
<p>It&#8217;s fairly straightforward.  First, the functions unpack and apply the options, check for the existance of the requested compressor and so on.  Once that&#8217;s done, the compressor opens the cipher module (such as Blowfish, RSA, Rijndael, TripleDES and so on,) engages the appropriate block cipher mode (cbc, cfb, ecb or ofb,) creates a salted MD5 hash of the weak key, generates a randomized initialization vector, ciphers the IV with a resalted strong key, serializes the incoming data, compresses the serialized data if requested, encrypts the serialized data, writes out the result array and cleans up.  Unsurprisingly, the unpacking scheme is basically the same thing in reverse.<br />
The thing is, you have to know all the steps in order, and you have to do them correctly, accomodating for the different sizes in each algorithm and platform implementation, trim extra space and so on.  So, wrap &#8216;em up, no problem, done.  Welcome to PackCrypt() territory.</p>
<h2>Safe IV Transfer: BlockScramble() and BlockDescramble()</h2>
<p>The PHP manual incorrectly states that the initialization vector for an encrypted datastream may be transmitted plaintext.  This would be highly convenient and provides a desirable mechanism for transfer, but can be the source of man-in-the-middle attacks in CBC block mode algorithms, as well as several other situations.  See <a href="http://www.ciphersbyritter.com/GLOSSARY.HTM#IV">Ciphers by Ritter</a> for a detailed explanation of the problem.  This library solves the problem by salted hashing the weak key and then reversibly merging that with the IV, so that the leading block can be transmitted safely as a stream prefix.</p>
<p>The functions which perform this salting, hashing and merging are called BlockScramble() and BlockDescramble().</p>
<h2>Convenient compression: $options['compressor']</h2>
<p>Of course, one thing that&#8217;s really helpful to have in this kind of routine is inline compression.  Compression both makes the original stream harder to detect and (obviously) reduces bandwidth and storage costs.  However, the way to apply compression to the encryption stream is inobvious; most people would just try compressing the results of the encryption, and that&#8217;s not going to work.  The reason is that compression and encryption are at ends: compression relies on patterns in data, whereas the purpose of encryption is to hide patterns in data.  A well encrypted string when compressed is generally larger than uncompressed.</p>
<p>As such, to keep things simple, I put compression directly into the mechanism, in a way that can be extended to new compression algorithms later (though I have a hard time imagining needing to replace BZip2.)  However, if you want to add support for the latest greatest algorithm, even if it&#8217;s newer than my library, well, no problem.  Open StonePhpSafeCrypt_compressors.php and add your compressor to the list.  Instructions are in the file, but it&#8217;s really quite trivial.</p>
<h2>Subdirectories and require_once()</h2>
<p>Because of the way PHP inclusion works, the require directives in a given script are referential to the including script&#8217;s location, rather than their own.  That means that the includes for the various parts of this library need to be referenced according to their own directory.  If you just dump all the files in the same directory as your main project, well great, works fine.  If you want to put them in a subdirectory, do the following <strong><u>before</u></strong> you include the library (or it will fail in a fairly unreadable way):</p>
<blockquote><p><tt>define('STONE_PHP_SAFE_CRYPT_HOST_DIRECTORY', 'dirgoeshere/');</tt></p></blockquote>
<p>The directory may be absolute or referential, should be in Unix directory format, and needs the trailing slash.</p>
<h1>That&#8217;s it?</h1>
<p>That&#8217;s it.  Unpack the files, set the salt, <tt>$foo = PackCrypt(data, key, options);</tt> and look in $foo['output'].  Safe, convenient and reliable.  This is what it should have been all along.</p>
<p>In case you missed it earlier, <a href="http://sc.tri-bit.com/outgoing/StonePhpSafeCrypt.zip">get the source here</a>.  There is a working example in test.php, but here&#8217;s that same fairly minimalist example again, now that you know what it&#8217;s doing:</p>
<blockquote><p><tt><strong>require_once('StonePhpSafeCrypt.php');</strong></tt></p>
<p><tt><strong>$sourcedata = array('Hello', 1, 2, 3=&gt;4, 'Goodbye');<br />
$packed     = PackCrypt($sourcedata, 'Password');<br />
</strong></tt></p>
<p><tt><strong>if ($packed['state'] === false) { die('Error: ' . $packed['reason']); }<br />
</strong></tt></p>
<p><tt><strong>echo 'Packed: ', $packed['output'], '&lt;br /&gt;';<br />
</strong></tt></p>
<p><tt><strong>$unpacked = UnpackCrypt($packed, 'Password');<br />
echo 'Unpacked: ', print_r($unpacked);<br />
</strong></tt></p></blockquote>
<p>And that&#8217;s all there is to it.  <img src='http://fullof.bs/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://fullof.bs/stone-php-safecrypt-convenient-secure-and-typesafe-encryption-tutorial-library-and-test-code/feed/</wfw:commentRss>
		<slash:comments>44</slash:comments>
		</item>
		<item>
		<title>Checklist for Embedded IE</title>
		<link>http://fullof.bs/checklist-for-embedded-ie/</link>
		<comments>http://fullof.bs/checklist-for-embedded-ie/#comments</comments>
		<pubDate>Thu, 24 Aug 2006 02:13:56 +0000</pubDate>
		<dc:creator>John Haugeland</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[ECMA / Javascript]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tools and Libraries]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web and Web Standards]]></category>

		<guid isPermaLink="false">http://blog.sc.tri-bit.com/archives/163</guid>
		<description><![CDATA[MSHTML is an awesome user interface tool, but it has a whole lot of standard behaviors, many of which aren&#8217;t what one wants for an application (since it&#8217;s designed for the web.) This is a list of stuff you need to do to embed IE COM and have it behave like a normal application. There&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>MSHTML is an awesome user interface tool, but it has a whole lot of standard behaviors, many of which aren&#8217;t what one wants for an application (since it&#8217;s designed for the web.)  This is a list of stuff you need to do to embed IE COM and have it behave like a normal application.  There&#8217;s more than a person might expect.</p>
<p><span id="more-153"></span></p>
<ul>
<li>Suppress the user interface.  IE starts with most of its interface turned off, but a few things aren&#8217;t.  Notable things to include are to suppress the context menu and keyboard navigation.</li>
<ul>
<li>There are several ways to suppress the context menu.  The easiest way is to do it in the html.  Add <u>oncontextmenu=&#8221;return false;&#8221;</u> to your &lt;body&gt; and the problem just goes away, and it&#8217;s easily manually overridden for specific elements later.</li>
<li>Alternately, you can override the interface programmatically through <a title="IDocHostUIHandler Interface" href="http://msdn.microsoft.com/workshop/browser/hosting/reference/ifaces/idochostuihandler/idochostuihandler.asp">IDocHostUIHandler</a>.</li>
</ul>
<li>Get rid of the OnNavigate noise (the clicking sound when you hit a link.)  <a title="Suppressing OnNavigate" href="http://blog.sc.tri-bit.com/archives/162">This is harder than it should be</a>.</li>
<li>Prevent keyboard navigation.  If you only ever navigate once, and then do everything else in DHTML, this isn&#8217;t an issue, because there&#8217;s nothing to go forward or back to.  However, if you need to, the way to do this is to capture <a title="BeforeNavigate2" href="http://windowssdk.msdn.microsoft.com/en-us/library/ms628868.aspx">DWebBrowserEvents2::BeforeNavigate2()</a> and fill its last parameter, VARIANT_BOOL*&amp; Cancel, to true.  For security reasons this can&#8217;t be done in HTML without a garish ugly dialog box confirmation.</li>
<li>Prevent dragging and dropping links.  Do this with BeforeNavigate2() just like keyboard navigation.</li>
<li>Prevent selection.  The easiest way to do that is in the HTML by adding <u>onselectstart=&#8221;return false;&#8221;</u> to the &lt;body&gt;, which is also easily overridden for child elements where appropriate.  If you need it programmatically, such as a block which can be turned from and to editability, that&#8217;s in IDocHostUIHandler.</li>
<li>Handle some keys directly.  Particularly often, control keys, tab and f-keys need very different interpretations in applications than are the defaults in IE.  Some keys can be reliably intercepted in JScript, but not all of them.  For lightweight stuff, use JScript; it&#8217;ll be less painful.  However, if you need real control, you need to provide an <a title="Handle keypresses" href="http://msdn.microsoft.com/workshop/browser/hosting/reference/ifaces/idochostuihandler/translateaccelerator.asp">IDocHostUIHandler::TranslateAccelerator()</a> implementation.</li>
<li>Suppress the interior border.  People are often surprised that they turn off the window border in IE, and yet it seems to still appear.  That&#8217;s because IE&#8217;s default stylesheet puts an inset bevel on every web page.  Turn that off in CSS by writing <u>body { border: 0; }</u>.</li>
<li>Begin to embed your images and other support media as resources, and access them with <a title="The res protocol" href="http://msdn.microsoft.com/workshop/networking/predefined/res.asp">the res:// protocol</a>.</li>
<ul>
<li>One ugly caveat: I have never found any variation of the DirectX PNG alpha filter hack which works with res://, and I&#8217;ve looked often and at some very weird variations.  It is my current belief that a PNG cannot be embedded through res:// and still be fixed for alpha.  This leads to the unfortunate case of requiring at least part of your resources on disk.  If anyone knows a way around this, a heads-up would be <em>greatly</em> appreciated.</li>
</ul>
<li>Set up a system to exchange messages between IE DOM/DHTML/JScript and your application.  There are a bujillion ways to do this, but I tend to use a combination of intercepted element events (mostly OnClick in <a title="NO U INVOKE" href="http://msdn.microsoft.com/workshop/browser/webbrowser/reference/ifaces/dwebbrowserevents/dwebbrowserevents.asp">WebBrowserEvents Invoke</a>,) DOM extension behaviors that allow me to call C++ directly from JScript through <a title="The missing link" href="http://msdn.microsoft.com/workshop/browser/hosting/reference/ifaces/idochostuihandler/getexternal.asp">IDocHostUIHandler::GetExternal()</a>, and executing scripts directly on the DOM object through <a title="Do what I say, DOM" href="http://msdn.microsoft.com/workshop/browser/mshtml/reference/ifaces/window2/execscript.asp">IHTMLWindow2::execScript()</a>.</li>
<li>Build everything in the to be inside a container; make the body itself <u>overflow: none</u>.  This prevents several ugly re-layout quirks which we&#8217;re used to on the web but not in applications, when content gets long.</li>
<ul>
<li>Start the container invisible, and make the black.  That way, during the lag while resources are being loaded, you have a reasonable appearance.  Black flashes look correct.  White flashes look broken.</li>
<li>Set an <u>onload=&#8221;HandleLoad();&#8221;</u> function for the &lt;body&gt;.  That way, you know when all resources are loaded, and thus when it&#8217;s safe to take the invisible clause off of the main container.</li>
<li>Set the main container <u>position:relative</u>, to make absolute positioning of contained elements easier.</li>
</ul>
<li>Build your web page in as a resource, and load it through <a title="How to load a document without about:blank and its white flash." href="http://msdn.microsoft.com/workshop/browser/mshtml/reference/ifaces/document2/write.asp">IHtmlDocument2::write()</a>.  This allows you to load a document at runtime without using about:blank (which most people use, but which causes a brief white flash before your application loads; very unprofessional looking.)  You&#8217;ll need <a title="SafeArrayAccessData" href="http://windowssdk.msdn.microsoft.com/en-us/library/ms221620.aspx">SafeArrayAccessData()</a> and <a title="SafeArrayUnaccessData" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/html/61b482cb-f0a3-4efb-9a68-f373f241e89a.asp">SafeArrayUnaccessData()</a> to use write() safely.  When it comes time to skin or internationalize, and when you&#8217;re dealing with a compile cycle which is just linking, you&#8217;ll thank me for this.</li>
<li>Suppress dragging on links and buttons.  If you don&#8217;t, people will be able to drag them outside the app and onto the desktop as shortcuts, and when followed those shortcuts will lead into your HTML page from the outside (which is, surprisingly, legal.)</li>
<li>Consider compressing your executable, such as with <a title="Universal Packer for Executables" href="http://upx.sourceforge.net/">UPX</a>, which makes resources unreadable externally.</li>
<li>Set an id on your &lt;body&gt;.  The is considered the origin of most events which don&#8217;t have a clear origin, and that means that catching these events is a lot easier (catching by id is the most straightforward way to sort out sources.)</li>
<li>Resist the urge to use runtime styles.  They&#8217;re not worth the problems they cause.</li>
</ul>
<p>That should get the new IE user through some common foibles.  I&#8217;ve probably missed stuff; if you can think of something, lemme know.  I do not currently know of a way to embed flash, unfortunately, without leaving available an extra file.</p>
]]></content:encoded>
			<wfw:commentRss>http://fullof.bs/checklist-for-embedded-ie/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Oh, Neat: A Hack To Fix The IE Click Problem</title>
		<link>http://fullof.bs/oh-neat-a-hack-to-fix-the-ie-click-problem/</link>
		<comments>http://fullof.bs/oh-neat-a-hack-to-fix-the-ie-click-problem/#comments</comments>
		<pubDate>Thu, 24 Aug 2006 01:08:44 +0000</pubDate>
		<dc:creator>John Haugeland</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://blog.sc.tri-bit.com/archives/162</guid>
		<description><![CDATA[I always wondered how applications suppressed that god-awful clicking sound in embedded IE. Usually you catch them screwing with user preferences, but there&#8217;s a utility I have which never showed any apparent method of getting rid of the goddamned noise. I always assumed they just styled text to look like a link. Well, I still [...]]]></description>
			<content:encoded><![CDATA[<p>I always wondered how applications suppressed that god-awful clicking sound in embedded IE.  Usually you catch them screwing with user preferences, but there&#8217;s a utility I have which never showed any apparent method of getting rid of the goddamned noise.  I always assumed they just styled text to look like a link.</p>
<p>Well, I still don&#8217;t know what he does, but I found a way.</p>
<p><span id="more-152"></span></p>
<p>Back in post #141, <a title="More IE Woes - This Time, from the Inside" href="http://blog.sc.tri-bit.com/archives/141">More IE Woes</a>, I documented several problems.  One was that <a title="LIES!  DIRTY LIES!" href="http://support.microsoft.com/default.aspx?scid=kb;en-us;201901">MSDN claims this noise cannot be suppressed</a>.  Indeed, by design, IE6 refuses to allow you to suppress that sound (god knows why.)  That MSDN article goes as far as to tell you to <em>override the user&#8217;s sound preferences to turn the noise off</em>.  How badbear is that?  Anyway, IE7 <strong>finally </strong>has an interface to turn that off, called <a title="It's about freaking time" href="http://msdn.microsoft.com/workshop/security/szone/overview/sec_featurecontrols.asp">FEATURE_DISABLE_NAVIGATION_SOUNDS</a>.  However, people like me who are reluctant to make their applications non-functional without IE7 will not like that answer.</p>
<p>It turns out there&#8217;s a better way.</p>
<p>There&#8217;s a moderately obscure interface from IE5 for IDocHostUIHandler called <a title="Pay attention, padamon." href="http://msdn.microsoft.com/workshop/browser/hosting/wbcustomization.asp#GetOptionKeyPath">GetOptionKeyPath</a>.  The superficial purpose of this is to allow the IE embedder to create a fake user, so that they can set defaults for IE like the basic font size, background color and so on.  This is generally completely ignored in favor of some CSS, but it turns out that this thing actually covers the sound effect scheme too.</p>
<p>All you need to do is use GetOptionKeyPath, create a fake user, override the OnNavigate sound (and maybe some others) to nothing, and let the rest alone, to default to the user&#8217;s preferences.</p>
<p>Bang: no more clicky noise, and no overriding preferences, breaking other applications and risking corrupting preferences on crash.</p>
<p>Very clean.  <img src='http://fullof.bs/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://fullof.bs/oh-neat-a-hack-to-fix-the-ie-click-problem/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

