Sunday, September 27, 2009

Adding Enum support to CakePHP

CakePHP have been previously support Enum, but it was removed because Enum is actually MySQL specific datatype.

I really need this feature and so I decided to hack the form helper to support Enum type.
It is basically adding new Enum handler to the input() method of form helper which is used by scaffolding or user custom form.

Here is the patch of [CAKE_ROOT]/cake/libs/view/helpers/form.php file:
582c582
< 
---
>   
613a614,625
>     
>  // enum special handling
>  preg_match('/enum\((.*)\)/i', $type, $matches);
>  if(!empty($matches[1])) {
>    $options['type'] = 'select';
>    $enum_options = explode(',', $matches[1]);
>    $options['options'] = array();
>    foreach($enum_options as $_option) {
>      $option = trim($_option, "\"' ");
>      $options['options'][$option] = $option;
>    }
>  }
624c636
< 
---
>    

Once you patched the file, every Enum fields will be displayed as a HTML select instead of a normal text field. Goodluck!

Thursday, September 3, 2009

Setting up DomainKeys (DK) and DomainKeys Identified Mail (DKIM) for Sendmail

A short introduction abort DK and DKIM. DK and DKIM is basically an email authentication system to verify the DNS of email sender and message integrity.

How it works? Let say a user (john@example.org) send an email to other people using Yahoo! account (jen@yahoo.com). The MTA of example.org will sign the message using private key before delivering the email. Once the message received by target server (in this case Yahoo!), they will verify the message using example.org public key published as TXT info by the example.org name server.

DK or DKIM will guarantee that a verified email is coming from the right person or organization.

I will explain how to install DK and DKIM with Sendmail. Why DK and DKIM? some email server might support only DK and some might support advanced DK which is DKIM.

Requirements:
  • Sendmail 8.13 or higher (with Milter support)
  • OpenSSL
  • Bind DNS server (or any other DNS server)

Installation:
  1. Install this following packages:
    • latest OpenSSL + OpenSSL-devel package from YUM
    • Sendmail, Sendmail-cf and Sendmail-devel for Milter support
  2. Download DK-Milter and DKIM-Milter packages:
  3. Build and compilation
    DK-Milter & DKIM-Milter have quite similar installation step configuration.
    • DKIM-Milter
      • Extract package
      • Copy configuration file from site.config.m4.dist to devtools/Site/site.config.m4 (use default configuration for now)
      • Build & install:
        # sh Build
        # sh Build install
        
    • DK-Milter
      • Extract package
      • Copy configuration file from site.config.m4.dist to devtools/Site/site.config.m4 (use default configuration for now)
      • Build & install:
        # sh Build
        # sh Build install


    • Key generation and DNS setup
      Both DK & DKIM require secure key pair to sign the mail. DKIM comes with tools called dkim-genkey, run it and 2 files will be created, one is the private key and the other one is the DNS TXT entry.
      • Copy & rename the default.private to /var/db/dk-dkim/mail
      • Update bind and add this follwoing TXT entry:
        mail._domainkey.example.org. IN TXT "v=DKIM1; g=*; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMa7vGwI3zb+y8DL5cI5YU0PrdWhrpOTDLrdwnkGzmj0SEYj4lk7Vsq2f40uiB9qL70OB4HTT+eTeFgL1TNPPcMUkQRj8zKX98BwF+CCQ7wpIbJfoMKGpMQaKbzHcfjWjqWbYGpk4WtM4oj/aSklrIr71w0GpjhONDj+M/QT5w/wIDAQAB"
        _domainkey.example.org.  IN TXT "o=~"
        
        Where p=?, ? is the public key generated by dkim-genkey.
      • Restart the DNS service.


  4. Sendmail integration
    • Configure sendmail milter
      We will run DK on port 8891 and DKIM on port 8892
      • Edit /etc/mail/sendmail.mc and add this following lines
        INPUT_MAIL_FILTER(`dk-filter', `S=inet:8891@localhost')
        INPUT_MAIL_FILTER(`dkim-filter', `S=inet:8892@localhost')
      • Rebuild sendmail config by running
        # make sendmail.cf
        # make restart
    • Start DK and DKIM
      # /usr/sbin/useradd -r domainkeys
      # chown -Rf domainkeys /var/db/dk-dkim/
      # /usr/bin/dk-filter -l -p inet:8891@localhost -c simple -b s -h -d example.org -D -s /var/db/dk-dkim/mail -S mail -u domainkeys -m MSA
      # /usr/sbin/dkim-filter -l -p inet:8892@localhost -c simple -b s -h -d example.org -D -k /var/db/dk-dkim/mail -s mail -S rsa-sha256 -u domainkeys -m MSA
      
To test send an email to DK or DKIM aware mail provider (eg: Yahoo!). You should see something like this in mail the header: Signature:
X-DKIM: Sendmail DKIM Filter v2.8.3 host3.example.org n82G7Xwh008144
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=example.org;
 s=mail; t=1251907653; i=@example.org;
 bh=XgF6uYzcgcROQtd83d1Evx8x2uW+SniFx69skZp5azo=;
 h=Date:From:Message-Id:To:Subject;
 b=d2J8AiWmqecDvFvOva6bahU0TEB+q5RYonPCMh/24UpKBzAIczV7ohhW73LcVJaKw
  xshr0SFRDaOE48iGp6FxC1yfHEFr7nix6vzvhc2Hr5MgwsRy1HwwI36mkPrhrnbMb/
  d2Khy498P9z7qj+yNF99RRxq7NAftRbFFxbVb10s=
X-DomainKeys: Sendmail DomainKeys Filter v1.0.2 host3.example.org n82G7Xwh008144
DomainKey-Signature: a=rsa-sha1; s=mail; d=example.org; c=simple; q=dns;
 b=ndEg7XD5PnWe1/SHdKygFZ9s8ZwwhmFBRVjNwEaPytptgEl5XJ41DWwjspq5+4huj
 6SFBQMmVnEOvRwMPTvL8o9mD+M41vaV0X7dLSNYnC9K3JjFpZiwzLonGNag2TwrQBc3
 zzxZqpol5SSOsi93sZ7j3FMNTPdjVIhcsHdvHVw=

Verification:
Authentication-Results: mta117.mail.re3.yahoo.com  from=mail.example.org; domainkeys=pass (ok); from=example.org; dkim=pass (ok)

Thats all