File: attachment.php

package info (click to toggle)
imp4 4.2-4lenny3
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 18,252 kB
  • ctags: 5,316
  • sloc: php: 21,340; xml: 19,302; makefile: 68; sql: 14
file content (144 lines) | stat: -rw-r--r-- 6,542 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<?php
/**
 * $Horde: imp/attachment.php,v 2.5.10.21 2007/12/20 13:59:19 jan Exp $
 *
 * Copyright 2004-2007 Andrew Coleman <mercury@appisolutions.net>
 *
 * See the enclosed file COPYING for license information (GPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
 *
 * This file should be the basis for serving hosted attachments.  It
 * should fetch the file from the VFS and funnel it to the client
 * wishing to download the attachment. This will allow for the
 * exchange of massive attachments without causing mail server havoc.
 */

// Set up initial includes.
// This does *not* include IMP's base.php because we do not need to be
// authenticated to get the file. Most users won't send linked
// attachments just to other IMP users.
if (!defined('HORDE_BASE')) {
    @define('HORDE_BASE', dirname(__FILE__) . '/..');
}
@define('IMP_BASE', dirname(__FILE__));
require_once HORDE_BASE . '/lib/core.php';
require_once 'VFS.php';
require_once 'Horde/MIME/Magic.php';
$registry = &Registry::singleton();
$registry->importConfig('imp');

$_self_url = Horde::selfUrl(false, true, true);

// Lets see if we are even able to send the user an attachment.
if (!$conf['compose']['link_attachments']) {
    Horde::fatal(_("Linked attachments are forbidden."), $_self_url, __LINE__);
}

// Gather required form variables.
$mail_user = Util::getFormData('u');
$time_stamp = Util::getFormData('t');
$file_name = Util::getFormData('f');
if (!isset($mail_user) || !isset($time_stamp) || !isset($file_name) ||
    $mail_user == '' || $time_stamp == '' || $file_name == '') {
    Horde::fatal(_("The attachment was not found."),
        $_self_url, __LINE__);
}

// Initialize the VFS.
$vfsroot = &VFS::singleton($conf['vfs']['type'], Horde::getDriverConfig('vfs', $conf['vfs']['type']));
if (is_a($vfsroot, 'PEAR_Error')) {
    Horde::fatal(sprintf(_("Could not create the VFS backend: %s"), $vfsroot->getMessage()), $_self_url, __LINE__);
}

// Check if the file exists.
$mail_user = basename($mail_user);
$time_stamp = basename($time_stamp);
$file_name = escapeshellcmd(basename($file_name));
$full_path = sprintf('.horde/imp/attachments/%s/%d', $mail_user, $time_stamp);
if (!$vfsroot->exists($full_path, $file_name)) {
    Horde::fatal(_("The specified attachment does not exist. It may have been deleted by the original sender."), $_self_url, __LINE__);
}

// Check to see if we need to send a verification message.
if ($conf['compose']['link_attachments_notify']) {
    if ($vfsroot->exists($full_path, $file_name . '.notify')) {
        $delete_id = Util::getFormData('d');
        $read_id = $vfsroot->read($full_path, $file_name . '.notify');
        if (is_a($read_id, 'PEAR_Error')) {
            Horde::logMessage($read_id, __FILE__, __LINE__, PEAR_LOG_ERR);
        } elseif ($delete_id == $read_id) {
            $vfsroot->deleteFile($full_path, $file_name);
            $vfsroot->deleteFile($full_path, $file_name . '.notify');
            printf(_("Attachment %s deleted."), $file_name);
            exit;
        }
    } else {
        /* Create a random identifier for this file. */
        $id = base_convert($file_name . microtime(), 10, 36);
        $res = $vfsroot->writeData($full_path, $file_name . '.notify' , $id, true);
        if (is_a($res, 'PEAR_Error')) {
            Horde::logMessage($res, __FILE__, __LINE__, PEAR_LOG_ERR);
        } else {
            /* Load $mail_user's preferences so that we can use their
             * locale information for the notification message. */
            include_once 'Horde/Prefs.php';
            $prefs = &Prefs::singleton($conf['prefs']['driver'],
                                       'horde', $mail_user);
            $prefs->retrieve();
            include_once 'Horde/Identity.php';
            $mail_identity = &Identity::singleton('none', $mail_user);
            $mail_address = $mail_identity->getDefaultFromAddress();
            /* Ignore missing addresses, which are returned as <>. */
            if (strlen($mail_address) > 2) {
                $mail_address_full = $mail_identity->getDefaultFromAddress(true);
                NLS::setTimeZone();
                NLS::setLang($prefs->getValue('language'));
                NLS::setTextdomain('imp', IMP_BASE . '/locale', NLS::getCharset());
                String::setDefaultCharset(NLS::getCharset());

                /* Set up the mail headers and read the log file. */
                include_once 'Horde/MIME/Headers.php';
                $msg_headers = new MIME_Headers();
                $msg_headers->addReceivedHeader();
                $msg_headers->addMessageIdHeader();
                $msg_headers->addAgentHeader();
                $msg_headers->addHeader('Date', date('r'));
                $msg_headers->addHeader('From', $mail_address_full);
                $msg_headers->addHeader('To', $mail_address_full);
                $msg_headers->addHeader('Subject', _("Notification: Linked attachment downloaded"));

                include_once 'Horde/MIME/Message.php';
                $msg = new MIME_Message();
                $msg->setType('text/plain');
                $msg->setCharset(NLS::getCharset());
                $msg->setContents(String::wrap(sprintf(_("Your linked attachment has been downloaded by at least one user.\n\nAttachment name: %s\nAttachment date: %s\n\nClick on the following link to permanently delete the attachment:\n%s"), $file_name, date('r', $time_stamp), Util::addParameter(Horde::selfUrl(true, false, true), 'd', $id))));

                $msg_headers->addMIMEHeaders($msg);

                $msg->send($mail_address, $msg_headers);
            }
        }
    }
}

// Find the file's mime-type.
$file_data = $vfsroot->read($full_path, $file_name);
if (is_a($file_data, 'PEAR_Error')) {
    Horde::logMessage($file_data, __FILE__, __LINE__, PEAR_LOG_ERR);
    Horde::fatal(_("The specified file cannot be read."), $_self_url, __LINE__);
}
$mime_type = MIME_Magic::analyzeData($file_data, isset($conf['mime']['magic_db']) ? $conf['mime']['magic_db'] : null);
if ($mime_type === false) {
    $mime_type = MIME_Magic::filenameToMIME($file_name, false);
}

// Prevent 'jar:' attacks on Firefox.  See Ticket #5892.
if ($browser->isBrowser('mozilla')) {
    if (in_array(String::lower($mime_type), array('application/java-archive', 'application/x-jar'))) {
        $mime_type = 'application/octet-stream';
    }
}

// Send the client the file.
$browser->downloadHeaders($file_name, $mime_type, false, strlen($file_data));
echo $file_data;