Last active
December 13, 2015 20:08
-
-
Save cflove/4967768 to your computer and use it in GitHub Desktop.
To accept AWS SNS calls originating from SES mail bounces and complains. http://cflove.org/2013/02/track-amazon-aws-ses-email-bounce-and-complains-with-coldfusion.cfm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfset sns = getHttpRequestData()> | |
<!---<cfif YesNoFormat(fromSNS(cgi.REMOTE_ADDR))>---> | |
<cfset sns = DeserializeJSON(sns.content)> | |
<!---- ****************************************************************** ---> | |
<!---- if subsribe request, acccept it (remove after first use) ---> | |
<!---- ****************************************************************** ---> | |
<cfif StructKeyExists(sns,'SubscribeURL')> | |
<cfhttp charset="utf-8" method="get" resolveurl="no" url="#sns.SubscribeURL#"> | |
</cfif> | |
<!---- ****************************************************************** ---> | |
<!---- Mail Bounce & Complains. sns.type, sns.subtype and sns.Recipients ---> | |
<!---- ****************************************************************** ---> | |
<cfif StructKeyExists(sns,'Message') and IsJSON(sns.Message)> | |
<cfset sns.Message = DeserializeJSON(sns.Message)> | |
<cfif StructKeyExists(sns.Message,'complaint')> | |
<cfset sns.Recipients = sns.Message.complaint.complainedRecipients> | |
<cfset sns.subtype = sns.Message.complaint.complaintFeedbackType> | |
<cfset sns.type = "complaint"> | |
</cfif> | |
<cfif StructKeyExists(sns.Message,'bounce')> | |
<cfset sns.Recipients = sns.Message.bounce.bouncedRecipients> | |
<cfset sns.subtype = sns.Message.bounce.bounceSubType> | |
<cfswitch expression="#sns.Message.bounce.bounceType#"> | |
<cfcase value="Transient"> | |
<cfset sns.type = "Our_Of_Office"> | |
</cfcase> | |
<cfcase value="Permanent"> | |
<cfset sns.type = "bounce"> | |
</cfcase> | |
</cfswitch> | |
</cfif> | |
<!---- ****************************************************************** ---> | |
<!---- Update The Dateabase ---> | |
<!---- ****************************************************************** ---> | |
<!--- update Mytable ... where messageid = '#sns.Message.mail.messageId#' ---> | |
</cfif> | |
<!---</cfif> ---> | |
<!---- ****************************************************************** ---> | |
<!---- Helpers ---> | |
<!---- ****************************************************************** ---> | |
<cffunction name="fromSNS" returntype="boolean" output="yes"> | |
<cfargument name="ip" type="string" required="yes"> | |
<cfset local.iplist ="207.171.167.101,207.171.172.6,207.171.167.25,207.171.167.26,72.21.196.64/29,72.21.198.64/29,72.21.198.72,72.21.217.0/24,204.246.160.32/28,204.246.162.32/28,54.240.198.0/24,205.251.233.32/28,205.251.233.48/29,205.251.233.160/28,205.251.233.176/29,205.251.234.32/28,87.238.84.64/29,87.238.80.64/29,54.240.197.0/24,203.83.220.24/29,203.83.220.152/29,54.240.199.0/24,27.0.1.24/29,27.0.1.152/29,54.240.200.0/24,177.72.241.96/28,177.72.241.112/28,177.72.241.160/28,177.72.241.176/28,177.72.242.96/28,177.72.242.112/28,177.72.241.16/29,177.72.242.16/29"> | |
<cfset local.out = "false"> | |
<cfloop list="#local.iplist#" index="local.i"> | |
<cfif find('/',local.i)> | |
<cfif YesNoFormat(testCidrRange(local.i,arguments.ip))> | |
<cfset local.out = "true"> | |
<cfbreak> | |
</cfif> | |
<cfelse> | |
<cfif not compare(local.i,arguments.ip)> | |
<cfset local.out = "true"> | |
<cfbreak> | |
</cfif> | |
</cfif> | |
</cfloop> | |
<cfreturn local.out> | |
</cffunction> | |
<!--- http://tech.groups.yahoo.com/group/fusebox5/message/2089 ---> | |
<cffunction name="testCidrRange" output="false" returntype="boolean"> | |
<cfargument name="CIDR" required="true" type="string"> | |
<cfargument name="TestIP" required="true" type="string"> | |
<cfset var CIDRParts = ListToArray(arguments.CIDR, "/")> | |
<cfset var CIDRAddress = ListToArray(CIDRParts[1], ".")> | |
<cfset var CIDRMask = CIDRParts[2]> | |
<cfset var TestIPAddress = ListToArray(arguments.TestIP, ".")> | |
<cfset var CIDRRealAddress = 0> | |
<cfset var CIDRRealMask = 0> | |
<cfset var TestRealAddress = 0> | |
<cfset var TestIPA = 0> | |
<cfset var TestIPB = 0> | |
<cfset var CidrA = 0> | |
<cfset var CidrB = 0> | |
<cfset var MaskA = 0> | |
<cfset var MaskB = 0> | |
<cfset var x = ""> | |
<!--- Get the integer the CIDR core address represents ---> | |
<cfset CIDRRealAddress = CIDRAddress[4]> | |
<cfset CIDRRealAddress = CIDRRealAddress | |
+ CIDRAddress[3] * 256> <!--- 2^8 ---> | |
<cfset CIDRRealAddress = CIDRRealAddress | |
+ CIDRAddress[2] * 65536> <!--- 2^16 ---> | |
<cfset CIDRRealAddress = CIDRRealAddress | |
+ CIDRAddress[1] * 16777216> <!--- 2^24 ---> | |
<!--- Get the integer representation of the test IP address ---> | |
<cfset TestRealAddress = TestIPAddress[4]> | |
<cfset TestRealAddress = TestRealAddress | |
+ TestIPAddress[3] * 256> <!--- 2^8 ---> | |
<cfset TestRealAddress = TestRealAddress | |
+ TestIPAddress[2] * 65536> <!--- 2^16 ---> | |
<cfset TestRealAddress = TestRealAddress | |
+ TestIPAddress[1] * 16777216> <!--- 2^24 ---> | |
<!--- Get the integer representation of the CIDR mask ---> | |
<cfloop from="1" to="#CIDRMask#" index="x"> | |
<cfset CIDRRealMask = CIDRRealMask + 2^(32-x) > | |
</cfloop> | |
<!--- | |
CF's BitAnd() cannot handle 32-bit unsigned integers, we will | |
break these addresses into numbers denoting their left and right | |
half bits | |
---> | |
<!--- Just the left 16 bits ---> | |
<cfset CidrA = int(CIDRRealAddress / 65536)> | |
<cfset TestIPA = int(TestRealAddress / 65536)> | |
<cfset MaskA = int(CIDRRealMask / 65536)> | |
<!--- Just the right 16 bits ---> | |
<!--- Much more efficient would be to use "mod 65536" but even | |
this does not support unsigned integers ---> | |
<cfset CidrB = CIDRRealAddress - (CidrA * 65536)> | |
<cfset TestIPB = TestRealAddress - (TestIPA * 65536)> | |
<cfset MaskB = CIDRRealMask - (MaskA * 65536)> | |
<cfif BitAnd(CidrA, MaskA) eq BitAnd(TestIPA, MaskA) | |
AND BitAnd(CidrB, MaskB) eq BitAnd(TestIPB, MaskB)> | |
<cfreturn true> | |
<cfelse> | |
<cfreturn false> | |
</cfif> | |
</cffunction> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment