pilif.ch - a cuwps

[home]
stuff
some worldwide unique stuff
  • Daily Strips
  • PersistentHandler
  • Denis' Birthday
  • DVD-Region (1)
  • DVD-Region (2)
  • Defeating Miguel
  • Neuronal Interface ;-)
  • Swiss ADSL Check
  • Autodestructing Email
  • Fun with bounces

  • Introduction
  • Theory
  • Solution
  • The MTA
  • Code
  • Conclusion
  • backstage
    backstage-reports of some of my paid projects
  • bookexchange.ch
  • info
    valuable information for my visitors
  • RasInTask
  •  
    the {{something}}
    Since I hate parsing strings and since parsing bounce-mails is a real pain in the a** (every MTA creates it's own flavour of message and there is no real standard for the headers the bounce-message should have), I looked for a way to get the failed address without having to parse the bounce (in which the address certainly would be written somehwere).

    This leads me to the misterious {{something}}: I looked for a solution to encode the whole email-address of the reciver into this faked local username. So my PHP script would have nothing to do but to decode the string.

    First I thougt of BASE64: I wanted to create the {{something}} by BASE64 encoding the Address the Email was directed to, but some real-live tests with real mailservers in the internet showed me, that this cannot work since email-Addresses are case-insensitive (and mostly converted to all lowercase) and BASE64 relies on Upper and Lowercase being passed.

    Finally, I used a very cheap solution (I was in a hurry: I had less than a week from the first idea to the final implementation): I modified the BASE64-Algorithm to add a dot (.) before every Uppercase letter and pass the letter back as lowercase.

    So when I have a BASE64-String of RGVkaWNhdGVkIHRvIEJhcmJhcmE=, my modified algorithm would create .r.g.vka.w.nhd.g.vk.i.h.rv.i.e.jhcm.jhcm.e= I did this with a simple regexp-replacement and I leave it to you to do it for yourself. Just a bit regexp is good for everyone.

    Decoding was also only a matter of regexps and using the PHP-Function base64_decode()

    To conclude: The {{something}} is the address to which the mail is sent to encoded in BASE64 where every uppercase-letter is replaced with a lowercase one with a dot (.) before it.

    php tweaks
    The two scripts finally used where quite simple. I'm just showing you some specialities:

    The modified base64-Algorithm

    Yes... I know: I did not want to tell it in the section above, but I'm showing it here anyway because I do not want to receive mails of puzzled sysadmins that cannot work it out. It's PHP-Code:

     
    
    
     <?php
     
    function decode_address($str){
      return 
    base64_decode(preg_replace('/\.([a-z])/e'"strtoupper('\1')"$str));
     }
     
     function 
    encode_address($str){
      return 
    preg_replace('/([A-Z])/e'"strtolower('.\1')"base64_encode($str));
     }
     
    ?>

    Reading the address and flag it in the database

    This is also really simple, I'm just showing it here in case you cannot understand what I'm writing about in this tutorial (my PHP might be better than my English):

     
    
    
    <?php
    //...
    $address decode_address($argv[1]);
    // $address now contains the address, the mail that 
    // just bounced was sent to
    //...
    $hsh  get_bounce_state($address);
    $flag $hsh['BounceFlag'];

    if (
    $flag == BOUNCE_ERR) exit(0); //no error code. This would lead to
                                      //bounce being generated. -> loop
    /*
       BOUNCE_ONCE is never the state of a mail that fails. The mailer-
       script sets the Flag to bounce_check before sending the mail
    */
    $old_flag $flag;
    if (
    $flag == BOUNCE_OK)
     
    $flag BOUNCE_ONCE;
    elseif(
    $flag == BOUNCE_CHECK)
     
    $flag BOUNCE_FAIL;

    if (
    $flag != $old_flag)
     
    set_bounce_flag($address$flag);

    /*
     The code above is just twiddling with my whish to have two bounces
     received before the message is blocked. I cannot just increment a
     counter everytime I receive a bounce. And decrement when sending it
     because I wanted to handle also the complex cases where mail was
     bouncing sometimes and sometimes not...
    */ 
    ?>

    Setting the envelope-From

    This is the most important step: We want the Mails we generate to have this special Envelope-From-Address where the bounces are to be sent to. the PHP mail() function does not allow this, so I was calling exim directely:

     
    
    
     <?php
     $env_from 
    'webreply-'.encode_address($email).'@domain.com';
     
    $exim     popen("/usr/local/exim/bin/exim -f $env_from $email""w");
     
    ?>
    For this to work, the user calling the command must be listed in the trusted_users list of your exim.conf:
     trusted_users = domain:root:pilif
    
    (jepp. I always trust myself... mostly... at least when dealing with computers... sometimes.)


    © 2003 by pilif. cuwps stands for completely useless webpage and is a non-registered non-trademark by pilif - Last Modification: 04/03/01 at 13:54:00