Solved

Exim forwaring email to scripts

Posted on 2013-11-25
11
771 Views
Last Modified: 2013-11-26
Hi,

I was hoping some one could help me. I want to set up a EXIM to forward all emails sent to a domain to a script on the server.

now I know I should be able to do this with an aliases entry such as

*@devilwah.com: |/var/tmp/script/php

although for some reason I don't see the script running so not sure it is working correctly. even though I see the mail get added in

You have new mail in /var/mail/pi

(yep running on a raspberry  )

but more importantly I want all emails to "devilwah.com" to go to the script even if no user exists. at the moment I get an unroutable error if I try to send to a non existence user.

Can any one help me set up the redirect to script for an entire domain. I want people to be able to pass information to the script usign the format of the address. for example 01234567891@sms.devilwah.com I would use the sms.devilwah.com to determin what script to use and the number would be a varible to extract.

Cheers
0
Comment
Question by:Aaron Street
  • 6
  • 4
11 Comments
 
LVL 19

Expert Comment

by:xterm
Comment Utility
Your syntax for the alias is correct - make sure that /var/tmp/script/php exists, is executable (chmod 755), and is accessible to the mail daemon.  I don't know what exim's rules are, but for sendmail to pipe to a file, the file needs to live in /etc/smrsh.  I would gather that your mail server has similar security in place that limits where you can run the script from.  While you are testing, I would suggest putting a logging routine that simply writes a file in /tmp or something to let you know that it ran (see the end of my script)

Once you've got the deliveries reliably going to the script, you can use the following to get you started.  Right now it does the following:

1)  Takes the piped stream and feeds it into a variable
2)  Passes the contents of that variable to a function which looks for a specified header (in this case, the "To" header)
3)  Writes a little log file entry with the recipient info

Now that you have the recipient line, you should be able to split it up into username and domain variables pretty easily and do whatever else you need.

#!/usr/bin/php -q
<?php

// THIS IS THE REAL-TIME PIPE OF THE MESSAGE
function piped_stdin() {
        $fd=fopen("php://stdin","r");
        $message="";
        while(!feof($fd)) { $message.=fread($fd,4096); }
        fclose($fd);
        return($message);
}

// JUST LOOKS FOR ^PATTERN: AND RETURNS THE RIGHT HAND SIDE
function find_header($message,$needle) {
  $hlines=explode("\n",$message);
  foreach ($hlines as $hline) {
    if(eregi("^$needle:",$hline)) {
      $needle=substr($hline,strpos($hline,":")+2,strlen($hline));
      return($needle);
    }
  }
  return("NOTFOUND");
}

$message=piped_stdin();
$recipient=find_header($message,"To");
$logfile="/tmp/mylog.txt";
$fp=fopen($logfile,"a");
fputs($fp,"This message was sent to $recipient\n");
fclose($fp);

?>

Open in new window

0
 
LVL 16

Author Comment

by:Aaron Street
Comment Utility
Ahh jsut seen one thing I miss typed the script name. "script.php" not "script/php"

however now that's sorted I am still not getting it to fire. I assume it must be security issue.

All my current script does at the moment is create a time stamped file in the same directory. Just so I can see if the redirect is kicking it off.

Cheers for the script above though, will be very useful once I have it working.
0
 
LVL 16

Author Comment

by:Aaron Street
Comment Utility
Also is this bit of config required for EXIM4 do you know ?

address_pipe:
  driver = pipe
  pipe_as_creator

from
http://evolt.org/incoming_mail_and_php
0
 
LVL 108

Assisted Solution

by:Ray Paseur
Ray Paseur earned 100 total points
Comment Utility
In my experience with automated processing of email, I had to have a single email address for the pipe script.  I never tried to use "any" email address -- it was always a single address.  I have not tested it, but that implies to me that the mail system could take any misrouted email for the domain and send it to the single email that is the pipe.

On my servers, if there was any browser output created by the pipe script, the sender would get a "mail rejected" message.  Hence the use of output buffering.  I also found that the pipe script needed to be placed outside of the WWW root to prevent accidental execution.  This meant some changes in things like file paths and database connections.

I used PHP mail() to get the diagnostic information when I was debugging the script. You can do that, or you can use error_log() to trap and reveal the diagnostic information.

Here is my teaching example of the pipe script.  Please read the comments carefully.  Add your own email address on line 60.  And best of luck!

#!/usr/bin/php -q
<?php
/**
 * /email_pipe/index.php
 * DATED: 2009-05-12
 *
 * THIS IS AN EMAIL PIPE SCRIPT.
 * THIS SCRIPT IS STARTED AUTOMATICALLY FOR EACH MESSAGE.
 * NOTE THAT THIS SCRIPT IS ABOVE THE /public_html/ DIRECTORY TO PREVENT ACCIDENTAL EXECUTION
 *
 * --> HOW DO WE KNOW WHICH EMAIL MESSAGES GET SENT HERE?
 * THIS SCRIPT RECEIVES MESSAGES SENT TO email_pipe@your.org
 * CREATE AN EMAIL MAILBOX EXCLUSIVELY FOR AUTOMATED PROCESSING.
 * SET UP AN EMAIL FORWARD FOR THAT MAILBOX IN cPANEL->EMAIL LIKE THIS:
 * 1...5...10...15...20...25...
 * |/home/{account}/email_pipe/index.php
 *
 * --> WHEN YOU UPLOAD, THIS SCRIPT WILL BE MARKED RW-R-R BUT THAT IS WRONG
 * THIS SCRIPT MUST BE MARKED EXECUTABLE x0755
 * YOU CAN USE FTP SOFTWARE TO CHMOD TO RWX-RX-RX
 *
 * --> NOTE THE FIRST LINE OF THIS SCRIPT MUST SAY #!/usr/bin/php -q STARTING IN COLUMN ONE
 * 1...5...10...15...20...25...
 * #!/usr/bin/php -q
 * <?php ... PROGRAM CODE FOLLOWS
 */
error_reporting(E_ALL);

// USE THE OUTPUT BUFFER - THIS DOES NOT HAVE BROWSER OUTPUT
ob_start();

// COLLECT THE INFORMATION HERE
$raw_email = NULL;

// TRY TO READ THE EMAIL FROM STDIN
if (!$stdin = fopen("php://stdin", "R"))
{
    echo 'ERROR: UNABLE TO OPEN php://stdin' . PHP_EOL;
}

// ABLE TO READ THE MAIL
else
{
    while (!feof($stdin))
    {
        $raw_email .= fread($stdin, 4096);
    }
    fclose($stdin);
}


// REMOVE MULTIPLE BLANKS - AND OTHER PROCESSING AS MIGHT BE NEEDED
$raw_email = preg_replace('/ +/', ' ', $raw_email);

// SPEW WHAT WE GOT, IF ANYTHING, INTO THE OUTPUT BUFFER
var_dump($raw_email);

// CAPTURE THE OUTPUT BUFFER AND SEND IT TO SOMEONE ELSE VIA EMAIL
$buf = ob_get_contents();
mail ('you@your.org', 'EMAIL PIPE DATA', $buf);

// PREVENT ANY BROWSER OUTPUT - MAY CAUSE ERROR RESPONSES AND BOUNCED MESSAGES
ob_end_clean();

Open in new window

HTH, ~Ray
0
 
LVL 16

Author Comment

by:Aaron Street
Comment Utility
I am still having issues getting the script to be fired?

my aliseas file now has the line

pi@devilwah.com: |/tmp/script.php

and the script is simply

#!/usr/bin/php -q
<?php

$data = "hello World";
$file = '/tmp/test';

file_put_contents($file, $data);


?>

Open in new window


useing the below telnet test I can send an email to the pi user

telnet 127.0.0.1 25
helo devilwah.com
mail from: me.me@table.ac.uk
rcpt to: pi@devilwah.com
data
To: pi@devilwah.com
From me
Subject: A test

test hello test

.
quit

Open in new window


the email appears in /var/mail/pi but the script never runs, it does work fine running it from command line ./script.php

I don't see any logs any where suggesting it even attempts to pipe it to the script instead it just shows it getting delivered.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 19

Expert Comment

by:xterm
Comment Utility
If the mail gets to the script, it will never arrive in /var/mail/pi, so clearly it's not reading that alias - what does it say in /var/log/exim_mainlog? exim_rejectlog?  Anything?

That should give you some idea as to why it's refusing to pipe it.
0
 
LVL 16

Author Comment

by:Aaron Street
Comment Utility
Hi,

nope all i see is this

2013-09-25 23:59:18 1VOyzF-0000xV-VV <= aaron.street@example.com H=localhost (devilwah.com) [127.0.0.1] P=smtp S=419
2013-09-25 23:59:19 1VOyzF-0000xV-VV => pi <pi@devilwah.com> R=local_user T=mail_spool
2013-09-25 23:59:19 1VOyzF-0000xV-VV Completed

So dosen't even seem to attempt the redirect?
0
 
LVL 16

Author Comment

by:Aaron Street
Comment Utility
Ahh.

buried in the config I find

Delivery to arbitrary directories, files, and piping to programs in
# /etc/aliases is disabled per default.
# If that is a problem for you, see
#   /usr/share/doc/exim4-base/README.Debian.gz
# for explanation and some workarounds.

yet to find he workaround but....
0
 
LVL 19

Accepted Solution

by:
xterm earned 400 total points
Comment Utility
Step #2 and onward of the link below seems to address what you need:

http://shout.setfive.com/2012/06/20/use-exim-and-pipes-to-replicate-mailgun-routes/
0
 
LVL 16

Author Closing Comment

by:Aaron Street
Comment Utility
Cheers Xterm.

Adding them all together I finally got it to process the script! More playing is needed but the basic redirecting of emails is there. I am wondering if sendmail or another MTA would be a cleaner solution :)

thanks for all you help with this appricate it.
0
 
LVL 19

Expert Comment

by:xterm
Comment Utility
Exim, postfix, sendmail are all good - I am a sendmail guy, but you should use whatever has the most familiarity to you.  Personally, I think if you have it working there's now no need to change it.

Glad you're all set up!
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Marketers need statistics and metrics like everybody else needs oxygen. In this article we explain how to enable marketing campaign statistics for Microsoft Exchange mail.
Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
To show how to generate a certificate request in Exchange 2013. We show this process by using the Exchange Admin Center. Log into Exchange Admin Center.:  First we need to log into the Exchange Admin Center. Navigate to the Servers >> Certificates…
The video tutorial explains the basics of the Exchange server Database Availability groups. The components of this video include: 1. Automatic Failover 2. Failover Clustering 3. Active Manager

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now