[Mimedefang] passing filename data through action_replace_with_url()

Jeremy Mates jmates at sial.org
Thu Jun 5 22:50:01 EDT 2003


The attatched patch (content-disposition.patch) updates mimedefang.pl.in
to allow action_replace_with_url() to optionally save additional data to
a dotfile named after the generated filename.  Using this feature, the
original filename can be written to the dotfile, and then be parsed by a
CGI in order to add a Content-Disposition header field in the outgoing
response to a web client.  For example:

  return action_replace_with_url(
    $entity, "/www/defang", "http://sial.org/stuff",
    ($fname? "\"$fname\"" : "Attachment").
      " (".humanize($size).") relocated:\n\n_URL_",
    $fname  # extra data to save
  );

The example mod_perl module (AddContentDisposition.pm) shows how to add
the filename to the Content-Disposition header, plus security checkes on
the filename to mitigate any filename based attacks against clients that
support the Content-Disposition header (such as the security hazard
known as Internet Explorer).

-------------- next part --------------
Patch before ./configure, as otherwise mimedefang.pl will not have the
proper code below.

--- mimedefang.pl.in.orig       Fri Apr 25 06:16:11 2003
+++ mimedefang.pl.in    Thu Jun  5 19:14:37 2003
@@ -4763,14 +4763,15 @@
 #  base_url -- base URL for retrieving document
 #  msg -- message to replace document with.  The string "_URL_" is
 #         replaced with the actual URL of the part.
+#  cd_data -- optional Content-Disposition filename data to save
 # %RETURNS:
 #  1 on success, 0 on failure
 # %DESCRIPTION:
 #  Places the part in doc_root/{sha1_of_part}.ext and replaces it with
 #  a text/plain part giving the URL for pickup.
 #***********************************************************************
-sub action_replace_with_url ($$$$) {
-    my($entity, $doc_root, $base_url, $msg) = @_;
+sub action_replace_with_url ($$$$;$) {
+    my($entity, $doc_root, $base_url, $msg, $cd_data) = @_;
     my($ctx);
     my($path);
     my($fname, $ext, $name, $url);
@@ -4808,6 +4809,16 @@
        # In case umask is whacked...
        chmod 0644, $fname;
     }
+
+    # save optional Content-Disposition data
+    if ($cd_data) {
+      if (open CDF, ">$doc_root/.$name") {
+        print CDF $cd_data;
+        close CDF;
+        chmod 0644, "$doc_root/.$name";
+      }
+    }
+
     $msg =~ s/_URL_/$url/g;
     action_replace_with_warning($msg);
     return 1;
--- mimedefang-filter.5.in.orig Mon Apr 21 09:17:24 2003
+++ mimedefang-filter.5.in      Thu Jun  5 19:20:13 2003
@@ -861,6 +861,12 @@
 them.  If indexing is disabled, an attacker would have to guess the SHA1
 hash of a part in order to read it.
 
+Optionally, a fifth argument can supply data to be saved into a hidden
+dot filename based on the generated name.  This data can then be read in
+on the fly by a CGI script or mod_perl module before serving the file to
+a web client, and used to add information to the response, such as
+Content-Disposition data.
+
 .TP
 .B action_defang($entity, $name, $fname, $type)
 Accept the part, but change its name to \fI$name\fR, its suggested filename
-------------- next part --------------
# Apache 1.3 mod_perl PerlTypeHandler to add the Content-Disposition
# header to outgoing files from a ".filename" file in the same directory
# containing the real file.  This allows files with names such as
# "341ee566.gif" to have a human-friendly name associated with them.
#
# See RFC 2183 for more information on the Content-Disposition header.
#
# Enable this module with a PerlTypeHandler directive for the
# <Directory> or similar areas in question after installing this file
# under an Apache directory in @INC.
#
# PerlTypeHandler Apache::AddContentDisposition
#
# The author disclaims all copyrights and releases this module into the
# public domain.

package Apache::AddContentDisposition;

use Apache::Constants qw(OK DECLINED);

# to determine the Content-Type of the file
use File::MMagic;

sub handler {
  my $r = shift;

  # /foo/bar file from Apache -> /foo/.bar metafile
  (my $metafile = $r->filename) =~ s,/([^/]+)$,/.$1,;

  # first line of data should contain mime type, tab, then the
  # recommended filename
  open FILE, $metafile or return DECLINED;
  my $filename = <FILE>;
  close FILE;

  return DECLINED unless $filename;

  # sanitize out characters not listed and .. runs to mitigate potential
  # security problems on clients
  $filename =~ s/[^\w.-]//g;
  $filename =~ s/\.\.+//g;

  return DECLINED unless $filename;

  # need to set Content-Type as is set to text/plain once our custom
  # Content-Disposition header is set, which trips up Mozilla
  my $mime_type = File::MMagic->new->checktype_filename($r->filename);
  return DECLINED unless $mime_type;

  $r->content_type($mime_type);
  $r->headers_out->set("Content-Disposition" => "inline; filename=$filename");

  return OK;
}

1;


More information about the MIMEDefang mailing list