<?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>BuzaMoto &#187; Programming</title>
	<atom:link href="http://blog.buzamoto.com/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.buzamoto.com</link>
	<description>Life as a BuzaMoto Employee</description>
	<lastBuildDate>Tue, 03 Aug 2010 20:54:23 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>PhotoViewer with CSS Transition Goodies</title>
		<link>http://blog.buzamoto.com/2010/04/14/photoviewer/</link>
		<comments>http://blog.buzamoto.com/2010/04/14/photoviewer/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 23:46:24 +0000</pubDate>
		<dc:creator>mud</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[iPad]]></category>

		<guid isPermaLink="false">http://blog.buzamoto.com/?p=215</guid>
		<description><![CDATA[
I wanted to play with the new CSS transition stuff, to see what all the fuss was about. At the same time I wanted to make something useful, so I thought why not make a little site for my friend Dave, who is one bad ass photographer. I have a rough demo up and it [...]]]></description>
			<content:encoded><![CDATA[<p><object width="400" height="300"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=10946270&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=10946270&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object></p>
<p>I wanted to play with the new CSS transition stuff, to see what all the fuss was about. At the same time I wanted to make something useful, so I thought why not make a little site for my friend Dave, who is one bad ass photographer. I have a rough demo up and it works pretty well. It only works with Safari 4, but the good news is that it also works with Mobile Safari.</p>
<p>It&#8217;s really nice that the animation is defined in the CSS and you don&#8217;t need any JavaScript to move objects. It was also really simple to implement, most of the work was done in about an hour. The interaction is simple. Click a picture to zoom into it, then a full version loads, click on it and you zoom back out. You can also move the thumbnails around.</p>
<p>I had to violate some ui for the iPad because of the way mobile safari handles events, or more precisely, doesn&#8217;t handle events. I wanted to maintain the native gestures of but weirdly enough safari does fire any events when double tapping to zoom in, as stated in their documentation. Why?</p>
<p>I decided implementing my own photo uploading/managing would be too much of a pain in the ass, after all Dave isn&#8217;t paying me for this. Yes, this may come as a shock, but I&#8217;m not a total asshole. So I decided to use Flickr as a CMS. Since the API allows for a JavaScript callback, there&#8217;s no backend proxy work required.</p>
<p>Anyway, here&#8217;s a little taste of how it works. You need Safari 4 or iPhone OS 3. Currently, there are three different ways to load photos.</p>
<p>1) Load from a JSON file</p>
<p>Loading a JSON file, don&#8217;t pass any query terms: <a href="http://mud.mitplw.com/PhotoViewer/">http://mud.mitplw.com/PhotoViewer/</a></p>
<p>The actual JSON file is: <a href="http://mud.mitplw.com/PhotoViewer/index.json"> http://mud.mitplw.com/PhotoViewer/index.json</a></p>
<p>2) Load Photosets from a Flickr user</p>
<p>Pass a photoset=flickr_user_id query, like this (using <a href="http://black.mitplw.com/">Luis&#8217;s</a> <a href="http://www.flickr.com/photos/blackaller/">Flickr account</a>)</p>
<p><a href="http://mud.mitplw.com/PhotoViewer/?photoset=75903973@N00">http://mud.mitplw.com/PhotoViewer/?photoset=75903973@N00</a></p>
<p>HINT: you can look up user_ids with <a href="http://idgettr.com/">idGettr</a>.</p>
<p>3) Load Photos from Flickr using tag search</p>
<p>Pass any comma delimited tags like ?drunk,punks</p>
<p><a href="http://mud.mitplw.com/PhotoViewer/?drunk,punks">http://mud.mitplw.com/PhotoViewer/?drunk,punks</a></p>
<p>Finally, I&#8217;ll post the source on github when I finally finish Dave&#8217;s site. Also, maybe in the near future I&#8217;ll add some local storage and HTML5 video support&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.buzamoto.com/2010/04/14/photoviewer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Private Members and Prototype</title>
		<link>http://blog.buzamoto.com/2010/03/20/private-members-and-prototype/</link>
		<comments>http://blog.buzamoto.com/2010/03/20/private-members-and-prototype/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 02:26:40 +0000</pubDate>
		<dc:creator>mud</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.buzamoto.com/?p=207</guid>
		<description><![CDATA[When writing JavaScript, most people don&#8217;t think about member access. Every member in an object is essentially a public variable. This is because there isn&#8217;t support for declaring variable modifiers (ie. public, protected, private) in the language. For most simple developments, this shouldn&#8217;t be a problem, and I never really thought too hard about it. [...]]]></description>
			<content:encoded><![CDATA[<p>When writing JavaScript, most people don&#8217;t think about member access. Every member in an object is essentially a public variable. This is because there isn&#8217;t support for declaring variable modifiers (ie. public, protected, private) in the language. For most simple developments, this shouldn&#8217;t be a problem, and I never really thought too hard about it. But now that I&#8217;m knee deep in a big JavaScript project (and interesting new JS projects popping up like <a href="http://nodejs.org">node.js</a>) putting more consideration into encapsulation is a good idea.</p>
<p>According to <a href="http://crockford.com">Douglas Crockford</a> it&#8217;s possible to create <a href="http://javascript.crockford.com/private.html">private variables</a> and methods, and privileged methods (public methods with access to private variables and methods). Crockford&#8217;s article also gives us some patterns to follow which we can easily follow.</p>
<p>I was curious to see how this might look like in my preferred JS framework, <a href="http://prototypejs.org">Prototype.js</a>. It didn&#8217;t take long before I concluded that you can&#8217;t use private variables with Class.create().</p>
<p>Here&#8217;s a rather useless class:</p>
<pre>
var AssetRequest = Class.create({
  initialize: function(_id, _url) {
    this.id      = _id;
    this.url     = _url;
    this.loaded  = false;
    this.content = null;
    this.request = null;
  },
  load: function() {
    if (!this.loaded) {
      this.request = new Ajax.Request(this.url, {
        onSuccess: function(transport) {
          this.loaded = true;
          this.content = transport.responseText;
          Event.fire(document, 'assetrequest:loaded', this);
        },
        onFailure: function() {
          Event.fire(document, 'assetrequest:failed', this);
        }
      });
    }
  }
});
</pre>
<p>The idea here is that you will create an AssetRequest object for an asset, say a JSON file. As you can imagine, all the members are editable. You can do something really dumb like this:</p>
<pre>
var request = new AssetRequest('req1', '/assets/asset-1.js');
request.loaded = true;
if (request.loaded) {
  alert(request.id + ' is loaded');
}
</pre>
<p>If you count on request.loaded to tell you if an asset has been loaded, it&#8217;s not reliable. So obviously we want to make this a private variable set it&#8217;s value internally, and create a privileged method that will provide access to its value. But you&#8217;ll see that this is actually not possible if we construct AssetRequest with Prototype&#8217;s Class.create.</p>
<p>It&#8217;s tempting to write:</p>
<pre>
var AssetRequest = Class.create((function() {
  var id,
      url,
      loaded  = false,
      content = null,
      request = null;

  return {
    initialize: function(_id, _url) {
      id  = _id;
      url = _url;
    },
    load: function() {
      if (!loaded) {
        request = new Ajax.Request(url, {
          onSuccess: function(transport) {
            loaded = true;
            content = transport.responseText;
            Event.fire(document, 'assetrequest:loaded', this);
          },
          onFailure: function() {
            Event.fire(document, 'assetrequest:failed', this);
          }
        });
      }
    },
    getURL:   function() { return url; },
    isLoaded: function() { return loaded; }
  }
})());
</pre>
<p>If you try this out, you&#8217;ll soon realize something is wrong:</p>
<pre>
var req = new AbstractRequest('1', '/request1');
alert(req.getURL());
//-> '/request'
var req2 = new AbstractRequest('2', '/request2');
alert(req2.getURL());
//-> '/request2'
alert(req.getURL());
//-> '/request2' ... this isn't good!
</pre>
<p>It seems the &#8220;private&#8221; variables that are created are not instance variables, instead they are &#8220;static&#8221; variables. I then thought the only way to create private variables would be defining the variables and all private/privileged methods inside the initialize method. But that&#8217;s where I gave up since that would be just so dirty looking.</p>
<p>I decided to not use Class.create and instead create my own constructor, just like the Crock style. So now our example will look like:</p>
<pre>
var AssetRequest = function(_id, _url) {
  var that    = this,
      id      = _id,
      url     = _url,
      loaded  = false,
      content = null,
      request = null;

  this.load = function() {
    if (!loaded) {
      request = new Ajax.Request(url, {
        onSuccess: function(transport) {
          loaded = true;
          content = transport.responseText;
          Event.fire(document, 'assetrequest:loaded', that);
        },
        onFailure: function() {
          Event.fire(document, 'assetrequest:failed', that);
        }
      });
    }
  };
  this.getURL   = function() { return url; };
  this.isLoaded = function() { return loaded; };
};
</pre>
<p>The problem now is that this new class can&#8217;t be extended as if it were created with Class.create. For now I only use this method for classes that don&#8217;t need to be subclassed, but hopefully in the near future, there will be an update to Prototype that will allow private variables!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.buzamoto.com/2010/03/20/private-members-and-prototype/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MudTyper 2.0</title>
		<link>http://blog.buzamoto.com/2010/01/10/mudtyper-2-0/</link>
		<comments>http://blog.buzamoto.com/2010/01/10/mudtyper-2-0/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 21:21:40 +0000</pubDate>
		<dc:creator>mud</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Note]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.buzamoto.com/?p=169</guid>
		<description><![CDATA[Like I mentioned earlier, Village 2.0 features the all new MudTyper Version 2. MudTyper 2 has two components: MudTyper Server, a light weight Cocoa HTTP server and MudTyper Renderer, the font renderer. On the Village website, MudTyper is integrated behind the rails application.
The Architecture
An overview of the architecture is shown below:

A POST request from the [...]]]></description>
			<content:encoded><![CDATA[<p>Like I mentioned earlier, <a href="http://vllg.com">Village 2.0</a> features the all new MudTyper Version 2. MudTyper 2 has two components: MudTyper Server, a light weight Cocoa HTTP server and MudTyper Renderer, the font renderer. On the Village website, MudTyper is integrated behind the rails application.</p>
<h4>The Architecture</h4>
<p>An overview of the architecture is shown below:</p>
<p><img class="aligncenter size-medium wp-image-170" title="mudtyper-diagram" src="http://blog.buzamoto.com/wp-content/uploads/2010/01/mudtyper-diagram-500x303.png" alt="mudtyper-diagram" width="500" height="303" /></p>
<p>A POST request from the browser is sent to a <a href="http://weblog.rubyonrails.org/2008/12/17/introducing-rails-metal">Rails Metal</a> URL periodically (as opposed to responding to keystroke events). The Rails Metal method verifies sessions, and request parameters and forwards them over to the MudTyper Server. The MudTyper Server then sends a request to MudTyper Renderer to create either a file that is saved to disk or a base64 encoded string depending on the user&#8217;s browser. The browser receives the image as a response and includes the rendered image into the page.</p>
<h4>Scalability</h4>
<p>With this architecture, it is possible to scale for increased load. We can run multiple instances of MudTyper Server+Renderer, and use <a href="http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html">mod_proxy</a> to get Apache to handle the load balancing.</p>
<h4>Font Rendering</h4>
<p>The new Renderer adds a lot of new support, including support for OpenType fonts with full kerning support, as well as many OTF features. For instance, we can now render <a href="http://vllg.com/Village/Galaxie_Cassiopeia#panel=mudtyper">Galaxie Cassiopeia</a>&#8217;s contextual alternates, adding smooth transitions between letters.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.buzamoto.com/2010/01/10/mudtyper-2-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BatesHori Website (PHP: Revisiting the Past)</title>
		<link>http://blog.buzamoto.com/2009/02/07/bateshori-website-php-revisiting-the-past/</link>
		<comments>http://blog.buzamoto.com/2009/02/07/bateshori-website-php-revisiting-the-past/#comments</comments>
		<pubDate>Sun, 08 Feb 2009 03:31:36 +0000</pubDate>
		<dc:creator>mud</dc:creator>
				<category><![CDATA[Client Work]]></category>
		<category><![CDATA[Note]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.buzamoto.com/?p=57</guid>
		<description><![CDATA[
Most of our client work involves Rails development. It seems everybody wants a website that allow them to change the content, anytime, anywhere, whenever they like. But I always tell my clients to think about how often this &#8220;change&#8221; is going to happen. It&#8217;s certainly a waste of money to pay for developing some feature that [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://www.bateshori.com/"><img class="aligncenter size-large wp-image-62" title="bateshori" src="http://blog.buzamoto.com/wp-content/uploads/2009/02/picture-1-1024x803.png" alt="bateshori" /></a></p>
<p>Most of our client work involves <a href="http://www.rubyonrails.org">Rails</a> development. It seems everybody wants a website that allow them to change the content, anytime, anywhere, whenever they like. But I always tell my clients to think about how often this &#8220;change&#8221; is going to happen. It&#8217;s certainly a waste of money to pay for developing some feature that you don&#8217;t end up using.</p>
<p>Even with Rails, having an &#8220;admin&#8221; backend requires extra design and development time. Also, with Rails and most other web frameworks, it&#8217;s not completely trivial to deploy and maintain these sites. For the client, it most likely means they need to ditch their current hosting provider and go with someone who will support Rails. Rails support on an affordable host is a hit or miss. I&#8217;m still surprised that Dreamhost still claims that they &#8220;support&#8221; Rails. In the world of VPS, the deployment is an easy thing, but for most clients, maintaining a VPS is a responsibility they don&#8217;t want. Why can&#8217;t it just work? I agree.</p>
<p>But this post isn&#8217;t about Rails. Instead, it&#8217;s about revisiting an oldie and ugly [but still sometimes a goodie] friend, PHP.</p>
<p><span id="more-57"></span></p>
<p>I just finished programming a site for <a href="http://www.bateshori.com/">Allen Hori</a>. His site doesn&#8217;t require many updates but he did want to update it himself whenever he needed to. Having a simple configuration file along with good old FTP to upload files was the way to go. I know there are those people that love XML and XSLT, but I&#8217;m not one of them. I hate XML &#8212; it&#8217;s hard to read, hard to edit in a text editor and it&#8217;s bloated&#8230;and I XSLT? It&#8217;s not for me, and that&#8217;s all there is to say. My choice was YAML and PHP.</p>
<p>I feel like I abandoned PHP long ago, but I still write it when I prototype, before going to Rails. As a language, I think PHP is ugly, inconsistent and generally something that makes me appreciate how great Ruby is. But PHP still has a lot going for it. First off, every host supports PHP. It doesn&#8217;t matter if it&#8217;s a linux, solaris or MS, they all support it. Also, it&#8217;s fast and easy to deploy. Copy the files over to the server, and it does it&#8217;s thing. No need to start a server or restart a process after your shared host restarts the server without warning.</p>
<p>Okay, enough with the talk, now for the technical goodies.</p>
<h2>Configuration</h2>
<p>Each &#8220;gallery&#8221; page is configurable. You can specify images and captions. This is easily described in YAML like this:</p>
<pre style="padding-left: 30px; ">title: Gallery Name
path: path/to/images
images:
  - image: first.jpg
    text: |
      here's a caption for the first image.
  - image: second.jpg
    text: |
      here's a caption for the second image.</pre>
<p>Parsing this in PHP is easy. We just google for a PHP yaml parser. I chose <a href="http://spyc.sourceforge.net/">spyc</a> because it comes as one file that you simply include. No installation necessary. You simply parse the yaml file like this:</p>
<pre style="padding-left: 30px;">$config = Spyc::YAMLLoad('config/gallery.yml');</pre>
<p>and magically, $config becomes a hash with the contents of the yaml file. That&#8217;s pretty much it, you can then go spaghetti style and insert content wherever you need. Whenever your client needs to update content, they just need to update the yaml file and upload any new images.</p>
<p>And&#8230;there&#8217;s more. Remember how this is a site that doesn&#8217;t change all that often? But we also don&#8217;t know when it will be updated. But with this current setup, every request will require PHP to do the same task. So being the responsible programmer, we need to implement caching.</p>
<h2>Caching</h2>
<p>We don&#8217;t know when Allen will decide to update the pages. But this is easy to determine. We know there was an update to the content any time the configuration file gets updated. So we need a way to generate a cache and update that cache anytime the configuration file is updated.</p>
<p>How do we do this? It&#8217;s actually really simple. Everything we need is built into PHP. To generate the cache, all we do is use <a href="http://ca2.php.net/outcontrol">PHP&#8217;s output buffer</a>. It&#8217;s surprisingly easy; 1. start the buffer, 2. generate the page, 3. open a file handler, 4. write the buffer contents, and 5. flush the buffer to the browser.</p>
<pre style="padding-left: 30px;">ob_start();
// generate the page here
$fp = fopen("cache_file_location", "w");
fwrite($fp, ob_get_contents());
fclose($fp);
ob_end_flush();</pre>
<p>This will save what&#8217;s sent to the browser to a file. To decide when to use the cache and when to generate a new one, we simply compare the file modification times of the yaml file and the cache.</p>
<pre style="padding-left: 30px;">if (file_exists($cachefile)) {
  if (filemtime("config/gallery.yml") &lt; filemtime($cachefile)) {
    include($cachefile);
    exit();
  }
}</pre>
<p>This will serve the contents of the cache file if the cache is up to date. Of course this conditional needs to run with every request, it will be much faster than having to evaluate the same PHP script over and over.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.buzamoto.com/2009/02/07/bateshori-website-php-revisiting-the-past/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CVOCV</title>
		<link>http://blog.buzamoto.com/2008/12/26/cvocv/</link>
		<comments>http://blog.buzamoto.com/2008/12/26/cvocv/#comments</comments>
		<pubDate>Fri, 26 Dec 2008 19:31:41 +0000</pubDate>
		<dc:creator>buza</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[opencv]]></category>

		<guid isPermaLink="false">http://blog.buzamoto.com/?p=50</guid>
		<description><![CDATA[
The development of some buzamoto internal research projects has resulted in CVOCV: A CoreVideo-based OpenCV experimentation environment. CVOCV is an XCode-based project that provides programmers with an extremely simple way to access and experiment with OpenCV. CVOCV is clean, fast, and understandable.  If you ever wanted to learn OpenCV on OS X without much hassle, download [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.buzamoto.com/wp-content/uploads/2008/12/cvocv_nb.png"><img class="alignnone size-full wp-image-53" title="cvocv_nb" src="http://blog.buzamoto.com/wp-content/uploads/2008/12/cvocv_nb.png" alt="" width="500" height="201" /></a></p>
<p>The development of some buzamoto internal research projects has resulted in <strong>CVOCV</strong>: <em>A CoreVideo-based OpenCV experimentation environment. </em>CVOCV is an XCode-based project that provides programmers with an extremely simple way to access and experiment with OpenCV. CVOCV is clean, fast, and understandable.  If you ever wanted to learn OpenCV on OS X without much hassle, download it from the <a href="http://wiki.buzamoto.com/cv_opencv/">buzamoto wiki</a> and have a look.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.buzamoto.com/2008/12/26/cvocv/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Crypted SMTP Auth with Postfix</title>
		<link>http://blog.buzamoto.com/2008/06/20/crypted-smtp-auth-with-postfix/</link>
		<comments>http://blog.buzamoto.com/2008/06/20/crypted-smtp-auth-with-postfix/#comments</comments>
		<pubDate>Sat, 21 Jun 2008 01:38:49 +0000</pubDate>
		<dc:creator>mud</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Server]]></category>

		<guid isPermaLink="false">http://blog.buzamoto.com/?p=8</guid>
		<description><![CDATA[
Today was a good day. Not only did I win Solitaire on my iPod on a train down to Providence, I fixed a mailserver issue that I&#8217;ve been struggling with for a few weeks.
I&#8217;m slowly switching over to Slicehost for all my web hosting requirements, and setting up the server (I&#8217;m running Ubuntu Hardy) so [...]]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter size-full wp-image-9" title="sany0005" src="http://blog.buzamoto.com/wp-content/uploads/2008/06/sany0005.jpg" alt="" width="500" height="333" /></p>
<p>Today was a good day. Not only did I win Solitaire on my iPod on a train down to Providence, I fixed a mailserver issue that I&#8217;ve been struggling with for a few weeks.</p>
<p>I&#8217;m slowly switching over to <a href="http://slicehost.com">Slicehost</a> for all my web hosting requirements, and setting up the server (I&#8217;m running Ubuntu Hardy) so that I can get rid of all the other hosting I use (I already got rid of crappy Dreamhost). I&#8217;ve been using <a href="http://pair.com">Pair</a> for the last ten years and have been really happy with them, but I&#8217;m a server junkie. VPS is just too tasty. Anyway, most server stuff is pretty straight forward to set up. <a href="http://articles.slicehost.com/">Pickled Onion articles</a> and a bunch of <a href="http://www.howtoforge.com/">howtoforge</a> docs will get you started from a fresh disk image in no time. One thing that tripped me up was setting up the mail server. I wanted the standard PostfixAdmin controlled virtual user setup using MySQL to manage the users. Following <a href="https://help.ubuntu.com/community/PostfixCompleteVirtualMailSystemHowto">this</a> and <a href="http://www.howtoforge.com/virtual-users-domains-postfix-courier-mysql-squirrelmail-ubuntu8.04">this</a> got everything working, except SMTP would not authenticate properly when storing passwords encrypted in the database.</p>
<p><span id="more-8"></span></p>
<p>Everything worked, Courier IMAP and SMTP Auth using TLS&#8230;but only if the users passwords were stored cleartext in the database. Even if connecting securely, storing passwords cleartext is a bad idea. The problem comes from <a href="http://ubuntuforums.org/showthread.php?t=259862">Ubuntu SASL libraries not supporting password_format</a>. I didn&#8217;t want to run the patch, since&#8230;well, I don&#8217;t really know how patching while using aptitude works (you probably have to run it every time you update), and I didn&#8217;t want to start compiling some things from source, while mostly relying on a package manager. I&#8217;ve inherited servers where some things are compiled from source and other things are managed on multiple package managers, and it is a BAD IDEA.</p>
<p>So, the solution. I followed the Ubuntu article and set up my database much like their example, but instead of using auxprop for pwcheck_method, I use saslauthd with PAM.</p>
<p>First, make sure you install libpam-mysql:</p>
<p><code> sudo aptitude install libpam-mysql<br />
</code></p>
<p>Then, in /etc/postfix/sasl/smtpd.conf:</p>
<p><code> pwcheck_method: saslauthd<br />
mech_list: plain login<br />
</code></p>
<p>You might also want to add log_level: 7 while you are debugging. Next, create /etc/pam.d/smtp with the following:</p>
<p><code> auth required pam_mysql.so user=the_user passwd=the_password host=127.0.0.1 db=postfix table=mailbox usercolumn=username passwdcolumn=password crypt=1<br />
account sufficient pam_mysql.so user=the_user passwd=the_password host=127.0.0.1 db=postfix table=mailbox usercolumn=username passwdcolumn=password crypt=1<br />
</code></p>
<p>Then make sure you use $CONF['encrypt'] = &#8217;system&#8217; for PostfixAdmin. You should observe /var/log/mail.log and /var/log/auth.log for any errors. When I first tried out PAM, I didn&#8217;t realize that I had not installed libpam-mysql, so only today when I went back and set the log_level did I actually realize I needed to install it.</p>
<p>Now I feel a little better not having cleartext passwords around&#8230;</p>
<p>ps. I am really bad at Solitaire, so it was a good day.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.buzamoto.com/2008/06/20/crypted-smtp-auth-with-postfix/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
