function getFile() { if (!$this->file && $this->getFileId()) { $this->file = AttachmentFile::lookup($this->getFileId()); } return $this->file; }
function viewableImages($html, $script = false) { return preg_replace_callback('/"cid:([\\w._-]{32})"/', function ($match) use($script) { $hash = $match[1]; if (!($file = AttachmentFile::lookup($hash))) { return $match[0]; } return sprintf('"%s" data-cid="%s"', $file->getDownloadUrl(false, 'inline', $script), $match[1]); }, $html); }
function render($how) { $config = $this->field->getConfiguration(); $name = $this->field->getFormName(); $id = substr(md5(spl_object_hash($this)), 10); $attachments = $this->field->getFiles(); $mimetypes = array_filter($config['__mimetypes'], function ($t) { return strpos($t, '/') !== false; }); $files = array(); foreach ($this->value ?: array() as $fid) { $found = false; foreach ($attachments as $f) { if ($f['id'] == $fid) { $files[] = $f; $found = true; break; } } if (!$found && ($file = AttachmentFile::lookup($fid))) { $files[] = array('id' => $file->getId(), 'name' => $file->getName(), 'type' => $file->getType(), 'size' => $file->getSize(), 'download_url' => $file->getDownloadUrl()); } } ?> <div id="<?php echo $id; ?> " class="filedrop"><div class="files"></div> <div class="dropzone"><i class="icon-upload"></i> <?php echo sprintf(__('Drop files here or %s choose them %s'), '<a href="#" class="manual">', '</a>'); ?> <input type="file" multiple="multiple" id="file-<?php echo $id; ?> " style="display:none;" accept="<?php echo implode(',', $config['__mimetypes']); ?> "/> </div></div> <script type="text/javascript"> $(function(){$('#<?php echo $id; ?> .dropzone').filedropbox({ url: 'ajax.php/form/upload/<?php echo $this->field->get('id'); ?> ', link: $('#<?php echo $id; ?> ').find('a.manual'), paramname: 'upload[]', fallback_id: 'file-<?php echo $id; ?> ', allowedfileextensions: <?php echo JsonDataEncoder::encode($config['__extensions'] ?: array()); ?> , allowedfiletypes: <?php echo JsonDataEncoder::encode($mimetypes); ?> , maxfiles: <?php echo $config['max'] ?: 20; ?> , maxfilesize: <?php echo ($config['size'] ?: 1048576) / 1048576; ?> , name: '<?php echo $name; ?> []', files: <?php echo JsonDataEncoder::encode($files); ?> });}); </script> <?php }
function send($to, $subject, $message, $options = null) { global $ost; //Get the goodies require_once PEAR_DIR . 'Mail.php'; // PEAR Mail package require_once PEAR_DIR . 'Mail/mime.php'; // PEAR Mail_Mime packge //do some cleanup $to = preg_replace("/(\r\n|\r|\n)/s", '', trim($to)); $subject = preg_replace("/(\r\n|\r|\n)/s", '', trim($subject)); //We're decoding html entities here becasuse we only support plain text for now - html support comming. $body = Format::htmldecode(preg_replace("/(\r\n|\r)/s", "\n", trim($message))); /* Message ID - generated for each outgoing email */ $messageId = sprintf('<%s%d-%s>', Misc::randCode(6), time(), $this->getEmail() ? $this->getEmail()->getEmail() : '@osTicketMailer'); $headers = array('From' => $this->getFromAddress(), 'To' => $to, 'Subject' => $subject, 'Date' => date('D, d M Y H:i:s O'), 'Message-ID' => $messageId, 'X-Mailer' => 'osTicket Mailer'); //Set bulk/auto-response headers. if ($options && ($options['autoreply'] or $options['bulk'])) { $headers += array('X-Autoreply' => 'yes', 'X-Auto-Response-Suppress' => 'ALL, AutoReply', 'Auto-Submitted' => 'auto-replied'); if ($options['bulk']) { $headers += array('Precedence' => 'bulk'); } else { $headers += array('Precedence' => 'auto_reply'); } } if ($options) { if (isset($options['inreplyto']) && $options['inreplyto']) { $headers += array('In-Reply-To' => $options['inreplyto']); } if (isset($options['references']) && $options['references']) { if (is_array($options['references'])) { $headers += array('References' => implode(' ', $options['references'])); } else { $headers += array('References' => $options['references']); } } } $mime = new Mail_mime(); $mime->setTXTBody($body); //XXX: Attachments if ($attachments = $this->getAttachments()) { foreach ($attachments as $attachment) { if ($attachment['file_id'] && ($file = AttachmentFile::lookup($attachment['file_id']))) { $mime->addAttachment($file->getData(), $file->getType(), $file->getName(), false); } elseif ($attachment['file'] && file_exists($attachment['file']) && is_readable($attachment['file'])) { $mime->addAttachment($attachment['file'], $attachment['type'], $attachment['name']); } } } //Desired encodings... $encodings = array('head_encoding' => 'quoted-printable', 'text_encoding' => 'base64', 'html_encoding' => 'base64', 'html_charset' => 'utf-8', 'text_charset' => 'utf-8', 'head_charset' => 'utf-8'); //encode the body $body = $mime->get($encodings); //encode the headers. $headers = $mime->headers($headers, true); if ($smtp = $this->getSMTPInfo()) { //Send via SMTP $mail = mail::factory('smtp', array('host' => $smtp['host'], 'port' => $smtp['port'], 'auth' => $smtp['auth'], 'username' => $smtp['username'], 'password' => $smtp['password'], 'timeout' => 20, 'debug' => false)); $result = $mail->send($to, $headers, $body); if (!PEAR::isError($result)) { return $messageId; } $alert = sprintf("Unable to email via SMTP:%s:%d [%s]\n\n%s\n", $smtp['host'], $smtp['port'], $smtp['username'], $result->getMessage()); $this->logError($alert); } //No SMTP or it failed....use php's native mail function. $mail = mail::factory('mail'); return PEAR::isError($mail->send($to, $headers, $body)) ? false : $messageId; }
function send($to, $subject, $message, $options = null) { global $ost, $cfg; //Get the goodies require_once PEAR_DIR . 'Mail.php'; // PEAR Mail package require_once PEAR_DIR . 'Mail/mime.php'; // PEAR Mail_Mime packge $messageId = $this->getMessageId($to, $options); if (is_object($to) && is_callable(array($to, 'getEmail'))) { // Add personal name if available if (is_callable(array($to, 'getName'))) { $to = sprintf('"%s" <%s>', $to->getName()->getOriginal(), $to->getEmail()); } else { $to = $to->getEmail(); } } //do some cleanup $to = preg_replace("/(\r\n|\r|\n)/s", '', trim($to)); $subject = preg_replace("/(\r\n|\r|\n)/s", '', trim($subject)); $headers = array('From' => $this->getFromAddress(), 'To' => $to, 'Subject' => $subject, 'Date' => date('D, d M Y H:i:s O'), 'Message-ID' => $messageId, 'X-Mailer' => 'osTicket Mailer'); // Add in the options passed to the constructor $options = ($options ?: array()) + $this->options; if (isset($options['nobounce']) && $options['nobounce']) { $headers['Return-Path'] = '<>'; } elseif ($this->getEmail() instanceof Email) { $headers['Return-Path'] = $this->getEmail()->getEmail(); } //Bulk. if (isset($options['bulk']) && $options['bulk']) { $headers += array('Precedence' => 'bulk'); } //Auto-reply - mark as autoreply and supress all auto-replies if (isset($options['autoreply']) && $options['autoreply']) { $headers += array('Precedence' => 'auto_reply', 'X-Autoreply' => 'yes', 'X-Auto-Response-Suppress' => 'DR, RN, OOF, AutoReply', 'Auto-Submitted' => 'auto-replied'); } //Notice (sort of automated - but we don't want auto-replies back if (isset($options['notice']) && $options['notice']) { $headers += array('X-Auto-Response-Suppress' => 'OOF, AutoReply', 'Auto-Submitted' => 'auto-generated'); } if ($options) { if (isset($options['inreplyto']) && $options['inreplyto']) { $headers += array('In-Reply-To' => $options['inreplyto']); } if (isset($options['references']) && $options['references']) { if (is_array($options['references'])) { $headers += array('References' => implode(' ', $options['references'])); } else { $headers += array('References' => $options['references']); } } } // Make the best effort to add In-Reply-To and References headers $reply_tag = $mid_token = ''; if (isset($options['thread']) && $options['thread'] instanceof ThreadEntry) { if ($irt = $options['thread']->getEmailMessageId()) { // This is an response from an email, like and autoresponse. // Web posts will not have a email message-id $headers += array('In-Reply-To' => $irt, 'References' => $options['thread']->getEmailReferences()); } elseif ($parent = $options['thread']->getParent()) { // Use the parent item as the email information source. This // will apply for staff replies $headers += array('In-Reply-To' => $parent->getEmailMessageId(), 'References' => $parent->getEmailReferences()); } // Configure the reply tag and embedded message id token $mid_token = $options['thread']->asMessageId($to); if ($cfg && $cfg->stripQuotedReply() && (!isset($options['reply-tag']) || $options['reply-tag'])) { $reply_tag = $cfg->getReplySeparator() . '<br/><br/>'; } } // Use general failsafe default initially $eol = "\n"; // MAIL_EOL setting can be defined in `ost-config.php` if (defined('MAIL_EOL') && is_string(MAIL_EOL)) { $eol = MAIL_EOL; } $mime = new Mail_mime($eol); // If the message is not explicitly declared to be a text message, // then assume that it needs html processing to create a valid text // body $isHtml = true; if (!(isset($options['text']) && $options['text'])) { if ($reply_tag || $mid_token) { $message = "<div style=\"display:none\"\n class=\"mid-{$mid_token}\">{$reply_tag}</div>{$message}"; } $txtbody = rtrim(Format::html2text($message, 90, false)) . ($mid_token ? "\nRef-Mid: {$mid_token}\n" : ''); $mime->setTXTBody($txtbody); } else { $mime->setTXTBody($message); $isHtml = false; } if ($isHtml && $cfg && $cfg->isHtmlThreadEnabled()) { // Pick a domain compatible with pear Mail_Mime $matches = array(); if (preg_match('#(@[0-9a-zA-Z\\-\\.]+)#', $this->getFromAddress(), $matches)) { $domain = $matches[1]; } else { $domain = '@localhost'; } // Format content-ids with the domain, and add the inline images // to the email attachment list $self = $this; $message = preg_replace_callback('/cid:([\\w.-]{32})/', function ($match) use($domain, $mime, $self) { if (!($file = AttachmentFile::lookup($match[1]))) { return $match[0]; } $mime->addHTMLImage($file->getData(), $file->getType(), $file->getName(), false, $match[1] . $domain); // Don't re-attach the image below unset($self->attachments[$file->getId()]); return $match[0] . $domain; }, $message); // Add an HTML body $mime->setHTMLBody($message); } //XXX: Attachments if ($attachments = $this->getAttachments()) { foreach ($attachments as $attachment) { if ($attachment['file_id'] && ($file = AttachmentFile::lookup($attachment['file_id']))) { $mime->addAttachment($file->getData(), $file->getType(), $file->getName(), false); } } } //Desired encodings... $encodings = array('head_encoding' => 'quoted-printable', 'text_encoding' => 'base64', 'html_encoding' => 'base64', 'html_charset' => 'utf-8', 'text_charset' => 'utf-8', 'head_charset' => 'utf-8'); //encode the body $body = $mime->get($encodings); //encode the headers. $headers = $mime->headers($headers, true); // Cache smtp connections made during this request static $smtp_connections = array(); if ($smtp = $this->getSMTPInfo()) { //Send via SMTP $key = sprintf("%s:%s:%s", $smtp['host'], $smtp['port'], $smtp['username']); if (!isset($smtp_connections[$key])) { $mail = mail::factory('smtp', array('host' => $smtp['host'], 'port' => $smtp['port'], 'auth' => $smtp['auth'], 'username' => $smtp['username'], 'password' => $smtp['password'], 'timeout' => 20, 'debug' => false, 'persist' => true)); if ($mail->connect()) { $smtp_connections[$key] = $mail; } } else { // Use persistent connection $mail = $smtp_connections[$key]; } $result = $mail->send($to, $headers, $body); if (!PEAR::isError($result)) { return $messageId; } // Force reconnect on next ->send() unset($smtp_connections[$key]); $alert = sprintf(__("Unable to email via SMTP:%1\$s:%2\$d [%3\$s]\n\n%4\$s\n"), $smtp['host'], $smtp['port'], $smtp['username'], $result->getMessage()); $this->logError($alert); } //No SMTP or it failed....use php's native mail function. $mail = mail::factory('mail'); return PEAR::isError($mail->send($to, $headers, $body)) ? false : $messageId; }
file.php File download facilitator for clients Peter Rotich <*****@*****.**> Jared Hancock <*****@*****.**> Copyright (c) 2006-2014 osTicket http://www.osticket.com Released under the GNU General Public License WITHOUT ANY WARRANTY. See LICENSE.TXT for details. vim: expandtab sw=4 ts=4 sts=4: **********************************************************************/ require 'client.inc.php'; require_once INCLUDE_DIR . 'class.file.php'; //Basic checks if (!$_GET['key'] || !$_GET['signature'] || !$_GET['expires'] || !($file = AttachmentFile::lookup($_GET['key']))) { Http::response(404, __('Unknown or invalid file')); } // Validate session access hash - we want to make sure the link is FRESH! // and the user has access to the parent ticket!! if ($file->verifySignature($_GET['signature'], $_GET['expires'])) { if (($s = @$_GET['s']) && strpos($file->getType(), 'image/') === 0) { return $file->display($s); } // Download the file.. $file->download(@$_GET['disposition'] ?: false, $_GET['expires']); } // else Http::response(404, __('Unknown or invalid file'));
data-signature="<?php echo Format::htmlchars(Format::viewableImages($signature)); ?>" data-signature-field="signature" data-dept-field="deptId" placeholder="Intial response for the ticket" name="response" id="response" cols="21" rows="8" style="width:80%;"><?php echo $info['response']; ?></textarea> <table border="0" cellspacing="0" cellpadding="2" width="100%"> <?php if($cfg->allowAttachments()) { ?> <tr><td width="100" valign="top">Attachments:</td> <td> <div class="canned_attachments"> <?php if($info['cannedattachments']) { foreach($info['cannedattachments'] as $k=>$id) { if(!($file=AttachmentFile::lookup($id))) continue; $hash=$file->getKey().md5($file->getId().session_id().$file->getKey()); echo sprintf('<label><input type="checkbox" name="cannedattachments[]" id="f%d" value="%d" checked="checked" <a href="file.php?h=%s">%s</a> </label> ', $file->getId(), $file->getId() , $hash, $file->getName()); } } ?> </div> <div class="uploads"></div> <div class="file_input"> <input type="file" class="multifile" name="attachments[]" size="30" value="" /> </div> </td> </tr>
function updatePagesSettings($vars, &$errors) { global $ost; $f = array(); $f['landing_page_id'] = array('type' => 'int', 'required' => 1, 'error' => 'required'); $f['offline_page_id'] = array('type' => 'int', 'required' => 1, 'error' => 'required'); $f['thank-you_page_id'] = array('type' => 'int', 'required' => 1, 'error' => 'required'); if ($_FILES['logo']) { $error = false; list($logo) = AttachmentFile::format($_FILES['logo']); if (!$logo) { } elseif ($logo['error']) { $errors['logo'] = $logo['error']; } elseif (!($id = AttachmentFile::uploadLogo($logo, $error))) { $errors['logo'] = sprintf(__('Unable to upload logo image: %s'), $error); } } $company = $ost->company; $company_form = $company->getForm(); $company_form->setSource($_POST); if (!$company_form->isValid()) { $errors += $company_form->errors(); } if (!Validator::process($f, $vars, $errors) || $errors) { return false; } $company_form->save(); if (isset($vars['delete-logo'])) { foreach ($vars['delete-logo'] as $id) { if ($vars['selected-logo'] != $id && ($f = AttachmentFile::lookup($id))) { $f->delete(); } } } return $this->updateAll(array('landing_page_id' => $vars['landing_page_id'], 'offline_page_id' => $vars['offline_page_id'], 'thank-you_page_id' => $vars['thank-you_page_id'], 'client_logo_id' => is_numeric($vars['selected-logo']) && $vars['selected-logo'] ? $vars['selected-logo'] : false, 'staff_logo_id' => is_numeric($vars['selected-logo-scp']) && $vars['selected-logo-scp'] ? $vars['selected-logo-scp'] : false)); }
name="response" id="response" cols="21" rows="8" style="width:80%;"><?php echo $info['response']; ?> </textarea> <table border="0" cellspacing="0" cellpadding="2" width="100%"> <?php if ($cfg->allowAttachments()) { ?> <tr><td width="100" valign="top">Attachments:</td> <td> <div class="canned_attachments"> <?php if ($info['cannedattachments']) { foreach ($info['cannedattachments'] as $k => $id) { if (!($file = AttachmentFile::lookup($id))) { continue; } $hash = $file->getKey() . md5($file->getId() . session_id() . $file->getKey()); echo sprintf('<label><input type="checkbox" name="cannedattachments[]" id="f%d" value="%d" checked="checked" <a href="file.php?h=%s">%s</a> </label> ', $file->getId(), $file->getId(), $hash, $file->getName()); } } ?> </div> <div class="uploads"></div> <div class="file_input"> <input type="file" class="multifile" name="attachments[]" size="30" value="" /> </div> </td>
function getFileList() { global $thisstaff; if (!$thisstaff) { Http::response(403, "Login required for file queries"); } $sql = 'SELECT distinct f.id, COALESCE(a.type, f.ft) FROM ' . FILE_TABLE . ' f LEFT JOIN ' . ATTACHMENT_TABLE . ' a ON (a.file_id = f.id) WHERE (a.`type` IN (\'C\', \'F\', \'T\', \'P\') OR f.ft = \'L\') AND f.`type` LIKE \'image/%\''; if (!($res = db_query($sql))) { Http::response(500, 'Unable to lookup files'); } $files = array(); $folders = array('C' => __('Canned Responses'), 'F' => __('FAQ Articles'), 'T' => __('Email Templates'), 'L' => __('Logos'), 'P' => __('Pages')); while (list($id, $type) = db_fetch_row($res)) { $f = AttachmentFile::lookup($id); $url = $f->getDownloadUrl(); $files[] = array('thumb' => $url . '&s=128', 'image' => $url, 'title' => $f->getName(), 'folder' => $folders[$type]); } echo JsonDataEncoder::encode($files); }
function run($args, $options) { Bootstrap::connect(); osTicket::start(); switch ($args['action']) { case 'backends': // List configured backends foreach (FileStorageBackend::allRegistered() as $char => $bk) { print "{$char} -- {$bk::$desc} ({$bk})\n"; } break; case 'list': // List files matching criteria // ORM would be nice! $files = FileModel::objects(); $this->_applyCriteria($options, $files); foreach ($files as $f) { printf("% 5d %s % 8d %s % 16s %s\n", $f->id, $f->bk, $f->size, $f->created, $f->type, $f->name); if ($f->attrs) { printf(" %s\n", $f->attrs); } } break; case 'dump': $files = FileModel::objects(); $this->_applyCriteria($options, $files); if ($files->count() != 1) { $this->fail('Criteria must select exactly 1 file'); } if (($f = AttachmentFile::lookup($files[0]->id)) && ($bk = $f->open())) { $bk->passthru(); } break; case 'load': // Load file content from STDIN $files = FileModel::objects(); $this->_applyCriteria($options, $files); if ($files->count() != 1) { $this->fail('Criteria must select exactly 1 file'); } $f = AttachmentFile::lookup($files[0]->id); try { if ($bk = $f->open()) { $bk->unlink(); } } catch (Exception $e) { } if ($options['to']) { $bk = FileStorageBackend::lookup($options['to'], $f); } else { // Use the system default $bk = AttachmentFile::getBackendForFile($f); } $type = false; $signature = ''; $finfo = new finfo(FILEINFO_MIME_TYPE); if ($options['file'] && $options['file'] != '-') { if (!file_exists($options['file'])) { $this->fail($options['file'] . ': Cannot open file'); } if (!$bk->upload($options['file'])) { $this->fail('Unable to upload file contents to backend'); } $type = $finfo->file($options['file']); list(, $signature) = AttachmentFile::_getKeyAndHash($options['file'], true); } else { $stream = fopen('php://stdin', 'rb'); while ($block = fread($stream, $bk->getBlockSize())) { if (!$bk->write($block)) { $this->fail('Unable to send file contents to backend'); } if (!$type) { $type = $finfo->buffer($block); } } if (!$bk->flush()) { $this->fail('Unable to commit file contents to backend'); } } // TODO: Update file metadata $sql = 'UPDATE ' . FILE_TABLE . ' SET bk=' . db_input($bk->getBkChar()) . ', created=CURRENT_TIMESTAMP' . ', type=' . db_input($type) . ', signature=' . db_input($signature) . ' WHERE id=' . db_input($f->getId()); if (!db_query($sql) || db_affected_rows() != 1) { $this->fail('Unable to update file metadata'); } $this->stdout->write("Successfully saved contents\n"); break; case 'migrate': if (!$options['to']) { $this->fail('Please specify a target backend for migration'); } if (!FileStorageBackend::isRegistered($options['to'])) { $this->fail('Target backend is not installed. See `backends` action'); } $files = FileModel::objects(); $this->_applyCriteria($options, $files); $count = 0; foreach ($files as $m) { $f = AttachmentFile::lookup($m->id); if ($f->getBackend() == $options['to']) { continue; } if ($options['verbose']) { $this->stdout->write('Migrating ' . $m->name . "\n"); } try { if (!$f->migrate($options['to'])) { $this->stderr->write('Unable to migrate ' . $m->name . "\n"); } else { $count++; } } catch (IOException $e) { $this->stderr->write('IOError: ' . $e->getMessage()); } } $this->stdout->write("Migrated {$count} files\n"); break; case 'export': // Create a temporary ZIP file $files = FileModel::objects(); $this->_applyCriteria($options, $files); if (!$options['file']) { $this->fail('Please specify zip file with `-f`'); } $zip = new ZipArchive(); if (true !== ($reason = $zip->open($options['file'], ZipArchive::CREATE))) { $this->fail($reason . ': Unable to create zip file'); } $manifest = array(); foreach ($files as $m) { $f = AttachmentFile::lookup($m->id); $zip->addFromString($f->getId(), $f->getData()); $zip->setCommentName($f->getId(), $f->getName()); // TODO: Log %attachment and %ticket_attachment entries $info = array('file' => $f->getInfo()); foreach ($m->tickets as $t) { $info['tickets'][] = $t->ht; } $manifest[$f->getId()] = $info; } $zip->addFromString('MANIFEST', serialize($manifest)); $zip->close(); break; case 'expunge': // Create a temporary ZIP file $files = FileModel::objects(); $this->_applyCriteria($options, $files); foreach ($files as $f) { $f->tickets->expunge(); $f->unlink() && $f->delete(); } } }
function deleteAttachment($fileId) { $sql = 'DELETE FROM ' . FAQ_ATTACHMENT_TABLE . ' WHERE faq_id=' . db_input($this->getId()) . ' AND file_id=' . db_input($fileId) . ' LIMIT 1'; if (!db_query($sql) || !db_affected_rows()) { return false; } if (($file = AttachmentFile::lookup($fileId)) && !$file->isInuse()) { $file->delete(); } return true; }
function send($to, $subject, $message, $options = null) { global $ost, $cfg; //Get the goodies require_once PEAR_DIR . 'Mail.php'; // PEAR Mail package require_once PEAR_DIR . 'Mail/mime.php'; // PEAR Mail_Mime packge //do some cleanup $to = preg_replace("/(\r\n|\r|\n)/s", '', trim($to)); $subject = preg_replace("/(\r\n|\r|\n)/s", '', trim($subject)); /* Message ID - generated for each outgoing email */ $messageId = sprintf('<%s-%s-%s>', substr(md5('mail' . SECRET_SALT), -9), Misc::randCode(9), $this->getEmail() ? $this->getEmail()->getEmail() : '@osTicketMailer'); $headers = array('From' => $this->getFromAddress(), 'To' => $to, 'Subject' => $subject, 'Date' => date('D, d M Y H:i:s O'), 'Message-ID' => $messageId, 'X-Mailer' => 'osTicket Mailer'); // Add in the options passed to the constructor $options = ($options ?: array()) + $this->options; if (isset($options['nobounce']) && $options['nobounce']) { $headers['Return-Path'] = '<>'; } elseif ($this->getEmail() instanceof Email) { $headers['Return-Path'] = $this->getEmail()->getEmail(); } //Bulk. if (isset($options['bulk']) && $options['bulk']) { $headers += array('Precedence' => 'bulk'); } //Auto-reply - mark as autoreply and supress all auto-replies if (isset($options['autoreply']) && $options['autoreply']) { $headers += array('Precedence' => 'auto_reply', 'X-Autoreply' => 'yes', 'X-Auto-Response-Suppress' => 'DR, RN, OOF, AutoReply', 'Auto-Submitted' => 'auto-replied'); } //Notice (sort of automated - but we don't want auto-replies back if (isset($options['notice']) && $options['notice']) { $headers += array('X-Auto-Response-Suppress' => 'OOF, AutoReply', 'Auto-Submitted' => 'auto-generated'); } if ($options) { if (isset($options['inreplyto']) && $options['inreplyto']) { $headers += array('In-Reply-To' => $options['inreplyto']); } if (isset($options['references']) && $options['references']) { if (is_array($options['references'])) { $headers += array('References' => implode(' ', $options['references'])); } else { $headers += array('References' => $options['references']); } } } // The Suhosin patch will muck up the line endings in some // cases // // References: // https://github.com/osTicket/osTicket-1.8/issues/202 // http://pear.php.net/bugs/bug.php?id=12032 // http://us2.php.net/manual/en/function.mail.php#97680 if ((extension_loaded('suhosin') || defined("SUHOSIN_PATCH")) && !$this->getSMTPInfo()) { $mime = new Mail_mime("\n"); } else { // Use defaults $mime = new Mail_mime(); } // If the message is not explicitly declared to be a text message, // then assume that it needs html processing to create a valid text // body $isHtml = true; $mid_token = isset($options['thread']) ? $options['thread']->asMessageId($to) : ''; if (!(isset($options['text']) && $options['text'])) { if ($cfg && $cfg->stripQuotedReply() && ($tag = $cfg->getReplySeparator()) && (!isset($options['reply-tag']) || $options['reply-tag'])) { $message = "<div style=\"display:none\"\n data-mid=\"{$mid_token}\">{$tag}<br/><br/></div>{$message}"; } $txtbody = rtrim(Format::html2text($message, 90, false)) . ($mid_token ? "\nRef-Mid: {$mid_token}\n" : ''); $mime->setTXTBody($txtbody); } else { $mime->setTXTBody($message); $isHtml = false; } if ($isHtml && $cfg && $cfg->isHtmlThreadEnabled()) { // Pick a domain compatible with pear Mail_Mime $matches = array(); if (preg_match('#(@[0-9a-zA-Z\\-\\.]+)#', $this->getFromAddress(), $matches)) { $domain = $matches[1]; } else { $domain = '@localhost'; } // Format content-ids with the domain, and add the inline images // to the email attachment list $self = $this; $message = preg_replace_callback('/cid:([\\w.-]{32})/', function ($match) use($domain, $mime, $self) { if (!($file = AttachmentFile::lookup($match[1]))) { return $match[0]; } $mime->addHTMLImage($file->getData(), $file->getType(), $file->getName(), false, $match[1] . $domain); // Don't re-attach the image below unset($self->attachments[$file->getId()]); return $match[0] . $domain; }, $message); // Add an HTML body $mime->setHTMLBody($message); } //XXX: Attachments if ($attachments = $this->getAttachments()) { foreach ($attachments as $attachment) { if ($attachment['file_id'] && ($file = AttachmentFile::lookup($attachment['file_id']))) { $mime->addAttachment($file->getData(), $file->getType(), $file->getName(), false); } } } //Desired encodings... $encodings = array('head_encoding' => 'quoted-printable', 'text_encoding' => 'base64', 'html_encoding' => 'base64', 'html_charset' => 'utf-8', 'text_charset' => 'utf-8', 'head_charset' => 'utf-8'); //encode the body $body = $mime->get($encodings); //encode the headers. $headers = $mime->headers($headers, true); // Cache smtp connections made during this request static $smtp_connections = array(); if ($smtp = $this->getSMTPInfo()) { //Send via SMTP $key = sprintf("%s:%s:%s", $smtp['host'], $smtp['port'], $smtp['username']); if (!isset($smtp_connections[$key])) { $mail = mail::factory('smtp', array('host' => $smtp['host'], 'port' => $smtp['port'], 'auth' => $smtp['auth'], 'username' => $smtp['username'], 'password' => $smtp['password'], 'timeout' => 20, 'debug' => false, 'persist' => true)); if ($mail->connect()) { $smtp_connections[$key] = $mail; } } else { // Use persistent connection $mail = $smtp_connections[$key]; } $result = $mail->send($to, $headers, $body); if (!PEAR::isError($result)) { return $messageId; } // Force reconnect on next ->send() unset($smtp_connections[$key]); $alert = sprintf("Unable to email via SMTP:%s:%d [%s]\n\n%s\n", $smtp['host'], $smtp['port'], $smtp['username'], $result->getMessage()); $this->logError($alert); } //No SMTP or it failed....use php's native mail function. $mail = mail::factory('mail'); return PEAR::isError($mail->send($to, $headers, $body)) ? false : $messageId; }
function WriteHtml() { static $filenumber = 1; $args = func_get_args(); $text =& $args[0]; $self = $this; $text = preg_replace_callback('/cid:([\\w.-]{32})/', function ($match) use($self, &$filenumber) { if (!($file = AttachmentFile::lookup($match[1]))) { return $match[0]; } $key = "__attached_file_" . $filenumber++; $self->{$key} = $file->getData(); return 'var:' . $key; }, $text); call_user_func_array(array('parent', 'WriteHtml'), $args); }
function pdfExport($psize = 'Letter', $notes = false, $printAttachments) { global $thisstaff; require_once INCLUDE_DIR . 'class.pdf.php'; if (!is_string($psize)) { if ($_SESSION['PAPER_SIZE']) { $psize = $_SESSION['PAPER_SIZE']; } elseif (!$thisstaff || !($psize = $thisstaff->getDefaultPaperSize())) { $psize = 'Letter'; } } $pdfConverterPath = INCLUDE_DIR . 'pdfConverter/'; $cmd = " find " . $pdfConverterPath . ' -type f -delete'; shell_exec($cmd); $name = 'Ticket.pdf'; $pdf = new Ticket2PDF($this, $psize, $notes); $pdf->Output($pdfConverterPath . $name, 'F'); $cmd = "chmod -R 777 " . $pdfConverterPath . $name; shell_exec($cmd); $pdf = new mPDF('c'); $pdf->allow_charset_conversion = true; // Set by default to TRUE $pdf->charset_in = 'windows-1252'; $pdf->SetImportUse(); $this->importPdfPages($pdf, $pdfConverterPath . $name); $attachmentOrder = 1; foreach ($printAttachments as $attachmentId) { if (!($f = AttachmentFile::lookup(intval($attachmentId)))) { break; } // $this->logErrors($f->getDownloadUrl()); // $this->logErrors("http://mailtest.spitzeco.dk/".$f->getDownloadUrl()); if ($fileData = $f->getData()) { // $this->logErrors(json_encode($file['data'])); $timestamp = date("Y-m-d_H"); $extension = pathinfo($f->getName(), PATHINFO_EXTENSION); // $this->logErrors("fileName ".$f->getName()); $stringName = preg_replace('/\\s+/', '', $f->getName()); // $tempName = $timestamp.basename($stringName, '.'.$extension); // give the file a temp name in case the file name contians some blank space and then the command would take effect $tempName = "tempFile" . $attachmentOrder; file_put_contents($pdfConverterPath . $tempName . "." . $extension, $fileData); $originalFileName = $pdfConverterPath . $tempName . "." . $extension; $formattedFile = $tempName . "formatted.pdf"; $cmd = "chmod -R 777 " . $pdfConverterPath . $tempName . "." . $extension; shell_exec($cmd); // this is a command for changing other format to pdf $cmd = 'export HOME=/tmp && /usr/bin/libreoffice5.0 --headless --convert-to pdf --outdir ' . $pdfConverterPath . " " . $pdfConverterPath . $tempName . "." . $extension; // $this->logErrors("2222222 ".$cmd); system($cmd); $cmd = "chmod -R 777 " . $pdfConverterPath . $tempName . ".pdf"; shell_exec($cmd); // this command is for making unformatted files become formatted $cmd = 'gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=' . $pdfConverterPath . $formattedFile . ' ' . $pdfConverterPath . $tempName . ".pdf"; shell_exec($cmd); $cmd = "chmod -R 777 " . $pdfConverterPath . $formattedFile; shell_exec($cmd); try { $this->importPdfPages($pdf, $pdfConverterPath . $formattedFile); $cmd = "chmod -R 777 " . $pdfConverterPath . $tempName . ".pdf"; shell_exec($cmd); } catch (Exception $e) { logErrors('Caught exception: ', $e->getMessage(), "\n"); break; } $attachmentOrder = $attachmentOrder + 1; } } $name = 'Ticket-' . $this->getNumber() . '.pdf'; $pdf->Output($name, 'I'); //Remember what the user selected - for autoselect on the next print. $_SESSION['PAPER_SIZE'] = $psize; exit; }
function allLogos() { $sql = 'SELECT id FROM ' . FILE_TABLE . ' WHERE ft="L" ORDER BY created'; $logos = array(); $res = db_query($sql); while (list($id) = db_fetch_row($res)) { $logos[] = AttachmentFile::lookup($id); } return $logos; }
<?php /********************************************************************* image.php Simply downloads the file...on hash validation as follows; * Hash must be 64 chars long. * First 32 chars is the perm. file hash * Next 32 chars is md5(file_id.session_id().file_hash) Peter Rotich <*****@*****.**> Copyright (c) 2006-2013 osTicket http://www.osticket.com Released under the GNU General Public License WITHOUT ANY WARRANTY. See LICENSE.TXT for details. vim: expandtab sw=4 ts=4 sts=4: **********************************************************************/ require 'staff.inc.php'; require_once INCLUDE_DIR . 'class.file.php'; $h = trim($_GET['h']); //basic checks if (!$h || strlen($h) != 64 || !($file = AttachmentFile::lookup(substr($h, 0, 32))) || strcasecmp($h, $file->getDownloadHash())) { //next 32 is file id + session hash. die('Unknown or invalid file. #' . Format::htmlchars($_GET['h'])); } $file->display();
<?php /********************************************************************* file.php Simply downloads the file...on hash validation as follows; * Hash must be 64 chars long. * First 32 chars is the perm. file hash * Next 32 chars is md5(file_id.session_id().file_hash) Peter Rotich <*****@*****.**> Copyright (c) 2006-2013 osTicket http://www.osticket.com Released under the GNU General Public License WITHOUT ANY WARRANTY. See LICENSE.TXT for details. vim: expandtab sw=4 ts=4 sts=4: **********************************************************************/ require('staff.inc.php'); require_once(INCLUDE_DIR.'class.file.php'); $h=trim($_GET['h']); //basic checks if(!$h || strlen($h)!=64 //32*2 || !($file=AttachmentFile::lookup(substr($h,0,32))) //first 32 is the file hash. || strcasecmp($file->getDownloadHash(), $h)) //next 32 is file id + session hash. Http::response(404, __('Unknown or invalid file')); $file->download(); ?>
function send($to, $subject, $message, $options = null) { global $ost; //Get the goodies require_once PEAR_DIR . 'Mail.php'; // PEAR Mail package require_once PEAR_DIR . 'Mail/mime.php'; // PEAR Mail_Mime packge //do some cleanup $to = preg_replace("/(\r\n|\r|\n)/s", '', trim($to)); $subject = stripslashes(preg_replace("/(\r\n|\r|\n)/s", '', trim($subject))); $body = stripslashes(preg_replace("/(\r\n|\r)/s", "\n", trim($message))); /* Message ID - generated for each outgoing email */ $messageId = sprintf('<%s%d-%s>', Misc::randCode(6), time(), $this->getEmail() ? $this->getEmail()->getEmail() : '@osTicketMailer'); $headers = array('From' => $this->getFromAddress(), 'To' => $to, 'Subject' => $subject, 'Date' => date('D, d M Y H:i:s O'), 'Message-ID' => $messageId, 'X-Mailer' => 'osTicket Mailer', 'Content-Type' => 'text/html; charset="UTF-8"'); $mime = new Mail_mime(); $mime->setTXTBody($body); //XXX: Attachments if ($attachments = $this->getAttachments()) { foreach ($attachments as $attachment) { if ($attachment['file_id'] && ($file = AttachmentFile::lookup($attachment['file_id']))) { $mime->addAttachment($file->getData(), $file->getType(), $file->getName(), false); } elseif ($attachment['file'] && file_exists($attachment['file']) && is_readable($attachment['file'])) { $mime->addAttachment($attachment['file'], $attachment['type'], $attachment['name']); } } } //Desired encodings... $encodings = array('head_encoding' => 'quoted-printable', 'text_encoding' => 'quoted-printable', 'html_encoding' => 'base64', 'html_charset' => 'utf-8', 'text_charset' => 'utf-8', 'head_charset' => 'utf-8'); //encode the body $body = $mime->get($encodings); //encode the headers. $headers = $mime->headers($headers); if ($smtp = $this->getSMTPInfo()) { //Send via SMTP $mail = mail::factory('smtp', array('host' => $smtp['host'], 'port' => $smtp['port'], 'auth' => $smtp['auth'], 'username' => $smtp['username'], 'password' => $smtp['password'], 'timeout' => 20, 'debug' => false)); $result = $mail->send($to, $headers, $body); if (!PEAR::isError($result)) { return $messageId; } $alert = sprintf("Unable to email via SMTP:%s:%d [%s]\n\n%s\n", $smtp['host'], $smtp['port'], $smtp['username'], $result->getMessage()); $this->logError($alert); } //No SMTP or it failed....use php's native mail function. $mail = mail::factory('mail'); return PEAR::isError($mail->send($to, $headers, $body)) ? false : $messageId; }
function run($args, $options) { Bootstrap::connect(); osTicket::start(); switch ($args['action']) { case 'backends': // List configured backends foreach (FileStorageBackend::allRegistered() as $char => $bk) { print "{$char} -- {$bk::$desc} ({$bk})\n"; } break; case 'list': // List files matching criteria // ORM would be nice! $files = FileModel::objects(); $this->_applyCriteria($options, $files); foreach ($files as $f) { printf("% 5d %s % 8d %s % 16s %s\n", $f->id, $f->bk, $f->size, $f->created, $f->type, $f->name); if ($f->attrs) { printf(" %s\n", $f->attrs); } } break; case 'dump': $files = FileModel::objects(); $this->_applyCriteria($options, $files); if ($files->count() != 1) { $this->fail('Criteria must select exactly 1 file'); } if (($f = AttachmentFile::lookup($files[0]->id)) && ($bk = $f->open())) { $bk->passthru(); } break; case 'load': // Load file content from STDIN $files = FileModel::objects(); $this->_applyCriteria($options, $files); if ($files->count() != 1) { $this->fail('Criteria must select exactly 1 file'); } $f = AttachmentFile::lookup($files[0]->id); try { if ($bk = $f->open()) { $bk->unlink(); } } catch (Exception $e) { } if ($options['to']) { $bk = FileStorageBackend::lookup($options['to'], $f); } else { // Use the system default $bk = AttachmentFile::getBackendForFile($f); } $type = false; $signature = ''; $finfo = new finfo(FILEINFO_MIME_TYPE); if ($options['file'] && $options['file'] != '-') { if (!file_exists($options['file'])) { $this->fail($options['file'] . ': Cannot open file'); } if (!$bk->upload($options['file'])) { $this->fail('Unable to upload file contents to backend'); } $type = $finfo->file($options['file']); list(, $signature) = AttachmentFile::_getKeyAndHash($options['file'], true); } else { $stream = fopen('php://stdin', 'rb'); while ($block = fread($stream, $bk->getBlockSize())) { if (!$bk->write($block)) { $this->fail('Unable to send file contents to backend'); } if (!$type) { $type = $finfo->buffer($block); } } if (!$bk->flush()) { $this->fail('Unable to commit file contents to backend'); } } // TODO: Update file metadata $sql = 'UPDATE ' . FILE_TABLE . ' SET bk=' . db_input($bk->getBkChar()) . ', created=CURRENT_TIMESTAMP' . ', type=' . db_input($type) . ', signature=' . db_input($signature) . ' WHERE id=' . db_input($f->getId()); if (!db_query($sql) || db_affected_rows() != 1) { $this->fail('Unable to update file metadata'); } $this->stdout->write("Successfully saved contents\n"); break; case 'migrate': if (!$options['to']) { $this->fail('Please specify a target backend for migration'); } if (!FileStorageBackend::isRegistered($options['to'])) { $this->fail('Target backend is not installed. See `backends` action'); } $files = FileModel::objects(); $this->_applyCriteria($options, $files); $count = 0; foreach ($files as $m) { $f = AttachmentFile::lookup($m->id); if ($f->getBackend() == $options['to']) { continue; } if ($options['verbose']) { $this->stdout->write('Migrating ' . $m->name . "\n"); } try { if (!$f->migrate($options['to'])) { $this->stderr->write('Unable to migrate ' . $m->name . "\n"); } else { $count++; } } catch (IOException $e) { $this->stderr->write('IOError: ' . $e->getMessage()); } } $this->stdout->write("Migrated {$count} files\n"); break; /** * export * * Export file contents to a stream file. The format of the stream * will be a continuous stream of file information in the following * format: * * AFIL<meta-length><data-length><meta><data>EOF\x1c * * Where * A is the version code of the export * "FIL" is the literal text 'FIL' * meta-length is 'V' packed header length (bytes) * data-length is 'V' packed data length (bytes) * meta is the %file record, php serialized * data is the raw content of the file * "EOF" is the literal text 'EOF' * \x1c is an ASCII 0x1c byte (file separator) * * Options: * --file File to which to direct the stream output, default * is stdout */ /** * export * * Export file contents to a stream file. The format of the stream * will be a continuous stream of file information in the following * format: * * AFIL<meta-length><data-length><meta><data>EOF\x1c * * Where * A is the version code of the export * "FIL" is the literal text 'FIL' * meta-length is 'V' packed header length (bytes) * data-length is 'V' packed data length (bytes) * meta is the %file record, php serialized * data is the raw content of the file * "EOF" is the literal text 'EOF' * \x1c is an ASCII 0x1c byte (file separator) * * Options: * --file File to which to direct the stream output, default * is stdout */ case 'export': $files = FileModel::objects(); $this->_applyCriteria($options, $files); if (!$options['file'] || $options['file'] == '-') { $options['file'] = 'php://stdout'; } if (!($stream = fopen($options['file'], 'wb'))) { $this->fail($options['file'] . ': Unable to open file for export stream'); } foreach ($files as $m) { $f = AttachmentFile::lookup($m->id); if ($options['verbose']) { $this->stderr->write($m->name . "\n"); } // TODO: Log %attachment and %ticket_attachment entries $info = array('file' => $f->getInfo()); $header = serialize($info); fwrite($stream, 'AFIL' . pack('VV', strlen($header), $f->getSize())); fwrite($stream, $header); $FS = $f->open(); while ($block = $FS->read()) { fwrite($stream, $block); } fwrite($stream, "EOF"); } fclose($stream); break; /** * import * * Import a collection of file contents exported by the `export`. * See the export function above for details about the stream * format. * * Options: * --file File from which to read the export stream, default * is stdin * --to Backend to receive the contents (@see `backends`) * --verbose Show file names while importing */ /** * import * * Import a collection of file contents exported by the `export`. * See the export function above for details about the stream * format. * * Options: * --file File from which to read the export stream, default * is stdin * --to Backend to receive the contents (@see `backends`) * --verbose Show file names while importing */ case 'import': if (!$options['file'] || $options['file'] == '-') { $options['file'] = 'php://stdin'; } if (!($stream = fopen($options['file'], 'rb'))) { $this->fail($options['file'] . ': Unable to open import stream'); } while (true) { // Read the file header // struct file_data_header { // char[4] marker; // Four chars, 'AFIL' // int lenMeta; // int lenData; // }; if (!($header = fread($stream, 12))) { break; } // EOF list(, $mark, $hlen, $dlen) = unpack('V3', $header); // AFIL written as little-endian 4-byte int is 0x4c4946xx (LIFA), // where 'A' is the version code of the export $version = $mark & 0xff; if ($mark >> 8 != 0x4c4946) { $this->fail('Bad file record'); } // Read the header $header = fread($stream, $hlen); if (strlen($header) != $hlen) { $this->fail('Short read getting header info'); } $header = unserialize($header); if (!$header) { $this->fail('Unable to decipher file header'); } // Find or create the file record $finfo = $header['file']; // TODO: Consider the $version code $f = AttachmentFile::lookup($finfo['id']); if ($f) { // Verify file information if ($f->getSize() != $finfo['size'] || $f->getSignature() != $finfo['signature']) { $this->fail(sprintf('%s: File data does not match existing file record', $finfo['name'])); } // Drop existing file contents, if any try { if ($bk = $f->open()) { $bk->unlink(); } } catch (Exception $e) { } } else { $fm = FileModel::create($finfo); if (!$fm->save() || !($f = AttachmentFile::lookup($fm->id))) { $this->fail(sprintf('%s: Unable to create new file record', $finfo['name'])); } } // Determine the backend to recieve the file contents if ($options['to']) { $bk = FileStorageBackend::lookup($options['to'], $f); } else { $bk = AttachmentFile::getBackendForFile($f); } if ($options['verbose']) { $this->stdout->write('Importing ' . $f->getName() . "\n"); } // Write file contents to the backend $md5 = hash_init('md5'); $sha1 = hash_init('sha1'); $written = 0; // Handle exceptions by dropping imported file contents and // then returning the error to the error output stream. try { while ($dlen > 0) { $read_size = min($dlen, $bk->getBlockSize()); $contents = ''; // reading from the stream will likely return an amount of // data different from the backend requested block size. Loop // until $read_size bytes are recieved. while ($read_size > 0 && ($block = fread($stream, $read_size))) { $contents .= $block; $read_size -= strlen($block); } if ($read_size != 0) { // short read throw new Exception(sprintf('%s: Some contents are missing from the stream', $f->getName())); } // Calculate MD5 and SHA1 hashes of the file to verify // contents after successfully written to backend if (!$bk->write($contents)) { throw new Exception('Unable to send file contents to backend'); } hash_update($md5, $contents); hash_update($sha1, $contents); $dlen -= strlen($contents); $written += strlen($contents); } // Some backends cannot handle flush() without a // corresponding write() call. if ($written && !$bk->flush()) { throw new Exception('Unable to commit file contents to backend'); } // Check the signature hash if ($finfo['signature']) { $md5 = base64_encode(hash_final($md5, true)); $sha1 = base64_encode(hash_final($sha1, true)); $sig = str_replace(array('=', '+', '/'), array('', '-', '_'), substr($sha1, 0, 16) . substr($md5, 0, 16)); if ($sig != $finfo['signature']) { throw new Exception(sprintf('%s: Signature verification failed', $f->getName())); } } // Update file to record current backend $sql = 'UPDATE ' . FILE_TABLE . ' SET bk=' . db_input($bk->getBkChar()) . ' WHERE id=' . db_input($f->getId()); if (!db_query($sql) || db_affected_rows() != 1) { return false; } } catch (Exception $ex) { if ($bk) { $bk->unlink(); } $this->fail($ex->getMessage()); } // Read file record footer $footer = fread($stream, 4); if (strlen($footer) != 4) { $this->fail('Unable to read file EOF marker'); } list(, $footer) = unpack('N', $footer); // Footer should be EOF\x1c as an int if ($footer != 0x454f461c) { $this->fail('Incorrect file EOF marker'); } } break; case 'zip': // Create a temporary ZIP file $files = FileModel::objects(); $this->_applyCriteria($options, $files); if (!$options['file']) { $this->fail('Please specify zip file with `-f`'); } $zip = new ZipArchive(); if (true !== ($reason = $zip->open($options['file'], ZipArchive::CREATE))) { $this->fail($reason . ': Unable to create zip file'); } foreach ($files as $m) { $f = AttachmentFile::lookup($m->id); if ($options['verbose']) { $this->stderr->write($m->name . "\n"); } $name = Format::encode(sprintf('%d-%s', $f->getId(), $f->getName()), 'utf-8', 'cp437'); $zip->addFromString($name, $f->getData()); } $zip->close(); break; case 'expunge': $files = FileModel::objects(); $this->_applyCriteria($options, $files); foreach ($files as $m) { // Drop associated attachment links $m->tickets->expunge(); $f = AttachmentFile::lookup($m->id); // Drop file contents if ($bk = $f->open()) { $bk->unlink(); } // Drop file record $f->delete(); } } }
function send($to, $subject, $message, $attachments = null, $options = null) { global $cfg; //Get SMTP info IF enabled! $smtp = array(); if ($this->isSMTPEnabled() && ($info = $this->getSMTPInfo())) { //is SMTP enabled for the current email? $smtp = $info; } elseif ($cfg && ($email = $cfg->getDefaultSMTPEmail()) && $email->isSMTPEnabled()) { //What about global SMTP setting? if ($email->allowSpoofing() && ($info = $email->getSMTPInfo())) { //If spoofing is allowed..then continue. $smtp = $info; } elseif ($email->getId() != $this->getId()) { //No spoofing allowed. Send it via the default SMTP email. return $email->send($to, $subject, $message, $attachments, $options); } } //Get the goodies require_once 'Mail.php'; // PEAR Mail package require_once 'Mail/mime.php'; // PEAR Mail_Mime packge //do some cleanup $eol = "\n"; $to = preg_replace("/(\r\n|\r|\n)/s", '', trim($to)); $subject = stripslashes(preg_replace("/(\r\n|\r|\n)/s", '', trim($subject))); $body = stripslashes(preg_replace("/(\r\n|\r)/s", "\n", trim($message))); $fromname = $this->getName(); $from = sprintf('"%s"<%s>', $fromname ? $fromname : $this->getEmail(), $this->getEmail()); $headers = array('From' => $from, 'To' => $to, 'Subject' => $subject, 'Date' => date('D,d M Y H:i:s O'), 'Message-ID' => '<' . Misc::randCode(6) . '' . time() . '-' . $this->getEmail() . '>', 'X-Mailer' => 'osTicket v1.7', 'Content-Type' => 'text/html; charset="UTF-8"'); $mime = new Mail_mime(); $mime->setTXTBody($body); //XXX: Attachments if ($attachments) { foreach ($attachments as $attachment) { if ($attachment['file_id'] && ($file = AttachmentFile::lookup($attachment['file_id']))) { $mime->addAttachment($file->getData(), $file->getType(), $file->getName(), false); } elseif ($attachment['file'] && file_exists($attachment['file']) && is_readable($attachment['file'])) { $mime->addAttachment($attachment['file'], $attachment['type'], $attachment['name']); } } } $options = array('head_encoding' => 'quoted-printable', 'text_encoding' => 'quoted-printable', 'html_encoding' => 'base64', 'html_charset' => 'utf-8', 'text_charset' => 'utf-8'); //encode the body $body = $mime->get($options); //encode the headers. $headers = $mime->headers($headers); if ($smtp) { //Send via SMTP $mail = mail::factory('smtp', array('host' => $smtp['host'], 'port' => $smtp['port'], 'auth' => $smtp['auth'] ? true : false, 'username' => $smtp['username'], 'password' => $smtp['password'], 'timeout' => 20, 'debug' => false)); $result = $mail->send($to, $headers, $body); if (!PEAR::isError($result)) { return true; } $alert = sprintf("Unable to email via %s:%d [%s]\n\n%s\n", $smtp['host'], $smtp['port'], $smtp['username'], $result->getMessage()); Sys::log(LOG_ALERT, 'SMTP Error', $alert, false); //print_r($result); } //No SMTP or it failed....use php's native mail function. $mail = mail::factory('mail'); return PEAR::isError($mail->send($to, $headers, $body)) ? false : true; }
function deleteAttachments() { global $cfg; $deleted = 0; if ($attachments = $this->getAttachments()) { //Clear reference table - XXX: some attachments might be orphaned db_query('DELETE FROM ' . TICKET_ATTACHMENT_TABLE . ' WHERE ticket_id=' . db_input($this->getId())); //Delete file from DB IF NOT inuse. foreach ($attachments as $attachment) { if (($file = AttachmentFile::lookup($attachment['file_id'])) && !$file->isInuse() && $file->delete()) { $deleted++; } } } return $deleted; }
<?php /********************************************************************* file.php Simply downloads the file...on hash validation as follows; * Hash must be 64 chars long. * First 32 chars is the perm. file hash * Next 32 chars is md5(file_id.session_id().file_hash) Peter Rotich <*****@*****.**> Copyright (c) 2006-2013 osTicket http://www.osticket.com Released under the GNU General Public License WITHOUT ANY WARRANTY. See LICENSE.TXT for details. vim: expandtab sw=4 ts=4 sts=4: **********************************************************************/ require 'staff.inc.php'; require_once INCLUDE_DIR . 'class.file.php'; $h = trim($_GET['h']); //basic checks if (!$h || strlen($h) != 64 || !($file = AttachmentFile::lookup(substr($h, 0, 32))) || strcasecmp(substr($h, -32), md5($file->getId() . session_id() . $file->getHash()))) { //next 32 is file id + session hash. die('Unknown or invalid file. #' . Format::htmlchars($_GET['h'])); } $file->download();
function updatePagesSettings($vars, &$errors) { $f = array(); $f['landing_page_id'] = array('type' => 'int', 'required' => 1, 'error' => 'required'); $f['offline_page_id'] = array('type' => 'int', 'required' => 1, 'error' => 'required'); $f['thank-you_page_id'] = array('type' => 'int', 'required' => 1, 'error' => 'required'); if ($_FILES['logo']) { $error = false; list($logo) = AttachmentFile::format($_FILES['logo']); if (!$logo) { } elseif ($logo['error']) { $errors['logo'] = $logo['error']; } elseif (!($id = AttachmentFile::uploadLogo($logo, $error))) { $errors['logo'] = 'Unable to upload logo image. ' . $error; } } if (!Validator::process($f, $vars, $errors) || $errors) { return false; } if (isset($vars['delete-logo'])) { foreach ($vars['delete-logo'] as $id) { if ($vars['selected-logo'] != $id && ($f = AttachmentFile::lookup($id))) { $f->delete(); } } } return $this->updateAll(array('landing_page_id' => $vars['landing_page_id'], 'offline_page_id' => $vars['offline_page_id'], 'thank-you_page_id' => $vars['thank-you_page_id'], 'client_logo_id' => is_numeric($vars['selected-logo']) && $vars['selected-logo'] ? $vars['selected-logo'] : false)); }