diff --git a/api/pipe.php b/api/pipe.php index ff23cfa1b56c0f6fa75824f8106337c7440f6cb9..7429a6367a351882fef425d5d42f04f6b0919f34 100644 --- a/api/pipe.php +++ b/api/pipe.php @@ -3,7 +3,7 @@ /********************************************************************* pipe.php - Converts piped emails to ticket. Both local and remote! + Converts piped emails to ticket. Just local - remote must use /api/tickets.email Peter Rotich <peter@osticket.com> Copyright (c) 2006-2012 osTicket @@ -14,122 +14,14 @@ vim: expandtab sw=4 ts=4 sts=4: **********************************************************************/ -@chdir(realpath(dirname(__FILE__)).'/'); //Change dir. -ini_set('memory_limit', '256M'); //The concern here is having enough mem for emails with attachments. -$apikey = null; -require('api.inc.php'); -require_once(INCLUDE_DIR.'class.mailparse.php'); -require_once(INCLUDE_DIR.'class.email.php'); - -//Make sure piping is enabled! -if(!$cfg->isEmailPipingEnabled()) - api_exit(EX_UNAVAILABLE,'Email piping not enabled - check MTA settings.'); -elseif($apikey && !$apikey->canCreateTickets()) //apikey is ONLY set on remote post - local post don't need a key (for now). - api_exit(EX_NOPERM, 'API key not authorized'); - -//Get the input -$data=isset($_SERVER['HTTP_HOST'])?file_get_contents('php://input'):file_get_contents('php://stdin'); -if(empty($data)){ - api_exit(EX_NOINPUT,'No data'); -} - -//Parse the email. -$parser= new Mail_Parse($data); -if(!$parser->decode()){ //Decode...returns false on decoding errors - api_exit(EX_DATAERR,'Email parse failed ['.$parser->getError()."]\n\n".$data); -} - - - -//Check from address. make sure it is not a banned address. -$fromlist = $parser->getFromAddressList(); -//Check for parsing errors on FROM address. -if(!$fromlist || PEAR::isError($fromlist)){ - api_exit(EX_DATAERR,'Invalid FROM address ['.$fromlist?$fromlist->getMessage():''."]\n\n".$data); -} - -$from=$fromlist[0]; //Default. -foreach($fromlist as $fromobj){ - if(!Validator::is_email($fromobj->mailbox.'@'.$fromobj->host)) - continue; - $from=$fromobj; - break; -} - -//TO Address:Try to figure out the email associated with the message. -$tolist = $parser->getToAddressList(); -foreach ($tolist as $toaddr){ - if(($emailId=Email::getIdByEmail($toaddr->mailbox.'@'.$toaddr->host))){ - //We've found target email. - break; - } -} -if(!$emailId && ($cclist=$parser->getCcAddressList())) { - foreach ($cclist as $ccaddr){ - if(($emailId=Email::getIdByEmail($ccaddr->mailbox.'@'.$ccaddr->host))){ - break; - } - } -} -//TODO: Options to reject emails without a matching To address in db? May be it was Bcc? Current Policy: If you pipe, we accept policy -require_once(INCLUDE_DIR.'class.ticket.php'); //We now need this bad boy! +//Only local piping supported via pipe.php +if (substr(php_sapi_name(), 0, 3) != 'cli') + die('pipe.php only supports local piping - use http -> api/tickets.email'); -$var=array(); -$deptId=0; -$name=trim($from->personal,'"'); -if($from->comment && $from->comment[0]) - $name.=' ('.$from->comment[0].')'; -$subj=utf8_encode($parser->getSubject()); -if(!($body=Format::stripEmptyLines($parser->getBody()))) - $body=$subj?$subj:'(EMPTY)'; - -$var['mid']=$parser->getMessageId(); -$var['email']=$from->mailbox.'@'.$from->host; -$var['name']=$name?utf8_encode($name):$var['email']; -$var['emailId']=$emailId?$emailId:$cfg->getDefaultEmailId(); -$var['subject']=$subj?$subj:'[No Subject]'; -$var['message']=utf8_encode(Format::stripEmptyLines($body)); -$var['header']=$parser->getHeader(); -$var['priorityId']=$cfg->useEmailPriority()?$parser->getPriority():0; - -$ticket=null; -if(preg_match ("[[#][0-9]{1,10}]", $var['subject'], $regs)) { - $extid=trim(preg_replace("/[^0-9]/", "", $regs[0])); - if(!($ticket=Ticket::lookupByExtId($extid, $var['email'])) || strcasecmp($ticket->getEmail(), $var['email'])) - $ticket = null; -} - -$errors=array(); -$msgid=0; -if($ticket) { - //post message....postMessage does the cleanup. - if(!($msgid=$ticket->postMessage($var['message'], 'Email',$var['mid'],$var['header']))) - api_exit(EX_DATAERR, 'Unable to post message'); - -} elseif(($ticket=Ticket::create($var, $errors, 'email'))) { // create new ticket. - $msgid=$ticket->getLastMsgId(); -} else { // failure.... - - // report success on hard rejection - if(isset($errors['errno']) && $errors['errno'] == 403) - api_exit(EX_SUCCESS); - - // check if it's a bounce! - if($var['header'] && TicketFilter::isAutoBounce($var['header'])) { - $ost->logWarning('Bounced email', $var['message'], false); - api_exit(EX_SUCCESS); - } - - api_exit(EX_DATAERR, 'Ticket create Failed '.implode("\n",$errors)."\n\n"); -} - -//Ticket created...save attachments if enabled. -if($ticket && $cfg->allowEmailAttachments() && ($attachments=$parser->getAttachments())) { - foreach($attachments as $attachment) { - if($attachment['filename'] && $ost->isFileTypeAllowed($attachment['filename'])) - $ticket->saveAttachment(array('name' => $attachment['filename'], 'data' => $attachment['body']), $msgid, 'M'); - } -} -api_exit(EX_SUCCESS); +ini_set('memory_limit', '256M'); //The concern here is having enough mem for emails with attachments. +@chdir(realpath(dirname(__FILE__)).'/'); //Change dir. +require('api.inc.php'); +require_once(INCLUDE_DIR.'api.tickets.php'); +PipeApiController::process(); ?> diff --git a/include/api.tickets.php b/include/api.tickets.php index 5da97182ec13b16acb78cba69589291d546fcbac..7346f2b2943bbc5c0451d62fcc7952677034b6d5 100644 --- a/include/api.tickets.php +++ b/include/api.tickets.php @@ -91,4 +91,50 @@ class TicketApiController extends ApiController { } +//Local email piping controller - no API key required! +class PipeApiController extends TicketApiController { + + //Overwrite grandparent's (ApiController) response method. + function response($code, $resp) { + + //Use postfix exit codes - instead of HTTP + switch($code) { + case 201: //Success + $exitcode = 0; + break; + case 400: + $exitcode = 66; + break; + case 401: /* permission denied */ + case 403: + $exitcode = 77; + break; + case 415: + case 416: + case 417: + case 501: + $exitcode = 65; + break; + case 503: + $exitcode = 69; + break; + case 500: //Server error. + default: //Temp (unknown) failure - retry + $exitcode = 75; + } + + //echo "$code ($exitcode):$resp"; + //We're simply exiting - MTA will take care of the rest based on exit code! + exit($exitcode); + } + + function process() { + $pipe = new PipeApiController(); + if(($ticket=$pipe->processEmail())) + return $pipe->response(201, $ticket->getNumber()); + + return $pipe->exerr(416, 'Request failed -retry again!'); + } +} + ?>