From e024f133fae30a5c84973825d99dc82989a79b55 Mon Sep 17 00:00:00 2001 From: PhilW Date: Sun, 4 Nov 2018 08:25:06 +0000 Subject: [PATCH] give all temp files a constant prefix --- plugins/enigma/lib/enigma_driver_phpssl.php | 5 ++- .../filesystem_attachments.php | 7 ++-- plugins/zipdownload/zipdownload.php | 10 +++--- program/include/rcmail.php | 4 +-- program/include/rcmail_resend_mail.php | 3 +- program/include/rcmail_sendmail.php | 3 +- program/lib/Roundcube/bootstrap.php | 1 + program/lib/Roundcube/rcube.php | 5 ++- program/lib/Roundcube/rcube_utils.php | 36 +++++++++++++++++++ program/steps/addressbook/upload_photo.inc | 2 +- program/steps/mail/func.inc | 3 +- program/steps/mail/get.inc | 7 ++-- program/steps/mail/import.inc | 3 +- 13 files changed, 57 insertions(+), 32 deletions(-) diff --git a/plugins/enigma/lib/enigma_driver_phpssl.php b/plugins/enigma/lib/enigma_driver_phpssl.php index e4056c8c0..e0a078461 100644 --- a/plugins/enigma/lib/enigma_driver_phpssl.php +++ b/plugins/enigma/lib/enigma_driver_phpssl.php @@ -82,9 +82,8 @@ class enigma_driver_phpssl extends enigma_driver function verify($struct, $message) { // use common temp dir - $temp_dir = $this->rc->config->get('temp_dir'); - $msg_file = tempnam($temp_dir, 'rcmMsg'); - $cert_file = tempnam($temp_dir, 'rcmCert'); + $msg_file = rcube_utils::temp_filename('enigmsg'); + $cert_file = rcube_utils::temp_filename('enigcrt'); $fh = fopen($msg_file, "w"); if ($struct->mime_id) { diff --git a/plugins/filesystem_attachments/filesystem_attachments.php b/plugins/filesystem_attachments/filesystem_attachments.php index 1f030b50e..9f2940afb 100644 --- a/plugins/filesystem_attachments/filesystem_attachments.php +++ b/plugins/filesystem_attachments/filesystem_attachments.php @@ -60,8 +60,7 @@ class filesystem_attachments extends rcube_plugin $rcmail = rcube::get_instance(); // use common temp dir for file uploads - $temp_dir = $rcmail->config->get('temp_dir'); - $tmpfname = tempnam($temp_dir, 'rcmAttmnt'); + $tmpfname = rcube_utils::temp_filename('attmnt'); if (move_uploaded_file($args['path'], $tmpfname) && file_exists($tmpfname)) { $args['id'] = $this->file_id(); @@ -85,9 +84,7 @@ class filesystem_attachments extends rcube_plugin $args['status'] = false; if (!$args['path']) { - $rcmail = rcube::get_instance(); - $temp_dir = $rcmail->config->get('temp_dir'); - $tmp_path = tempnam($temp_dir, 'rcmAttmnt'); + $tmp_path = rcube_utils::temp_filename('attmnt'); if ($fp = fopen($tmp_path, 'w')) { fwrite($fp, $args['data']); diff --git a/plugins/zipdownload/zipdownload.php b/plugins/zipdownload/zipdownload.php index d6fbefefd..385f257f2 100644 --- a/plugins/zipdownload/zipdownload.php +++ b/plugins/zipdownload/zipdownload.php @@ -134,8 +134,7 @@ class zipdownload extends rcube_plugin $rcmail->request_security_check(rcube_utils::INPUT_GET); $imap = $rcmail->get_storage(); - $temp_dir = $rcmail->config->get('temp_dir'); - $tmpfname = tempnam($temp_dir, 'zipdownload'); + $tmpfname = rcube_utils::temp_filename('zipdownload'); $tempfiles = array($tmpfname); $message = new rcube_message(rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GET)); @@ -148,7 +147,7 @@ class zipdownload extends rcube_plugin $part = $message->mime_parts[$pid]; $disp_name = $this->_create_displayname($part); - $tmpfn = tempnam($temp_dir, 'zipattach'); + $tmpfn = rcube_utils::temp_filename('zipattach'); $tmpfp = fopen($tmpfn, 'w'); $tempfiles[] = $tmpfn; @@ -237,11 +236,10 @@ class zipdownload extends rcube_plugin $rcmail = rcmail::get_instance(); $imap = $rcmail->get_storage(); $mode = rcube_utils::get_input_value('_mode', rcube_utils::INPUT_POST); - $temp_dir = $rcmail->config->get('temp_dir'); $limit = $rcmail->config->get('zipdownload_selection', $this->default_limit); $limit = $limit !== true ? parse_bytes($limit) : -1; $delimiter = $imap->get_hierarchy_delimiter(); - $tmpfname = tempnam($temp_dir, 'zipdownload'); + $tmpfname = rcube_utils::temp_filename('zipdownload'); $tempfiles = array($tmpfname); $folders = count($messageset) > 1; $timezone = new DateTimeZone('UTC'); @@ -331,7 +329,7 @@ class zipdownload extends rcube_plugin fwrite($tmpfp, "\r\n"); } else { // maildir - $tmpfn = tempnam($temp_dir, 'zipmessage'); + $tmpfn = rcube_utils::temp_filename('zipmessage'); $tmpfp = fopen($tmpfn, 'w'); $imap->get_raw_body($uid, $tmpfp); $tempfiles[] = $tmpfn; diff --git a/program/include/rcmail.php b/program/include/rcmail.php index 43fb4a85b..164299725 100644 --- a/program/include/rcmail.php +++ b/program/include/rcmail.php @@ -2235,11 +2235,11 @@ class rcmail extends rcube // generate image thumbnail for file browser in HTML editor if (!empty($_GET['_thumbnail'])) { - $temp_dir = $this->config->get('temp_dir'); $thumbnail_size = 80; $mimetype = $file['mimetype']; $file_ident = $file['id'] . ':' . $file['mimetype'] . ':' . $file['size']; - $cache_basename = $temp_dir . '/' . md5($file_ident . ':' . $this->user->ID . ':' . $thumbnail_size); + $thumb_name = md5($file_ident . ':' . $this->user->ID . ':' . $thumbnail_size) . '.thumb'; + $cache_basename = rcube_utils::temp_filename($thumb_name, false, false); $cache_file = $cache_basename . '.thumb'; // render thumbnail image if not done yet diff --git a/program/include/rcmail_resend_mail.php b/program/include/rcmail_resend_mail.php index 9670e48d6..95b785455 100644 --- a/program/include/rcmail_resend_mail.php +++ b/program/include/rcmail_resend_mail.php @@ -120,8 +120,7 @@ class rcmail_resend_mail extends Mail_mime $rcmail = rcmail::get_instance(); $storage = $rcmail->get_storage(); $message = $this->build_params['bounce_message']; - $temp_dir = unslashify($rcmail->config->get('temp_dir')); - $path = tempnam($temp_dir, 'rcmBounce'); + $path = rcube_utils::temp_filename('bounce'); // We'll write the body to the file and the headers to a variable if ($fp = fopen($path, 'w')) { diff --git a/program/include/rcmail_sendmail.php b/program/include/rcmail_sendmail.php index 03ace3597..d92b1ad21 100644 --- a/program/include/rcmail_sendmail.php +++ b/program/include/rcmail_sendmail.php @@ -469,8 +469,7 @@ class rcmail_sendmail $msg = $message->mailbody_file; } else { - $temp_dir = $this->rcmail->config->get('temp_dir'); - $mailbody_file = tempnam($temp_dir, 'rcmMsg'); + $mailbody_file = rcube_utils::temp_filename('msg'); $msg = $message->saveMessageBody($mailbody_file); if (!is_a($msg, 'PEAR_Error')) { diff --git a/program/lib/Roundcube/bootstrap.php b/program/lib/Roundcube/bootstrap.php index b754a2d58..8868d5747 100644 --- a/program/lib/Roundcube/bootstrap.php +++ b/program/lib/Roundcube/bootstrap.php @@ -59,6 +59,7 @@ foreach ($config as $optname => $optval) { // framework constants define('RCUBE_VERSION', '1.4-git'); define('RCUBE_CHARSET', 'UTF-8'); +define('RCUBE_TEMP_FILE_PREFIX', 'RCMTEMP'); if (!defined('RCUBE_LIB_DIR')) { define('RCUBE_LIB_DIR', __DIR__ . '/'); diff --git a/program/lib/Roundcube/rcube.php b/program/lib/Roundcube/rcube.php index 74ddd82c8..b22f84c1e 100644 --- a/program/lib/Roundcube/rcube.php +++ b/program/lib/Roundcube/rcube.php @@ -523,7 +523,7 @@ class rcube if ($tmp && ($dir = opendir($tmp))) { while (($fname = readdir($dir)) !== false) { - if ($fname[0] == '.') { + if (strpos($fname, RCUBE_TEMP_FILE_PREFIX) !== 0) { continue; } @@ -1652,8 +1652,7 @@ class rcube if ($message->getParam('delay_file_io')) { // use common temp dir - $temp_dir = $this->config->get('temp_dir'); - $body_file = tempnam($temp_dir, 'rcmMsg'); + $body_file = rcube_utils::temp_filename('msg'); $mime_result = $message->saveMessageBody($body_file); if (is_a($mime_result, 'PEAR_Error')) { diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php index 6113f4393..4db93b65c 100644 --- a/program/lib/Roundcube/rcube_utils.php +++ b/program/lib/Roundcube/rcube_utils.php @@ -1388,4 +1388,40 @@ class rcube_utils return false; } + + /** + * Generate a temporary file path in the Roundcube temp directory + * + * @param string $file_name String identifier for the type of temp file + * @param bool $unique Generate unique file names based on $file_name + * @param bool $create Create the temp file or not + * + * @return string temporary file path + */ + public static function temp_filename($file_name, $unique = true, $create = true) + { + $temp_dir = rcube::get_instance()->config->get('temp_dir'); + + // Fall back to system temp dir if configured dir is not writable + if (!is_writable($temp_dir)) { + $temp_dir = sys_get_temp_dir(); + } + + // On Windows tempnam() uses only the first three characters of prefix so use uniqid() and manually add the prefix + // Full prefix is required for garbage collection to recognise the file + $temp_file = $unique ? str_replace('.', '', uniqid($file_name, true)) : $file_name; + $temp_path = unslashify($temp_dir) . '/' . RCUBE_TEMP_FILE_PREFIX . $temp_file; + + // Sanity check for unique file name + if ($unique && file_exists($temp_path)) { + return self::temp_filename($file_name); + } + + // Create the file to prevent possible race condition like tempnam() does + if ($create) { + touch($temp_path); + } + + return $temp_path; + } } diff --git a/program/steps/addressbook/upload_photo.inc b/program/steps/addressbook/upload_photo.inc index 6a5395b91..745c3f1a4 100644 --- a/program/steps/addressbook/upload_photo.inc +++ b/program/steps/addressbook/upload_photo.inc @@ -35,7 +35,7 @@ if ($filepath = $_FILES['_photo']['tmp_name']) { && $imageprop['width'] && $imageprop['height'] ) { $maxsize = intval($RCMAIL->config->get('contact_photo_size', 160)); - $tmpfname = tempnam($RCMAIL->config->get('temp_dir'), 'rcmImgConvert'); + $tmpfname = rcube_utils::temp_filename('imgconvert'); $save_hook = 'attachment_upload'; // scale image to a maximum size diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc index a2fa8242a..26b038401 100644 --- a/program/steps/mail/func.inc +++ b/program/steps/mail/func.inc @@ -1796,8 +1796,7 @@ function rcmail_save_attachment($message, $pid, $compose_id, $params = array()) if (!isset($data)) { // don't load too big attachments into memory if (!rcube_utils::mem_check($size)) { - $temp_dir = unslashify($rcmail->config->get('temp_dir')); - $path = tempnam($temp_dir, 'rcmAttmnt'); + $path = rcube_utils::temp_filename('attmnt'); if ($fp = fopen($path, 'w')) { if ($pid) { diff --git a/program/steps/mail/get.inc b/program/steps/mail/get.inc index 36908cdd3..2ba16e75b 100644 --- a/program/steps/mail/get.inc +++ b/program/steps/mail/get.inc @@ -76,9 +76,9 @@ if (!empty($_GET['_frame'])) { // render thumbnail of an image attachment if (!empty($_GET['_thumb']) && $attachment->is_valid()) { $thumbnail_size = $RCMAIL->config->get('image_thumbnail_size', 240); - $temp_dir = $RCMAIL->config->get('temp_dir'); $file_ident = $attachment->ident; - $cache_basename = $temp_dir . '/' . md5($file_ident . ':' . $RCMAIL->user->ID . ':' . $thumbnail_size); + $thumb_name = md5($file_ident . ':' . $RCMAIL->user->ID . ':' . $thumbnail_size) . '.thumb'; + $cache_basename = rcube_utils::temp_filename($thumb_name, false, false); $cache_file = $cache_basename . '.thumb'; // render thumbnail image if not done yet @@ -261,8 +261,7 @@ if (empty($_GET['_thumb']) && $attachment->is_valid()) { // handle tiff to jpeg conversion if (!empty($convert2jpeg)) { - $temp_dir = unslashify($RCMAIL->config->get('temp_dir')); - $file_path = tempnam($temp_dir, 'rcmAttmnt'); + $file_path = rcube_utils::temp_filename('attmnt'); // convert image to jpeg and send it to the browser if ($attachment->body_to_file($file_path)) { diff --git a/program/steps/mail/import.inc b/program/steps/mail/import.inc index e9c507474..98a62063b 100644 --- a/program/steps/mail/import.inc +++ b/program/steps/mail/import.inc @@ -128,14 +128,13 @@ function rcmail_zip_extract($path) } $rcmail = rcmail::get_instance(); - $temp_dir = $rcmail->config->get('temp_dir'); $zip = new ZipArchive; $files = array(); if ($zip->open($path)) { for ($i = 0; $i < $zip->numFiles; $i++) { $entry = $zip->getNameIndex($i); - $tmpfname = tempnam($temp_dir, 'zipimport'); + $tmpfname = rcube_utils::temp_filename('zipimport'); if (copy("zip://$path#$entry", $tmpfname)) { $ctype = rcube_mime::file_content_type($tmpfname, $entry);