# pm-jamime.rc -- subroutine to read mime boundary etc. variables # $Id: pm-jamime.rc,v 2.6 2004/08/19 13:47:16 jaalto Exp $ # # File id # # .Copyright (C) 1997-2004 Jari Aalto # .$Keywords: procmail, subroutine, mime $ # # This code is free software in terms of GNU Gen. pub. Lic. v2 or later # Refer to http://www.gnu.org/copyleft/gpl.html # # Documentation # # This includerc reads MIME boundary string from the message # if it exists. The boundary string is typically found from # Content-Type header. # # Mime-Version: 1.0 # Content-Type: multipart/mixed; boundary=9i9nmIyA2yEADZbW # # In addition it will define few other mime variables. See the # returned values. You use these variables later in your MIME # message processing. # # Mime Notes # # 1998-07-28 Brett Glass reported in PM-L that # there was security exploit in long attachment filenames: # http://www.xray.mpe.mpg.de/mailing-lists/procmail/1998-07/msg00248.html # # And here is the url to the matter: # # http://www.sjmercury.com/business/microsoft/docs/security0728.htm # # # When you use this module to detect mime messages, you can check the # filename length with recipe: # # # Recipe after calling $RC_MIME, this module, # # re = ".........." # regexp with 10 matches # too_long = "$re$re$re$re" # allow 40 characters maximum # # :0 # *$ $SUPREME^0 MIME_H_ATTACHMENT ?? $re # *$ $SUPREME^0 MIME_B_ATTACHMENT ?? $re # { # dummy = "** Dangerously long mime attachment filename" # dummy = "** $MIME_H_ATTACHMENT $MIME_B_ATTACHMENT" # # :0 : # /var/spool/mail/MimeDanger # } # # Required settings # # PMSRC must point to source directory of procmail code. This subroutine # will include # # o pm-javar.rc # # Call arguments (variables to set before calling) # # (none) # # Return values # # o Variable MIME is set to "yes" or "no" if messages has mime version # string # o MIME_VER contains the mime version string from the header. # o MIME_TYPE contains the Content-Type from the header. # o MIME_CTE contains Content-Transfer-Encoding from the header. # o MIME_H_QP is "yes" if Content-Transfer-Encoding: quoted-printable # is in the header. # o MIME_B_QP is "yes" if Content-Transfer-Encoding: quoted-printable # is found from the body. # o MIME_BOUNDARY contains the boundary string, which is used to # differentiate mime sections in the body. # o MIME_BOUNDARY_COUNT is the number of boundary strings found # from the body. The value is 3 if there is two mime sections, # and 4 if 3 etc. MIME_BOUNDARY_COUNT -1 = count of sections. # o MIME_H_ATTACHMENT, contains the filename if there was attachement # filename in the header. Content-Disposition: attachment; # filename="..." # o MIME_B_ATTACHMENT. `body' file attachment. Note however that # this is the match of first string in the body. There may be # several attachments. MIME_B_ATTACHMENT_FILE_COUNT tells you # how many filenames are in the body. # # Usage example # # INCLUDERC = $PMSRC/pm-jamime.rc # # Change Log (none) # ............................................................ &code ... dummy = " ======================================================================== pm-jamime.rc: init:" :0 * ! WSPC ?? [ ] { INCLUDERC = $PMSRC/pm-javar.rc } # ..................................................... &output-vars ... # output variables MIME = "no" # set default value MIME_H_QP = "no" MIME_B_QP = "no" MIME_VER MIME_CTE MIME_TYPE MIME_BOUNDARY MIME_BOUNDARY_COUNT # ........................................................... &do-it ... # The WSPC ?? ( ) is there just double checking that we REALLY read # the pm-javar.rc. We must not set any MIME variables if that wasn't # read. :0 * ^Mime-Version: *\/[0-9.]+ * WSPC ?? [ ] { MIME = "yes" MIME_VER = $MATCH :0 * ^Content-Type: +\/.* { MIME_TYPE = $MATCH } :0 *$ ^Content-Transfer-Encoding:$s+\/.* { MIME_CTE = $MATCH :0 * MIME_CTE ?? quoted-printable { MIME_H_QP = "yes" } } :0 *$ B ?? ^Content-Transfer-Encoding:$s+quoted-printable { MIME_B_QP = "yes" } # What is the MIME tag in this message? # # Content-Type: multipart/mixed; # boundary="---- =_NextPart_000_01BD04D4.A5AC6B00" # # Note that in the text, this string may not be excatly like this, # Eg. in my messages there was "--" prepended to the tag. # :0 * boundary *= *\"\/[^\";]+ { MIME_BOUNDARY = $MATCH } # Hm, the boundary string was not surrounded by double quotes. # Search this kind of boundary string then: # # Content-Type: multipart/mixed; boundary=9i9nmIyA2yEADZbW :0 E * boundary *= *\/[^\";]+ { # " Don't mind this, a dummy double quote to help Emacs # to end starting quote below. Otherwise syntax colour # highlighting would go beserk. MIME_BOUNDARY = $MATCH } dummy = "pm-jamime.rc: Do we have the boundary string?" :0 *! MIME_BOUNDARY ?? ^^^^ { # Count how many mime sections there are in the message. # MIME_BOUNDARY_COUNT -1 = count of mime sections. :0 *$ B ?? 1^1 $\MIME_BOUNDARY { } MIME_BOUNDARY_COUNT = $= } # Mime-Version: 1.0 (generated by tm-edit 7.106) # Content-Type: application/octet-stream # Content-Disposition: attachment; filename="file.txt" # Content-Transfer-Encoding: 7bit # # Note: the second regexp assumes "filename=file.txt" mimeAttachementRegexp1 = "filename$s*=$s*[\"']\/[^\"\']+" mimeAttachementRegexp2 = "filename$s*=$s*\/.*" :0 *$ H ?? ^Content-Disposition:.*attachment$s*;$s*\/.* *$ $SUPREME^0 MATCH ?? $mimeAttachementRegexp1 *$ $SUPREME^0 MATCH ?? $mimeAttachementRegexp2 { MIME_H_ATTACHMENT = $MATCH } :0 E *$ B ?? ^Content-Disposition:.*attachment$s*;$s*\/.* *$ $SUPREME^0 MATCH ?? $mimeAttachementRegexp1 *$ $SUPREME^0 MATCH ?? $mimeAttachementRegexp2 { MIME_B_ATTACHMENT = $MATCH :0 *$ B ?? 1^1 ^Content-Disposition:.*attachment.*filename { } MIME_B_ATTACHMENT_FILE_COUNT = $= } } dummy = "pm-jamime.rc: end:" # pm-jamime-tag.rc ends here