Email-Received-1.00/0000755000175000017500000000000010410745043013237 5ustar simonsimonEmail-Received-1.00/META.yml0000644000175000017500000000060210410745042014505 0ustar simonsimon# http://module-build.sourceforge.net/META-spec.html #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# name: Email-Received version: 1.00 version_from: lib/Email/Received.pm installdirs: site requires: Regexp::Common: 0 Text::Balanced: 0 distribution_type: module generated_by: ExtUtils::MakeMaker version 6.17 Email-Received-1.00/Changes0000644000175000017500000000025710407763440014545 0ustar simonsimonRevision history for Perl extension Email::Received. 0.01 Tue Mar 21 11:44:32 2006 - original version; created by h2xs 1.23 with options -AX -b 5.6.0 -n Email::Received Email-Received-1.00/t/0000755000175000017500000000000010410745043013502 5ustar simonsimonEmail-Received-1.00/t/Email-Received.t0000644000175000017500000000100410407763437016452 0ustar simonsimon# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl Email-Received.t' ######################### # change 'tests => 1' to 'tests => last_test_to_print'; use Test; BEGIN { plan tests => 1 }; use Email::Received; ok(1); # If we made it this far, we're ok. ######################### # Insert your test code below, the Test::More module is use()ed here so read # its man page ( perldoc Test::More ) for help writing this test script. Email-Received-1.00/t/rcvd_parser.t0000755000175000017500000006550010410743241016210 0ustar simonsimon#!/usr/bin/perl use Test::More tests => 48; use_ok("Email::Received"); use_ok("Email::Simple"); use strict; my %data = ( # format is: # q{ ...received hdrs sample... } => q{ [ expected string, normalized ] }, # .... # (normalized == s/\s+/ /gs;) q{ Received: (qmail 10681 invoked by uid 404); 14 Nov 2003 08:05:52 -0000 Received: from postfix3-2.free.fr (foobar@213.228.0.129) by totor.example.net with SMTP; 14 Nov 2003 08:05:50 -0000 Received: from asterix.laurier.org (lns-p19-8-82-65-66-244.adsl.proxad.net [82.65.66.244]) by postfix3-2.free.fr (Postfix) with ESMTP id 7BACDC372 for ; Fri, 14 Nov 2003 09:05:49 +0100 (CET) } => q{ [ ip=213.228.0.129 rdns=postfix3-2.free.fr helo=postfix3-2.free.fr by=totor.example.net ident=foobar envfrom= id= auth= ] [ ip=82.65.66.244 rdns=lns-p19-8-82-65-66-244.adsl.proxad.net helo=asterix.laurier.org by=postfix3-2.free.fr ident= envfrom= id=7BACDC372 auth= ] }, q{ Received: from 0 ([61.31.135.91]) by bass.bass.com.eg with Microsoft SMTPSVC(5.0.2195.6713); Tue, 21 Sep 2004 08:59:06 +0300 } => q{ [ ip=61.31.135.91 rdns= helo=0 by=bass.bass.com.eg ident= envfrom= intl=0 id= auth= ] }, q{ Received: from helene8.i.pinwand.net (helene.cats.ms) [10.0.8.6.13219] (mail) by lisbeth.i.pinwand.net with esmtp (Exim 3.35 #1 (Debian)) id 1CO5y7-0001vC-00; Sun, 31 Oct 2004 04:01:23 +0100 } => q{ [ ip=10.0.8.6 rdns=helene8.i.pinwand.net helo=helene.cats.ms by=lisbeth.i.pinwand.net ident= envfrom= intl=0 id=1CO5y7-0001vC-00 auth= ] }, q{ Received: from inet-vrs-05.redmond.corp.microsoft.com ([157.54.6.157]) by INET-IMC-05.redmond.corp.microsoft.com with Microsoft SMTPSVC(5.0.2195.6624); Thu, 6 Mar 2003 12:02:35 -0800 } => q{ [ ip=157.54.6.157 rdns= helo=inet-vrs-05.redmond.corp.microsoft.com by=INET-IMC-05.redmond.corp.microsoft.com ident= envfrom= id= auth= ] }, q{ Received: from tthompson ([217.35.105.172] unverified) by mail.neosinteractive.com with Microsoft SMTPSVC(5.0.2195.5329); Tue, 11 Mar 2003 13:23:01 +0000 } => q{ [ ip=217.35.105.172 rdns= helo=tthompson by=mail.neosinteractive.com ident= envfrom= id= auth= ] }, q{ Received: from mx56.pirmateh.us (64.119.196.56.rev.iwaynetworks.com [64.119.196.56] (may be forged)) by mail.core.obfugenedata.com (8.13.1/8.13.1) with ESMTP id i8FJcSRZ007847 for ; Wed, 15 Sep 2004 21:38:31 +0200 } => q{ [ ip=64.119.196.56 rdns=64.119.196.56.rev.iwaynetworks.com helo=mx56.pirmateh.us by=mail.core.obfugenedata.com ident= envfrom= intl=0 id=i8FJcSRZ007847 auth= ] }, q{ Received: from 0 ([61.31.138.57] RDNS failed) by nccdi.com with Microsoft SMTPSVC(6.0.3790.0); Thu, 23 Sep 2004 08:51:06 -0700 } => q{ [ ip=61.31.138.57 rdns= helo=0 by=nccdi.com ident= envfrom= id= auth= ] }, q{ Received: from klqe.net (unknown [192.168.50.50]) by mail.dropinsolutions.com (Postfix) with ESMTP id 62F9114047; Sun, 15 Feb 2004 14:29:04 -0500 (EST) } => q{ [ ip=192.168.50.50 rdns= helo=klqe.net by=mail.dropinsolutions.com ident= envfrom= id=62F9114047 auth= ] }, q{ Received: from Minstrel ([82.0.67.38]) by mta07-svc.ntlworld.com (InterMail vM.4.01.03.37 201-229-121-137-20020806) with ESMTP id <20031220035023.GCFK2588.mta07-svc.ntlworld.com@Minstrel> for ; Sat, 20 Dec 2003 03:50:23 +0000 } => q{ [ ip=82.0.67.38 rdns= helo=Minstrel by=mta07-svc.ntlworld.com ident= envfrom= id=20031220035023.GCFK2588.mta07-svc.ntlworld.com@Minstrel auth= ] }, q{ Received: from cs.helsinki.fi ([::ffff:218.11.152.141]) by mail.cs.helsinki.fi with esmtp; Mon, 18 Aug 2003 15:37:48 +0300 Received: from m165.4superdeals.biz (softdnserr [::ffff:64.235.238.165]) by mail.cs.helsinki.fi with esmtp; Sun, 17 Aug 2003 19:30:42 +0300 } => q{ [ ip=218.11.152.141 rdns= helo=cs.helsinki.fi by=mail.cs.helsinki.fi ident= envfrom= id= auth= ] [ ip=64.235.238.165 rdns= helo=m165.4superdeals.biz by=mail.cs.helsinki.fi ident= envfrom= id= auth= ] }, q{ Received: from hotmail.com (bay1-f95.bay1.hotmail.com [65.54.245.95]) by Daffy.timing.com; Received: from mail pickup service by hotmail.com with Microsoft SMTPSVC; Tue, 16 Mar 2004 18:12:31 -0800 Received: from 24.8.231.233 by by1fd.bay1.hotmail.msn.com with HTTP; Wed, 17 Mar 2004 02:12:31 GMT } => q{ [ ip=65.54.245.95 rdns=bay1-f95.bay1.hotmail.com helo=hotmail.com by=Daffy.timing.com ident= envfrom= id= auth= ] [ ip=24.8.231.233 rdns= helo= by=by1fd.bay1.hotmail.msn.com ident= envfrom= id= auth=HTTP ] }, q{ Received: (qmail 22147 invoked by uid 526); 6 Feb 2005 21:11:38 -0000 Received: from 156.56.111.196 by blazing.arsecandle.org (envelope-from , uid 502) with qmail-scanner-1.24 (clamdscan: 0.80/594. f-prot: 4.4.2/3.14.11. Clear:RC:0(156.56.111.196):. Processed in 0.288806 secs); 06 Feb 2005 21:11:38 -0000 DomainKey-Status: no signature Received: from lists.gentoo.org (HELO parrot.gentoo.org) (156.56.111.196) by blazing.arsecandle.org with (DHE-RSA-AES256-SHA encrypted) SMTP; 6 Feb 2005 21:11:37 -0000 Received: (qmail 3988 invoked by uid 89); 6 Feb 2005 21:11:12 +0000 } => q{ [ ip=156.56.111.196 rdns=lists.gentoo.org helo=parrot.gentoo.org by=blazing.arsecandle.org ident= envfrom=gentoo-announce-return-530-rod=arsecandle.org@lists.gentoo.org id= auth= ] }, q{ Received: from hotmail.com (something.com [65.54.245.95]) at just after 10pm by Daffy.timing.com on a Friday (CrazyMTA) (envelope-from ) with TFTP } => q{ [ ip=65.54.245.95 rdns=something.com helo=hotmail.com by=Daffy.timing.com ident= envfrom=foo@example.com id= auth= ] }, q{ Received: from postfix3-2.free.fr (foobar@213.228.0.139) by totor.example.net with SMTP; 14 Nov 2003 08:05:50 -0000 Received: from asterix.laurier.org (lns-p19-8-82-65-66-244.adsl.proxad.net [82.65.66.244]) by postfix3-2.free.fr (Postfix) with ESMTP id 7BACDC372 for ; Fri, 14 Nov 2003 09:05:49 +0100 (CET) } => q{ [ ip=213.228.0.139 rdns=postfix3-2.free.fr helo=postfix3-2.free.fr by=totor.example.net ident=foobar envfrom= id= auth= ] [ ip=82.65.66.244 rdns=lns-p19-8-82-65-66-244.adsl.proxad.net helo=asterix.laurier.org by=postfix3-2.free.fr ident= envfrom= id=7BACDC372 auth= ] }, q{ Received: from unknown (HELO feux01a-isp) (213.199.4.210) by totor.example.net with SMTP; 1 Nov 2003 07:05:19 -0000 } => q{ [ ip=213.199.4.210 rdns= helo=feux01a-isp by=totor.example.net ident= envfrom= id= auth= ] }, q{ Received: from x1-6-00-04-bd-d2-e0-a3.k317.webspeed.dk (benelli@80.167.158.170) by totor.example.net with SMTP; 5 Nov 2003 23:18:42 -0000 } => q{ [ ip=80.167.158.170 rdns=x1-6-00-04-bd-d2-e0-a3.k317.webspeed.dk helo=x1-6-00-04-bd-d2-e0-a3.k317.webspeed.dk by=totor.example.net ident=benelli envfrom= id= auth= ] }, q{ Received: from adsl-207-213-27-129.dsl.lsan03.pacbell.net (HELO merlin.net.au) (Owner50@207.213.27.129) by totor.example.net with SMTP; 10 Nov 2003 06:30:34 -0000 } => q{ [ ip=207.213.27.129 rdns=adsl-207-213-27-129.dsl.lsan03.pacbell.net helo=merlin.net.au by=totor.example.net ident=Owner50 envfrom= id= auth= ] }, q{ Received: from imo-m01.mx.aol.com ([64.12.136.4] verified) by xxx.com (CommuniGate Pro SMTP 4.1.8) with ESMTP id 875522 for yyy@xxx.com; Tue, 03 Feb 2004 08:37:38 -0800 Received: from Dwsf@aol.com by imo-m01.mx.aol.com (mail_out_v36_r4.12.) id m.b9.3bfe3305 (4116) for ; Tue, 3 Feb 2004 11:14:06 -0500 (EST) } => q{ [ ip=64.12.136.4 rdns= helo=imo-m01.mx.aol.com by=xxx.com ident= envfrom= id=875522 auth= ] }, q{ Received: from bigass1.example.com ([66.199.2.3]) by slim1.example.com with esmtp; Tue, 06 Jan 2004 23:56:09 +0000 Received: from a1200 ([24.83.2.4]) (AUTH: LOGIN mitch@example.com) by bigass1.example.com with esmtp; Tue, 06 Jan 2004 23:56:09 +0000 Received: from bigass1.example.com (ns1.example.com [66.199.2.5]) by fiat.example.edu (8.12.10/8.12.10) with ESMTP id i06MBJ6U020255 for ; Tue, 6 Jan 2004 16:11:19 -0600 Received: from a1200 ([24.83.2.6]) (AUTH: LOGIN mitch@example.com) by bigass1.example.com with esmtp; Tue, 06 Jan 2004 22:09:53 +0000 Received: from a1200 ([24.83.2.7]) (AUTH: LOGIN mitch@example.com) by bigass1.example.com with esmtp; Tue, 06 Jan 2004 23:56:09 +0000 } => q{ [ ip=66.199.2.3 rdns= helo=bigass1.example.com by=slim1.example.com ident= envfrom= id= auth= ] [ ip=24.83.2.4 rdns= helo=a1200 by=bigass1.example.com ident= envfrom= id= auth=LOGIN ] [ ip=66.199.2.5 rdns=ns1.example.com helo=bigass1.example.com by=fiat.example.edu ident= envfrom= id=i06MBJ6U020255 auth= ] [ ip=24.83.2.6 rdns= helo=a1200 by=bigass1.example.com ident= envfrom= id= auth=LOGIN ] [ ip=24.83.2.7 rdns= helo=a1200 by=bigass1.example.com ident= envfrom= id= auth=LOGIN ] }, q{ Received: from postfix3-2.free.fr (HELO machine.domain.com) (foobar@213.228.20.149) by totor.example.net with SMTP; 14 Nov 2003 08:31:29 -0000 } => q{ [ ip=213.228.20.149 rdns=postfix3-2.free.fr helo=machine.domain.com by=totor.example.net ident=foobar envfrom= id= auth= ] }, q{ Received: from postfix3-2.free.fr (213.228.0.159) by totor.example.net with SMTP; 14 Nov 2003 08:31:29 -0000 } => q{ [ ip=213.228.0.159 rdns=postfix3-2.free.fr helo=postfix3-2.free.fr by=totor.example.net ident= envfrom= id= auth= ] }, q{ Received: from postfix3-2.free.fr (foobar@213.228.0.169) by totor.example.net with SMTP; 14 Nov 2003 08:31:29 -0000 } => q{ [ ip=213.228.0.169 rdns=postfix3-2.free.fr helo=postfix3-2.free.fr by=totor.example.net ident=foobar envfrom= id= auth= ] }, q{ Received: from unknown (HELO machine.domain.com) (foobar@213.228.0.179) by totor.example.net with SMTP; 14 Nov 2003 08:31:29 -0000 } => q{ [ ip=213.228.0.179 rdns= helo=machine.domain.com by=totor.example.net ident=foobar envfrom= id= auth= ] }, q{ Received: from unknown (HELO machine.domain.com) (213.228.0.189) by totor.example.net with SMTP; 14 Nov 2003 08:31:29 -0000 } => q{ [ ip=213.228.0.189 rdns= helo=machine.domain.com by=totor.example.net ident= envfrom= id= auth= ] }, q{ Received: from loki.komtel.net (212.7.146.145) by totor.example.net with SMTP; 16 Nov 2003 04:53:54 -0000 } => q{ [ ip=212.7.146.145 rdns=loki.komtel.net helo=loki.komtel.net by=totor.example.net ident= envfrom= id= auth= ] }, q{ Received: from c66.169.197.134.ts46v-19.pkcty.ftwrth.tx.charter.com (66.169.197.134) by totor.example.net with SMTP; 16 Nov 2003 05:59:32 -0000 } => q{ [ ip=66.169.197.134 rdns=c66.169.197.134.ts46v-19.pkcty.ftwrth.tx.charter.com helo=c66.169.197.134.ts46v-19.pkcty.ftwrth.tx.charter.com by=totor.example.net ident= envfrom= id= auth= ] }, q{ Received: from dyn-81-166-39-132.ppp.tiscali.fr (81.166.39.132) by cpmail.dk.tiscali.com (6.7.018) id 3FE6899B004FE7A4; Thu, 1 Jan 2004 05:28:49 +0100 } => q{ [ ip=81.166.39.132 rdns=dyn-81-166-39-132.ppp.tiscali.fr helo=dyn-81-166-39-132.ppp.tiscali.fr by=cpmail.dk.tiscali.com ident= envfrom= id=3FE6899B004FE7A4 auth= ] }, q{ Received: from unknown (HELO [81.64.159.45]) ([81.64.159.45]) (envelope-sender ) by 212.198.2.120 (qmail-ldap-1.03) with SMTP for ; 28 Nov 2003 20:44:45 -0000 } => q{ [ ip=81.64.159.45 rdns= helo=!81.64.159.45! by=212.198.2.120 ident= envfrom=xyz@example.org id= auth= ] }, q{ Received: (qmail 8363 invoked by uid 526); 3 Mar 2004 20:34:41 -0000 Received: from advertisement@topofferz.net by blazing.fooooo.org by uid 501 with qmail-scanner-1.20 (clamuko: 0.65. f-prot: 4.2.0/3.13.4. Clear:RC:1(127.0.0.1):. Processed in 0.20859 secs); 03 Mar 2004 20:34:41 -0000 Received: (qmail 8351 invoked by uid 526); 3 Mar 2004 20:34:39 -0000 Received: from advertisement@topofferz.net by blazing.fooooo.org by uid 502 with qmail-scanner-1.20 (clamuko: 0.65. f-prot: 4.2.0/3.13.4. Clear:RC:0(69.6.60.10):. Processed in 0.212322 secs); 03 Mar 2004 20:34:39 -0000 Received: from mx10.topofferz.net (HELO ) (69.6.60.10) by blazing.fooooo.org with SMTP; 3 Mar 2004 20:34:38 -0000 } => q{ [ ip=69.6.60.10 rdns=mx10.topofferz.net helo= by=blazing.fooooo.org ident= envfrom= id= auth= ] }, q{ Received: from email.com (unknown [222.32.65.3]) by eclectic.kluge.net (Postfix) with ESMTP id 33DC4416F20 for ; Mon, 1 Mar 2004 01:09:44 -0500 (EST) } => q{ [ ip=222.32.65.3 rdns= helo=email.com by=eclectic.kluge.net ident= envfrom= id=33DC4416F20 auth= ] }, q{ Received: from kluge.net (unknown [222.156.78.32]) by eclectic.kluge.net (Postfix) with SMTP id CE1BA416F20 for ; Mon, 1 Mar 2004 13:11:31 -0500 (EST) } => q{ [ ip=222.156.78.32 rdns= helo=kluge.net by=eclectic.kluge.net ident= envfrom= id=CE1BA416F20 auth= ] }, q{ Received: from xjwrvjq (unknown [222.54.106.152]) by eclectic.kluge.net (Postfix) with SMTP id ED474416F20 for ; Tue, 2 Mar 2004 12:51:44 -0500 } => q{ [ ip=222.54.106.152 rdns= helo=xjwrvjq by=eclectic.kluge.net ident= envfrom= id=ED474416F20 auth= ] }, q{ Received: from europa21.inetsiteworld.net (europa21.inetsiteworld.net [217.110.206.5]) by mx1.redhat.com (8.12.10/8.12.10) with SMTP id i28CUmST012272 for ; Mon, 8 Mar 2004 07:30:48 -0500 Received: from SpamControl_operated_by_INetSiteWorld (localhost [127.0.0.1]) by europa21.inetsiteworld.net (8.12.9/8.12.7-jokey) with ESMTP id i28CNuck014319 for ; Mon, 8 Mar 2004 13:23:57 +0100 Received: from 212.202.243.194 ([212.202.243.194] helo=blackstar) by SpamControl_operated_by_INetSiteWorld ; 8 Mar 04 12:23:56 -0000 } => q{ [ ip=217.110.206.5 rdns=europa21.inetsiteworld.net helo=europa21.inetsiteworld.net by=mx1.redhat.com ident= envfrom= id=i28CUmST012272 auth= ] [ ip=127.0.0.1 rdns=localhost helo=SpamControl_operated_by_INetSiteWorld by=europa21.inetsiteworld.net ident= envfrom= id=i28CNuck014319 auth= ] [ ip=212.202.243.194 rdns= helo=blackstar by=SpamControl_operated_by_INetSiteWorld ident= envfrom= id= auth= ] }, q{ Received: from localhost (localhost [127.0.0.1]) by radish.zzzz.org (Postfix) with ESMTP id 1398F5900D9 for ; Mon, 8 Mar 2004 16:02:50 -0800 (PST) Received: from localhost [127.0.0.1] by localhost with IMAP (fetchmail-6.2.4) for zzzz@localhost (single-drop); Mon, 08 Mar 2004 16:02:50 -0800 (PST) Received: from mail00.svc.cra.dublin.eircom.net (mail00.svc.cra.dublin.eircom.net [159.134.118.16]) by amgod.boxhost.net (Postfix) with SMTP id 0ACFC31014D for ; Mon, 8 Mar 2004 23:59:19 +0000 (GMT) Received: (qmail 87263 messnum 771997 invoked from network[83.70.48.2/83-70-48-2.bas2.dbn.dublin.eircom.net]); 8 Mar 2004 23:59:05 -0000 Received: from 83-70-48-2.bas2.dbn.dublin.eircom.net (HELO ?192.168.23.32?) (83.70.48.2) by mail00.svc.cra.dublin.eircom.net (qp 87263) with SMTP; 8 Mar 2004 23:59:05 -0000 } => q{ [ ip=159.134.118.16 rdns=mail00.svc.cra.dublin.eircom.net helo=mail00.svc.cra.dublin.eircom.net by=amgod.boxhost.net ident= envfrom= id=0ACFC31014D auth= ] [ ip=83.70.48.2 rdns=83-70-48-2.bas2.dbn.dublin.eircom.net helo=?192.168.23.32? by=mail00.svc.cra.dublin.eircom.net ident= envfrom= id= auth= ] }, q{ Received: from localhost (localhost [127.0.0.1]) by radish.jmason.org (Postfix) with ESMTP id 27B275900D9 for ; Mon, 8 Mar 2004 16:13:23 -0800 (PST) Received: from localhost [127.0.0.1] by localhost with IMAP (fetchmail-6.2.4) for zzzzz@localhost (single-drop); Mon, 08 Mar 2004 16:13:23 -0800 (PST) Received: from smtp3.es.uci.edu (smtp3.es.uci.edu [128.200.80.6]) by amgod.boxhost.net (Postfix) with ESMTP id 87D0A310091 for ; Tue, 9 Mar 2004 00:07:59 +0000 (GMT) Received: from rigel.oac.uci.edu (rigel.oac.uci.edu [128.200.80.22]) by smtp3.es.uci.edu (8.12.8/8.12.8) with ESMTP id i2907ZaF008726 for ; Mon, 8 Mar 2004 16:07:35 -0800 Received: from localhost (wwwwww@localhost) by rigel.oac.uci.edu (8.9.3p2/8.9.3) with ESMTP id QAA13555 for ; Mon, 8 Mar 2004 16:07:35 -0800 (PST) } => q{ [ ip=128.200.80.6 rdns=smtp3.es.uci.edu helo=smtp3.es.uci.edu by=amgod.boxhost.net ident= envfrom= id=87D0A310091 auth= ] [ ip=128.200.80.22 rdns=rigel.oac.uci.edu helo=rigel.oac.uci.edu by=smtp3.es.uci.edu ident= envfrom= id=i2907ZaF008726 auth= ] }, q{ Received: from list.brainbuzz.com (63.146.189.86:23198) by mx1.yourtech.net with [XMail 1.20 ESMTP Server] id for from ; Sat, 18 Sep 2004 23:17:54 -0500 }, q{ [ ip=63.146.189.86 rdns= helo=list.brainbuzz.com by=mx1.yourtech.net ident= envfrom=bounce-cscommunity-11965901@list.obfuscatedzzzzzzz.com id=S72E auth= ] }, q{ Received: from list.brainbuzz.com ([63.146.189.86]:23198) by mx1.yourtech.net with [XMail 1.20 ESMTP Server] id for from ; Sat, 18 Sep 2004 23:17:54 -0500 }, q{ [ ip=63.146.189.86 rdns= helo=list.brainbuzz.com by=mx1.yourtech.net ident= envfrom=bounce-cscommunity-11965901@list.obfuscatedzzzzzzz.com id=S72E auth= ] }, q{ Received: from pop.vip.sc5.yahoo.com [216.136.173.10] by localhost with POP3 (fetchmail-5.9.13) for pppppppppp@hhhhhhhhh.net (single-drop); Sun, 22 Feb 2004 20:46:25 -0600 (CST) Received: from 211.245.85.228 (EHLO ) (211.245.85.228) by mta232.mail.scd.yahoo.com with SMTP; Sun, 25 Jan 2004 00:24:37 -0800 } => q{ [ ip=211.245.85.228 rdns=211.245.85.228 helo= by=mta232.mail.scd.yahoo.com ident= envfrom= id= auth= ] }, q{ Received: from dsl092-076-133.bos1.dsl.speakeasy.net ([66.92.76.133] helo=pendaran.arborius.net) by sc8-sf-mx1.sourceforge.net with esmtp (TLSv1:AES256-SHA:256) (Exim 4.41) id 1CIlfc-0003Pa-8W for xvoice-user@lists.sourceforge.net; Sat, 16 Oct 2004 03:20:18 -0700 Received: from gilmore.ael.be ([158.64.60.71]) by castlerea.stdlib.net with esmtp (TLSv1:DES-CBC3-SHA:168) (Exim 4.41) id 1CIusZ-00049K-45 for e-voting@lists.stdlib.net; Sat, 16 Oct 2004 21:10:16 +0100 Received: from rc3.isc.org (rc3.isc.org [IPv6:2001:4f8:3:bb::25]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by sf1.isc.org (Postfix) with ESMTP id C986F284EE for ; Sat, 16 Oct 2004 21:30:02 +0000 (UTC) (envelope-from bind-users-bounce@isc.org) Received: from rubel.csumb.edu (rubel.csumb.edu [198.189.237.214]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by sf1.isc.org (Postfix) with ESMTP id 23587284EE for ; Sat, 16 Oct 2004 23:32:19 +0000 (UTC) (envelope-from snort@csumb.edu) Received: from p50894de7.dip0.t-ipconnect.de ([80.137.77.231]:11218 helo=sandpiper) by mail1.isc.de with esmtp (TLSv1:RC4-SHA:128) (Exim 4.04) id 1CJaZW-0006rU-00 for linux-thinkpad@linux-thinkpad.org; Mon, 18 Oct 2004 18:41:23 +0200 } => q{ [ ip=66.92.76.133 rdns=dsl092-076-133.bos1.dsl.speakeasy.net helo=pendaran.arborius.net by=sc8-sf-mx1.sourceforge.net ident= envfrom= id=1CIlfc-0003Pa-8W auth= ] [ ip=158.64.60.71 rdns=gilmore.ael.be helo= by=castlerea.stdlib.net ident= envfrom= id=1CIusZ-00049K-45 auth= ] [ ip=198.189.237.214 rdns=rubel.csumb.edu helo=rubel.csumb.edu by=sf1.isc.org ident= envfrom=snort@csumb.edu id=23587284EE auth= ] [ ip=80.137.77.231 rdns=p50894de7.dip0.t-ipconnect.de helo=sandpiper by=mail1.isc.de ident= envfrom= id=1CJaZW-0006rU-00 auth= ] }, q{ Received: from 153.90.199.141 (SquirrelMail authenticated user admin); by web1.cs.montana.edu with HTTP; Thu, 23 Sep 2004 14:35:29 -0600 (MDT) Received: from [192.168.1.3] (80-28-223-208.adsl.nuria.telefonica-data.net [80.28.223.208]) (authenticated bits=0) by mac.com (Xserve/smtpin08/MantshX 4.0) with ESMTP id i8NIdH8G002812 for ... Received: from perceptions.couk.com (81.103.146.112) by n082.sc1.cp.net (7.0.030.2) (authenticated as r.dickenson) id 414B418B002D65F1 for forteana@yahoogroups.com; Thu, 23 Sep 2004 18:42:17 +0000 Received: from 141.44.167.13 (p83.129.191.197.tisdip.tiscali.de [83.129.191.197]) (authenticated bits=0) by sunny.urz.uni-magdeburg.de (8.12.10/8.12.10) with ESMTP id i8ND9v0N017746 (version=TLSv1/SSLv3 cipher=RC4-MD5 bits=128 verify=NO) for ; Thu, 23 Sep 2004 15:09:59 +0200 } => q{ [ ip=80.28.223.208 rdns=80-28-223-208.adsl.nuria.telefonica-data.net helo=!192.168.1.3! by=mac.com ident= envfrom= id=i8NIdH8G002812 auth=Sendmail ] [ ip=81.103.146.112 rdns=perceptions.couk.com helo=perceptions.couk.com by=n082.sc1.cp.net ident= envfrom= id=414B418B002D65F1 auth=CriticalPath ] [ ip=83.129.191.197 rdns=p83.129.191.197.tisdip.tiscali.de helo=141.44.167.13 by=sunny.urz.uni-magdeburg.de ident= envfrom= id=i8ND9v0N017746 auth=Sendmail ] }, q{ Received: from rousalka.dyndns.org (81.64.155.54) by mx.laposte.net (7.0.028) (authenticated as Nicolas.Mailhot) id 413489B100C9C1FD for fedora-devel-list@redhat.com; Tue, 28 Sep 2004 21:43:43 +0200 Received: from [10.0.0.253] (82-68-189-22.dsl.in-addr.zen.co.uk [82.68.189.22]) (authenticated (0 bits)) by ensim.rackshack.net (8.11.6/8.11.6) with ESMTP id i8TAFAI25021 for ; Wed, 29 Sep 2004 10:15:10 GMT Received: from [213.174.165.187] (213.174.165.187) by vsmtp1.tin.it (7.0.027) (authenticated as mgiammarco@virgilio.it) id 416A525B0000A53B for linux-thinkpad@linux-thinkpad.org; Mon, 11 Oct 2004 12:52:46 +0200 Received: from [10.10.10.215] (Collation_Software.demarc.cogentco.com [66.250.6.18]) (authenticated bits=0) by waste.org (8.12.3/8.12.3/Debian-6.6) with ESMTP id i46MehGO005108 for ; Thu, 6 May 2004 17:40:44-0500 Received: from ausisaps301-dmz.aus.amer.dell.com ([143.166.226.16]) (SquirrelMail authenticated user hoolis); by www.penguintowne.org with HTTP; Mon, 22 Mar 2004 12:54:13 -0600 (CST) Received: from dsl-082-082-143-115.arcor-ip.net (dsl-082-083-139-045.arcor-ip.net [82.83.139.45]) (authenticated bits=0) by postman.arcor.de (8.13.0.PreAlpha4/8.13.0.PreAlpha4) with ESMTP id i2U75jD1003350 for ; Tue, 30 Mar 2004 09:05:45 +0200 (MEST) } => q{ [ ip=81.64.155.54 rdns=rousalka.dyndns.org helo=rousalka.dyndns.org by=mx.laposte.net ident= envfrom= id=413489B100C9C1FD auth=CriticalPath ] [ ip=82.68.189.22 rdns=82-68-189-22.dsl.in-addr.zen.co.uk helo=!10.0.0.253! by=ensim.rackshack.net ident= envfrom= id=i8TAFAI25021 auth=Sendmail ] [ ip=213.174.165.187 rdns=!213.174.165.187! helo=!213.174.165.187! by=vsmtp1.tin.it ident= envfrom= id=416A525B0000A53B auth=CriticalPath ] [ ip=66.250.6.18 rdns=Collation_Software.demarc.cogentco.com helo=!10.10.10.215! by=waste.org ident= envfrom= id=i46MehGO005108 auth=Sendmail ] [ ip=82.83.139.45 rdns=dsl-082-083-139-045.arcor-ip.net helo=dsl-082-082-143-115.arcor-ip.net by=postman.arcor.de ident= envfrom= id=i2U75jD1003350 auth=Sendmail ] }, q{ Received: from p5483b7c0.dip.t-dialin.net ([84.131.183.192] helo=192.168.1.23) by moonflower.de with asmtp (TLS-1.0:RSA_ARCFOUR_MD5:16) (Exim 4.34) id 1CIoQP-0006SN-GV for linux-thinkpad@linux-thinkpad.org; Sat, 16 Oct 2004 15:16:47 +0200 Received: from bgp01132961bgs.ypeast01.mi.comcast.net ([68.42.119.201] helo=moonweaver.home.awesomeplay.com) by outbound.mailhop.org with esmtpsa (TLSv1:RC4-SHA:128) (Exim 4.42) id 1CJic5-00067m-U7 } => q{ [ ip=84.131.183.192 rdns=p5483b7c0.dip.t-dialin.net helo=192.168.1.23 by=moonflower.de ident= envfrom= id=1CIoQP-0006SN-GV auth=asmtp ] [ ip=68.42.119.201 rdns=bgp01132961bgs.ypeast01.mi.comcast.net helo=moonweaver.home.awesomeplay.com by=outbound.mailhop.org ident= envfrom= id=1CJic5-00067m-U7 auth=esmtpsa ] }, q{ Received: from gorkcomputer (my.dns.com [1.2.3.4]) (AUTH: LOGIN gork@mydomain.com, SSL: TLSv1/SSLv3,128bits,RC4-MD5) by mydomain.com with esmtp; Thu, 10 Nov 2005 08:24:21 -0600 id 000000DB.43735815.00001E11 } => q{ [ ip=1.2.3.4 rdns=my.dns.com helo=gorkcomputer by=mydomain.com ident= envfrom= id=000000DB.43735815.00001E11 auth=LOGIN ] }, q{ Received: FROM hackers.mr.itd.umich.edu (smtp.mail.umich.edu [141.211.14.81]) BY madman.mr.itd.umich.edu ID 434B508E.174A6.13932 ; 11 Oct 2005 01:41:34 -0400 Received: FROM [192.168.1.24] (s233-64-90-216.try.wideopenwest.com [64.233.216.90]) BY hackers.mr.itd.umich.edu ID 434B5051.8CDE5.15436 ; 11 Oct 2005 01:40:33 -0400 } => q{ [ ip=141.211.14.81 rdns=smtp.mail.umich.edu helo=hackers.mr.itd.umich.edu by=madman.mr.itd.umich.edu ident= envfrom= id=434B508E.174A6.13932 auth= ] [ ip=64.233.216.90 rdns=s233-64-90-216.try.wideopenwest.com helo=!192.168.1.24! by=hackers.mr.itd.umich.edu ident= envfrom= id=434B5051.8CDE5.15436 auth= ] }, q{ Received: from TCE-E-7-182-54.bta.net.cn(202.106.182.54) via SMTP by st.tahina.priv.at, id smtpdEDUB8h; Sun Nov 13 14:50:12 2005 Received: from pl027.nas934.d-osaka.nttpc.ne.jp(61.197.82.27), claiming to be "foo.woas.net" via SMTP by st.tahina.priv.at, id smtpd1PBsZT; Sun Nov 13 15:38:52 2005 } => q{ [ ip=202.106.182.54 rdns=TCE-E-7-182-54.bta.net.cn helo= by=st.tahina.priv.at ident= envfrom= id=smtpdEDUB8h auth= ] [ ip=61.197.82.27 rdns=pl027.nas934.d-osaka.nttpc.ne.jp helo=foo.woas.net by=st.tahina.priv.at ident= envfrom= id=smtpd1PBsZT auth= ] }, q{ Received: from [206.51.230.145] (helo=t-online.de) by mxeu2.kundenserver.de with ESMTP (Nemesis), id 0MKpdM-1CkRpr14PF-000608; Fri, 31 Dec 2004 19:49:15 +0100 } => q{ [ ip=206.51.230.145 rdns= helo=t-online.de by=mxeu2.kundenserver.de ident= envfrom= id=0MKpdM-1CkRpr14PF-000608 auth= ] } ); TODO: foreach my $hdrs (sort keys %data) { local $TODO; if($hdrs =~ /gentoo/) { $TODO = "qmail-scanner hack not supported" } if($hdrs =~ /gorkcomputer/) { $TODO = "Don't know why this fails" } if($hdrs =~ /fetchmail/) { $TODO = "since we work line at a time we can't pop fetchmail->localSMTP headers" } if($hdrs =~ /hotmail/) { $TODO = "hotmail is close but not there yet" } my $expected = $data{$hdrs}; $hdrs =~ s/^\s+//ms; $hdrs =~ s/\s+$//ms; my $msg = $hdrs."\n\n[no body]\n"; my $email = Email::Simple->new($msg); my @rcvd = $email->header("Received"); my @stuff = grep { !$_->{reason}} map { parse_received($_) } @rcvd; my @expected; for ($expected =~ /\[(.*?)\]/g) { my $line = {}; for (split /\s+/, $_) { my ($left, $right) = split /=/, $_,2 ; next unless $left; next if $left eq "intl"; # Bleh $line->{$left} = $right; } push @expected, $line; } my @fired; for my $i (0..$#stuff) { !defined $stuff[$i]->{$_} and $stuff[$i]->{$_} = '' for qw/ip rdns helo ident envfrom auth by id/; delete $stuff[$i]->{sub}; $fired[$i] = delete $stuff[$i]->{rules_fired}; } if(!is_deeply(\@stuff, \@expected)) { print "# Input was:\n"; $hdrs =~ s/^/# /gms; print $hdrs; print "#\n# Output was:\n"; my $out = Dumper(\@stuff); use Data::Dumper; $out =~ s/^/# /gms; print $out; print "#\n# Rules fired:\n"; for my $i (0..$#stuff) { for (@{$fired[$i]}) { print "# [$i] $_\n"; } } } } Email-Received-1.00/MANIFEST0000644000175000017500000000031410410744747014400 0ustar simonsimonChanges Makefile.PL MANIFEST README t/Email-Received.t t/rcvd_parser.t lib/Email/Received.pm lib/Email/Received/Constants.pm META.yml Module meta-data (added by MakeMaker) Email-Received-1.00/lib/0000755000175000017500000000000010410745043014005 5ustar simonsimonEmail-Received-1.00/lib/Email/0000755000175000017500000000000010410745043015034 5ustar simonsimonEmail-Received-1.00/lib/Email/Received/0000755000175000017500000000000010410745043016562 5ustar simonsimonEmail-Received-1.00/lib/Email/Received/Constants.pm0000644000175000017500000001160210410532447021076 0ustar simonsimonpackage Email::Received::Constants; use base qw( Exporter ); @IP_VARS = qw( LOCALHOST IPV4_ADDRESS IP_ADDRESS ); our @EXPORT = @IP_VARS; use constant LOCALHOST => qr/ (?: # as a string localhost(?:\.localdomain)? | \b(? qr/\b (?:1\d\d|2[0-4]\d|25[0-5]|\d\d|\d)\. (?:1\d\d|2[0-4]\d|25[0-5]|\d\d|\d)\. (?:1\d\d|2[0-4]\d|25[0-5]|\d\d|\d)\. (?:1\d\d|2[0-4]\d|25[0-5]|\d\d|\d) \b/ox; use constant IP_ADDRESS => qr/ (?: \b(? 0; require Exporter; use base 'Exporter'; our @EXPORT = qw( parse_received); our $VERSION = '1.00'; use Email::Received::Constants; my $IP_ADDRESS = IP_ADDRESS; my $LOCALHOST = LOCALHOST; use Regexp::Common qw/net/; # So the plan - man, this is so evil - is to make parse_received on the # fly from the rules below. *parse_received = generate_parse_received( unparse_rules(parse_rules())); sub tidy_up { my $r = shift; no warnings; #print "Tidy up called for $_\n"; $r->{envfrom} =~ s/^\s*<*//gs; $r->{envfrom} =~ s/>*\s*$//gs; $r->{by} =~ s/\;$//; if ($r->{ip} =~ /($RE{net}{IPv4})/) { $r->{ip} = $1 } else { return } exists $r->{$_} and $r->{$_} =~ s/[\s\0\#\[\]\(\)\<\>\|]/!/gs for qw/ip rdns helo by ident envfrom /; delete $r->{rdns} if lc $r->{rdns} eq "unknown"; return $r; } sub generate_parse_received { my $code = shift; $code = q|sub { local $_ = shift; s/\s+/ /gs; #print "Got $_\n"; my $r = {}; |. $code. q/ #print "Dropped off the end\n"; return tidy_up($r); } /; my $subref = eval $code; die "Couldn't create subroutine: $@" if $@; return $subref; } =head1 NAME Email::Received - Parse an email Received: header =head1 SYNOPSIS use Email::Received; for ($mail->header("Received")) { my $data = parse_received($_); return "SPAM" if rbl_lookup($data->{ip}); } =head1 DESCRIPTION This module is a Perl Email Project rewrite of SpamAssassin's email header parser. We did this so that the great work they did in analysing pretty much every possible Received header format could be used in applications other than SpamAssassin itself. The module provides one function, C, which takes a single Received line. It then produces either nothing, if the line is unparsable, a hash reference like this: { reason => "gateway noise" } if the line should be ignored for some good reason, and one like this: { ip => '64.12.136.4', id => '875522', by => 'xxx.com', helo => 'imo-m01.mx.aol.com' } if it parsed the message. Possible keys are: ip rdns helo ident envfrom auth by id =head1 RULE FORMAT Where SpamAssassin used a big static subroutine full of regular expressions to parse the data, we build up a big subroutine full of regular expressions dynamically from a set of rules. The rules are stored at the bottom of this module. The basic format for a rule looks like this: ((var=~)?/REGEXP/)? [ACTION; ]+ The C is either C, C, C or C. One control structure is provided, which is basically an C statement: GIVEN (NOT)? /REGEXP/ { ACTION+ } =head2 EXPORT parse_received =head1 SEE ALSO L, from which the rules and some of the IP address matching constants were blatantly stolen. Thanks, guys, for doing such a comprehensive job! =head1 AUTHOR simon, Esimon@E =head1 COPYRIGHT AND LICENSE Copyright (C) 2006 by simon This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.7 or, at your option, any later version of Perl 5 you may have available. =cut use Text::Balanced qw(extract_quotelike); sub parse_rules { my $in_given = shift; my $tree = []; while () { chomp; s/^\s+//; s/^#.*//; next unless /\S/; if (/^}\s*$/) { return $tree if $in_given; die "Syntax error on line $.: superfluous close bracket\n"; } if (s/^GIVEN\s+//) { my $inverse = s/^NOT\s+//; my $referent = s/^(\S+)=~//?$1:""; my $re; unless ($re= extract_quotelike($_)) { die "Syntax error on line $.: given has no expression\n"; } die "Syntax error on line $.: improper given\n" unless /\s*{\s*$/; my $subtree = parse_rules(1); # Let the reader understand! push @$tree, {given => $re, ($referent ? (referent => $referent) : ()), subtree => $subtree, inverse => $inverse }; next; } my $referent; $referent = $1 if s/^(\S+)=~//; my $current = {}; if (DEBUG) { $current->{line} = "$.: $_"; } if (my $re= extract_quotelike($_)) { $current->{regexp} = $re; $current->{referent} = $referent if $referent; } elsif($referent) { die "Syntax error on line $.: Referent with no regexp!\n"; } # At this point we want a set of commands delimited with # semicolons my @actions; while ($_) { s/^\s+// and next; if (s/^SET (\w+)\s*((?:\|\|)?=)\s*(.*?);//) { push @actions, { action => "SET", variable => $1, value => $3, operator => $2 }; next; }elsif (s/^IGNORE\s*//) { my $reason = extract_quotelike($_); die "No semicolon after reason? on line $.\n" unless s/^\s*;//; push @actions, { action => "IGNORE", reason => $reason}; next; } elsif (s/^(DONE|UNPARSABLE)\s*;//) { push @actions, { action => $1 }; next; } die "Can't parse action '$_' at line $.\n"; } if (@actions) { $current->{actions} = \@actions } push @$tree, $current; } return $tree; } sub unparse_rules { my $tree = shift; my $level = shift||0; my $output; for (@$tree) { $output .= " " x ($level * 5); if ($_->{given}) { #$output .= "print q{Trying given $_->{given} against |}.\$_.qq{|\n};\n"; $output .= $_->{inverse} ? "unless " : "if "; $output .= "("; $output .= '$r->{'.$_->{referent}."}=~" if $_->{referent}; $output .= $_->{given}.") {\n"; #$output .= "print q{In given\n};\n"; $output .= unparse_rules($_->{subtree}, $level+1); $output .= " " x ($level * 5); $output .= "}\n"; #$output .= "print qq{Given over\n};\n"; next; } if ($_->{regexp}) { #$output .= "print qq{Trying regexp }.q{$_->{regexp}}.qq{\n};"; $output .= 'if ('; $output .= '$r->{'.$_->{referent}."}=~" if $_->{referent}; $output .= $_->{regexp}.") {\n"; } else { $output .= "do { \n"; } $level++; if (DEBUG) { $output .= " " x ($level * 5); $output .= 'push @{$r->{rules_fired}}, q{'.$_->{line}."};\n"; } for (@{$_->{actions}||[]}) { $output .= " " x ($level * 5); if ($_->{action} eq "DONE") { $output .= "return tidy_up(\$r)" } elsif ($_->{action} eq "UNPARSABLE") { $output .= "return" } elsif ($_->{action} eq "IGNORE") { $output .= 'return '; if ($_->{reason}) { $output .= "{reason => $_->{reason} }" }; } elsif ($_->{action} eq "SET") { $output .= '$r->{'.$_->{variable}."} ".$_->{operator} . " ".$_->{value} } else { die "Couldn't unparse action!\n" } $output .= ";\n"; } $level--; $output .= " " x ($level * 5); $output .= "};\n"; } return $output; } __DATA__ /^\(/ IGNORE "gateway noise"; /\sid\s+;]{3,})/ SET id = $1; / by .*? with (ESMTPA|ESMTPSA|LMTPA|LMTPSA|ASMTP|HTTP)\;? /i SET auth = $1; GIVEN /^from/ { / \(SquirrelMail authenticated user / IGNORE "SquirrelMail injection"; /^from .*?(?:\]\)|\)\])\s+\(AUTH: (LOGIN|PLAIN|DIGEST-MD5|CRAM-MD5) \S+(?:, .*?)?\)\s+by\s+/ SET auth = $1; /^from .*?(?:\]\)|\)\]) .*?\(.*?authenticated.*?\).*? by/ SET auth ||= "Sendmail"; /\) by .+ \(\d{1,2}\.\d\.\d{3}(?:\.\d{1,3})?\) \(authenticated as .+\) id / SET auth ||= "CriticalPath"; /(?:return-path:? |envelope-(?:sender|from)[ =])(\S+)\b/i SET envfrom = $1; GIVEN / SMTPSVC/ { /^from (\S+) \(\[(${IP_ADDRESS})\][^\)]{0,40}\) by (\S+) with Microsoft SMTPSVC/ SET helo = $1; SET ip = $2; SET by = $3; DONE; /^from mail pickup service by (\S+) with Microsoft SMTPSVC;/ IGNORE; } GIVEN /^from (\S+) \((\[?${IP_ADDRESS}\]?)(?::\d+|)\) by (\S+)(?: \(\S+\)|) with \[XMail/ { SET helo = $1; SET ip = $2; SET by = $3; / id <(\S+)> / SET id = $1; / from <(\S+)>; / SET envfrom = $1; DONE; } GIVEN /Exim/ { GIVEN /^from \[(${IP_ADDRESS})\] \((.*?)\) by (\S+) / { SET ip = $1; SET sub = $2; SET by = $3; sub=~s/helo=(\S+)// SET helo = $1; sub=~s/ident=(\S*)// SET ident = $1; DONE; } GIVEN /^from (\S+) \(\[(${IP_ADDRESS})\](.*?)\) by (\S+) / { SET rdns = $1; SET ip = $2; SET sub = $3; SET by = $4; sub=~s/helo=(\S+)// SET helo = $1; sub=~s/ident=(\S*)// SET ident = $1; DONE; } /^from (\S+) \[(${IP_ADDRESS})\](:\d+)? by (\S+) / SET rdns = $1; SET ip = $2; SET helo = $1; SET by = $4; DONE; /^from (\S+) / SET rdns = $1; / \((\S+)\) / SET helo = $1; GIVEN / \[(${IP_ADDRESS})(?:\.\d+)?\] / { SET ip = $1; /by (\S+) / SET by = $1; DONE; } /by (\S+) / SET by = $1; } /^from (\S+) \((\S+) \[(${IP_ADDRESS})\]\) by (\S+) with \S+ \(/ SET rdns = $2; SET ip = $3; SET helo = $1; SET by = $4; DONE; /^from (\S+) \(\[(${IP_ADDRESS})\] helo=(\S+)\) by (\S+) with / SET rdns = $1; SET ip = $2; SET helo = $3; SET by = $3; DONE; /^from (\S+) \(\[(${IP_ADDRESS})\]\) by (\S+) / SET helo = $1; SET ip = $2; SET by = $3; DONE; /^from (\S+) \((\S+\.\S+)\[(${IP_ADDRESS})\]\) by (\S+) / SET helo = $1; SET rdns = $2; SET ip = $3; SET by = $4; DONE; GIVEN / \(Postfix\) with/ { /^from (\S+) \((\S+) \[(${IP_ADDRESS})\]\) by (\S+) / SET helo = $1; SET rdns = $2; SET ip = $3; SET by = $4; DONE; /^from (\S+) \((\S+)\[(${IP_ADDRESS})\]\) by (\S+) / SET helo = $1; SET rdns = $2; SET ip = $3; SET by = $4; DONE; } GIVEN NOT /^from .* by \S+ \(qmail-\S+\) with / { GIVEN /^from (\S+) \((\S+) \[(${IP_ADDRESS})\].*\) by (\S+) \(/ { SET helo = $1; SET rdns = $2; SET ip = $3; SET by = $4; rdns=~s/^IDENT:([^\@]*)\@// SET ident = $1; rdns=~ s/^([^\@]*)\@// SET ident = $1; DONE; } } /^from (\S+) \((\S*)\@\[(${IP_ADDRESS})\].*\) by (\S+) \(/ SET helo = $1; SET ident = $2; SET ip = $3; SET by = $4; DONE; GIVEN /by (\S+\.hotmail\.msn\.com) / { SET by = $1; /^from (\S+) / SET ip = $1; DONE; } /^from (\S+) \((?:HELO|EHLO) (\S*)\) \((${IP_ADDRESS})\) by (\S+) \(qpsmtpd\/(\S+)\) with (ESMTP|SMTP)/ SET rdns = $1; SET helo = $2; SET ip = $3; SET by = $4; DONE; /^from (\S+) \(\[(${IP_ADDRESS})\]\) by (\S+) via smtpd \(for \S+\) with SMTP\(/ SET helo = $1; SET ip = $2; SET by = $3; DONE; GIVEN /^from \S+( \((?:HELO|EHLO) \S*\))? \((\S+\@)?\[?${IP_ADDRESS}\]?\)( \(envelope-sender <\S+>\))? by \S+( \(.+\))* with (.* )?(SMTP|QMQP)/ { /^from (\S+) \((?:HELO|EHLO) ([^ \(\)]*)\) \((\S*)\@\[?(${IP_ADDRESS})\]?\)( \(envelope-sender <\S+>\))? by (\S+)/ SET rdns = $1; SET helo = $2; SET ident = $3; SET ip = $4; SET by = $6; DONE; /^from (\S+) \((?:HELO|EHLO) ([^ \(\)]*)\) \(\[?(${IP_ADDRESS})\]?\)( \(envelope-sender <\S+>\))? by (\S+)/ SET rdns = $1; SET helo = $2; SET ip = $3; SET by = $5; DONE; /^from (\S+) \((\S*)\@\[?(${IP_ADDRESS})\]?\)( \(envelope-sender <\S+>\))? by (\S+)/ SET helo = $1; SET rdns = $1; SET ident = $2; SET ip = $3; SET by = $5; DONE; /^from (\S+) \(\[?(${IP_ADDRESS})\]?\)( \(envelope-sender <\S+>\))? by (\S+)/ SET helo = $1; SET rdns = $1; SET ip = $2; SET by = $4; DONE; } /^from \[(${IP_ADDRESS})\] by (\S+) via HTTP\;/ SET ip = $1; SET by = $2; DONE; /^from (\S+) \( \[(${IP_ADDRESS})\]\).*? by (\S+) / SET ip = $2; SET by = $3; DONE; /^from \((\S+) \[(${IP_ADDRESS})\]\) by (\S+) / SET helo = $1; SET ip = $2; SET by = $3; DONE; /^from \[(${IP_ADDRESS})\] by (\S+) / SET ip = $1; SET by = $2; DONE; /^from (\S+) \[(${IP_ADDRESS})\] by (\S+) \[(\S+)\] with / SET helo = $1; SET ip = $2; SET by = $4; DONE; /^from (\S+) \(\[(${IP_ADDRESS})\]\) by (\S+) \(/ SET helo = $1; SET ip = $2; SET by = $3; DONE; # The following line does not pick up rdns; see SA's Received.pm:704 /^from (\S+) \((\S+) \[(${IP_ADDRESS})\]\).*? by (\S+) / SET helo = $1; SET ip = $3; SET by = $4; DONE; /^from (\S+) \(\[(${IP_ADDRESS})\]\).*? by (\S+) / SET helo = $1; SET ip = $2; SET by = $3; DONE; /^from (\S+) \((\S+) \[(${IP_ADDRESS})\]\)(?: \(authenticated bits=\d+\))? by (\S+) \(/ SET helo = $1; SET rdns = $2; SET ip = $3; SET by = $4; DONE; /^from (\S+) \[(${IP_ADDRESS})\] by (\S+) with \S+ \(fetchmail/ IGNORE "fetchmail"; /^from (\S+) \((?:HELO|EHLO) ([^\)]*)\) \((\S*@)?\[?(${IP_ADDRESS})\]?\).* by (\S+) / SET rdns = $1; SET helo = $2; SET ident = $3; SET ip = $4; SET by = $5; DONE; /^from (\S+) \((\S*@)?\[?(${IP_ADDRESS})\]?\).* by (\S+) / SET rdns = $1; SET helo = $1; SET ident = $2; SET ip = $3; SET by = $4; DONE; /^from \[(${IP_ADDRESS})\] by (\S+) with http for / SET ip = $1; SET by = $2; DONE; /^from (\S+) \[(${IP_ADDRESS})\] by (\S+) with POP3 / SET rdns = $1; SET ip = $2; SET by = $3; DONE; /^from (\S+)\((${IP_ADDRESS})\) by (\S+) via smap / SET rdns = $1; SET ip = $2; SET by = $3; DONE; /^from (\S+)\((${IP_ADDRESS}), (?:HELO|EHLO) (\S*)\) by (\S+) via smap / SET rdns = $1; SET ip = $2; SET helo = $3; SET by = $4; DONE; /^from \[(${IP_ADDRESS})\] by (\S+) \(Post/ SET ip = $1; SET by = $2; DONE; /^from \[(${IP_ADDRESS})\] by (\S+) \(ArGoSoft/ SET ip = $1; SET by = $2; DONE; /^from (${IP_ADDRESS}) by (\S+) \(InterScan/ SET ip = $1; SET by = $2; DONE; /^from (\S+) by (\S+) with BSMTP/ IGNORE "Not a TCP/IP handover"; /^from (\S+) \((\S+) \[(${IP_ADDRESS})\]\) by (\S+) with / SET helo = $1; SET rdns = $2; SET ip = $3; SET by = $4; DONE; GIVEN /^from (\S+) \((?:HELO|EHLO) (\S*)\) \((\S+).*?\) by (\S+) with / { SET rdns = $1; SET helo = $2; SET ip = $3; SET by = $4; ip=~s/([^\@]*)\@//g SET ident = $1; DONE; } /^from (\S+) by (\S+) with local/ IGNORE; /^from \[(${IP_ADDRESS})\] \(account \S+ (?:HELO|EHLO) (\S*)\) by (\S+) \(/ SET ip = $1; SET helo = $2; SET by = $3; DONE; /^from \(\[(${IP_ADDRESS})\]\) by (\S+) with / SET ip = $1; SET by = $2; /^from ([^\d]\S+) \((${IP_ADDRESS})\) by (\S+) / SET helo = $1; SET ip = $2; SET by = $3; DONE; /^from (\S+) \((\S+)\) by (\S+) \(Content Technologies / IGNORE "Useless without IP"; /^from (\S+) \(\[(\S+)\] \[(\S+)\]\) by (\S+) with / SET helo = $1; SET ip = $2; SET by = $4; DONE; /^from (${IP_ADDRESS}) by (\S+) with / SET ip = $1; SET by = $2; DONE; /^from (\S+) \((\S+)\[(${IP_ADDRESS})\]\) by (\S+) / SET helo = $1; SET rdns = $2; SET ip = $3; SET by = $4; DONE; /^from \[(${IP_ADDRESS})\]\S+ \((?:HELO|EHLO) (\S*)\) by (\S+) / SET ip = $1; SET helo = $2; SET by = $3; DONE; /^from (${IP_ADDRESS}) \((?:HELO|EHLO) (\S*)\) by (\S+) / SET ip = $1; SET helo = $2; SET by = $3; DONE; /^from (\S+) \[(${IP_ADDRESS})\] by (\S+) / SET helo = $1; SET ip = $2; SET by = $3; DONE; /^from (\S+)\((${IP_ADDRESS})\) by (\S+) / SET rdns = $1; SET ip = $2; SET by = $3; DONE; /^from \[(${IP_ADDRESS})\] by (\S+) \(MailGate / SET ip = $1; SET by = $2; DONE; /^from (\S+) \(unverified \[(${IP_ADDRESS})\]\) by (\S+) / SET helo = $1; SET ip = $2; SET by = $3; DONE; /^from (${IP_ADDRESS}) \([A-Za-z][^\)]+\) by (\S+) with / SET ip = $1; SET by = $2; DONE; GIVEN /^from \[(${IP_ADDRESS})\] \(([^\)]+)\) by (\S+) / { SET ip = $1; SET sub = $2; SET by = $3; sub=~s/helo=(\S+)// SET helo = $1; sub=~s/ident=(\S+)// SET ident = $1; DONE; } /^from (\S+) \((?:\S+\@)?(${IP_ADDRESS})\) by (\S+) with / SET rdns = $1; SET ip = $2; SET by = $3; DONE; /^from (\S+)\((${IP_ADDRESS})\)(?:, claiming to be "(\S+)")? via \S+ by (\S+),/ SET rdns = $1; SET ip = $2; SET helo = $3; SET by = $4; DONE; } /^FROM (\S+) \((\S+) \[(${IP_ADDRESS})\]\) BY (\S+) (?:ID (\S+) )?/ SET helo = $1; SET rdns = $2; SET ip = $3; SET by = $4; SET id = $5; DONE; /^by / IGNORE "By line, not from line!"; /^from \S+ \(\S+\@${LOCALHOST}\) by \S+ \(/ IGNORE "local"; /^from \S+ \S+ by \S+ with local-e?smtp / IGNORE "local"; /^from 127\.0\.0\.1 \(AVG SMTP \S+ \[\S+\]\); / IGNORE "local"; #/^from \S+\@\S+ by \S+ by uid \S+ / IGNORE "local"; /^from \S+\@\S+ by \S+ / IGNORE; /^from Unknown\/Local \(/ IGNORE "local"; /^from ${LOCALHOST} \((?:\S+\@)?${LOCALHOST}[\)\[]/ IGNORE "local"; /^from \S+ \((?:\S+\@)?${LOCALHOST}\) / IGNORE "local"; /^from (\S+) \(\S+\@\S+ \[${LOCALHOST}\]\) / IGNORE "local"; /^from \(AUTH: (\S+)\) by (\S+) with / IGNORE; /^from localhost \(localhost \[\[UNIX: localhost\]\]\) by / IGNORE "local"; /^Message by / IGNORE "whatever"; /^FROM \S+ BY \S+ \; / IGNORE; /^from \S+\.amazon\.com by \S+\.amazon\.com with ESMTP \(peer crosscheck: / IGNORE "internal amazon traffic"; /^from [^\.]+ by \S+ with Novell_GroupWise; / IGNORE; /^from no\.name\.available by \S+ via smtpd \(for / IGNORE "internal mail across a Raptor firewall"; /^from \S+ by \S+ (?:with|via|for|\()/ UNPARSABLE; /^from (\S+) by (\S+) *\;/ UNPARSABLE; /\bhelo=([-A-Za-z0-9\.]+)[^-A-Za-z0-9\.]/ SET helo = $1; /^from (\S+)[^-A-Za-z0-9\.]/ SET helo ||= $1; /\[(${IP_ADDRESS})\]/ SET ip = $1; / by (\S+)[^-A-Za-z0-9\;\.]/ SET by = $1; Email-Received-1.00/Makefile.PL0000644000175000017500000000117110410744736015221 0ustar simonsimonuse 5.006; use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile( NAME => 'Email::Received', VERSION_FROM => 'lib/Email/Received.pm', # finds $VERSION PREREQ_PM => { Regexp::Common => 0, Text::Balanced => 0, # Cor, it's a bit DCONWAY heavy. }, # e.g., Module::Name => 1.1 ($] >= 5.005 ? ## Add these new keywords supported since 5.005 (ABSTRACT_FROM => 'lib/Email/Received.pm', # retrieve abstract from module AUTHOR => 'simon ') : ()), ); Email-Received-1.00/README0000644000175000017500000000222710407763437014137 0ustar simonsimonEmail-Received version 0.01 =========================== The README is used to introduce the module and provide instructions on how to install the module, any machine dependencies it may have (for example C compilers and installed libraries) and any other information that should be provided before the module is installed. A README file is required for CPAN modules since CPAN extracts the README file from a module distribution so that people browsing the archive can use it get an idea of the modules uses. It is usually a good idea to provide version information here so that people can decide whether fixes for the module are worth downloading. INSTALLATION To install this module type the following: perl Makefile.PL make make test make install DEPENDENCIES This module requires these other modules and libraries: blah blah blah COPYRIGHT AND LICENCE Put the correct copyright and licence information here. Copyright (C) 2006 by simon This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.7 or, at your option, any later version of Perl 5 you may have available.