summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Appelbaum <jacob@appelbaum.net>2008-07-13 17:21:57 +0000
committerJacob Appelbaum <jacob@appelbaum.net>2008-07-13 17:21:57 +0000
commit5b5e62e94894467973f0ca9d622dbbf1d2821d77 (patch)
tree435fb8e5ad2d8b987f840b09848d43ceacaa9afc
parent81dcfafba3fd0f20f1802708a9ee6240f8fd1c38 (diff)
downloadtor-5b5e62e94894467973f0ca9d622dbbf1d2821d77.tar.gz
tor-5b5e62e94894467973f0ca9d622dbbf1d2821d77.zip
Removal of gettor, it belongs in projects.
svn:r15877
-rwxr-xr-xcontrib/gettor/gettor.py141
-rwxr-xr-xcontrib/gettor/gettor_blacklist.py116
-rwxr-xr-xcontrib/gettor/gettor_requests.py86
-rwxr-xr-xcontrib/gettor/gettor_responses.py72
-rw-r--r--contrib/gettor/sample-emails/negative-DKIM-header-package-sample.eml39
-rw-r--r--contrib/gettor/sample-emails/negative-DKIM-header.eml39
-rw-r--r--contrib/gettor/sample-emails/positive-DKIM-header.eml57
7 files changed, 0 insertions, 550 deletions
diff --git a/contrib/gettor/gettor.py b/contrib/gettor/gettor.py
deleted file mode 100755
index c687665a2f..0000000000
--- a/contrib/gettor/gettor.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/usr/bin/python2.5
-# -*- coding: utf-8 -*-
-"""
-
- gettor.py by Jacob Appelbaum <jacob@appelbaum.net>
- This program will hand out Tor via email to supported systems.
- This program is Free Software released under the GPLv3.
-
- It is intended to be used in a .forward file as part of a pipe like so:
-
- cat <<'EOF'> .forward
- |/usr/local/bin/gettor.py
- EOF
-
- You should have a dist/current/ mirror in a directory that gettor can read.
- Such a mirror can be created like so:
-
- cd /usr/local/
- rsync -av rsync://rsync.torproject.org/tor/dist/current tor-dist-current/
-
- You can keep it updated with a cronjob like so:
-
- MirrorDir=/usr/local/tor-dist-current/
- 0 3 * * * rsync -a rsync://rsync.torproject.org/tor/dist/current/ $MirrorDir
-
- You should ensure that for each file and signature pair you wish to
- distribute, you have created a zip file containing both.
-
- While this program isn't written in a threaded manner per se, it is designed to function
- as if it will be called as a pipe many times at once. There is a slight
- desynchronization with blacklist entry checking and may result in false
- negatives. This isn't perfect but it is designed to be lightweight. It could
- be fixed easily with a shared locking system but this isn't implemented yet.
-
-"""
-
-__program__ = 'gettor.py'
-__version__ = '20080713.00'
-__url__ = 'https://tor-svn.freehaven.net/svn/tor/trunk/contrib/gettor/'
-__author__ = 'Jacob Appelbaum <jacob@appelbaum.net>'
-__copyright__ = 'Copyright (c) 2008, Jacob Appelbaum'
-__license__ = 'See LICENSE for licensing information'
-
-try:
- from future import antigravity
-except ImportError:
- antigravity = None
-
-import syslog
-import gettor_blacklist
-import gettor_requests
-import gettor_responses
-
-if __name__ == "__main__":
-
- rawMessage = gettor_requests.getMessage()
- parsedMessage = gettor_requests.parseMessage(rawMessage)
-
- if not parsedMessage:
- syslog.syslog("gettor: No parsed message. Dropping message.")
- print "gettor: No parsed message. Dropping message."
- exit(1)
-
- signature = False
- signature = gettor_requests.verifySignature(rawMessage)
- print "Signature is : " + str(signature)
- replyTo = False
- srcEmail = "gettor@torproject.org"
-
- # TODO XXX:
- # Make the zip files and ensure they match packageList
- # Make each zip file like so:
- # zip -9 windows-bindle.z \
- # vidalia-bundle-0.2.0.29-rc-0.1.6.exe \
- # vidalia-bundle-0.2.0.29-rc-0.1.6.exe.asc
- #
- packageList = {
- "windows-bundle": "/tmp/windows-bundle.z",
- "macosx-bundle": "/tmp/macosx-bundle.z",
- "linux-bundle": "/tmp/linux-bundle.z",
- "source-bundle": "/tmp/source-bundle.z"
- }
-
- # XXX TODO: Ensure we have a proper replyTO or bail out (majorly malformed mail).
- replyTo = gettor_requests.parseReply(parsedMessage)
-
- if not signature:
- # Check to see if we've helped them to understand that they need DKIM in the past
- previouslyHelped = gettor_blacklist.blackList(replyTo)
-
- if not replyTo:
- syslog.syslog("No help dispatched. Invalid reply address for user.")
- print "No help dispatched. Invalid reply address for user."
- exit(1)
-
- if not signature and previouslyHelped:
- syslog.syslog("gettor: Unsigned messaged to gettor by blacklisted user dropped.")
- print "No help dispatched. Unsigned and unhelped for blacklisted user."
- exit(1)
-
- if not signature and not previouslyHelped:
- # Reply with some help and bail out
- # Someday call blackList(replyTo)
- message = """
- You should try your request again with a provider that implements DKIM. Sorry.
- """
- gettor_responses.sendHelp(message, srcEmail, replyTo)
- print "attempting to send email from: " + srcEmail + "The mail is sent to: " + replyTo
- syslog.syslog("gettor: Unsigned messaged to gettor. We issued some help about using DKIM.")
- print "gettor: Unsigned messaged to gettor. We issued some help about using DKIM."
- exit(0)
-
- if signature:
- syslog.syslog("gettor: Signed messaged to gettor.")
- print "gettor: Signed messaged to gettor."
-
- try:
- print "gettor: Parsing now."
- package = gettor_requests.parseRequest(parsedMessage, packageList)
- except:
- package = None
-
- if package == "windows-bundle":
- print "gettor: " + package + " selected."
- syslog.syslog("gettor: " + package + " selected.")
- message = "Here's your requested software as a zip file. Please \
- verify the signature."
- print "attempting to send email from: " +
- srcEmail + "The mail is sent to: " + replyTo
- gettor_responses.sendPackage(message, srcEmail, replyTo, packageList[package])
- exit(0)
- else:
- print "Package request is unknown: " + package
- message = " Your request was misunderstood. Please select one of the \
- following packages: " + packageList.keys()
-
- gettor_responses.sendHelp(message, srcEmail, replyTo)
- print "attempting to send email from: " + srcEmail + "The mail is sent to: " + replyTo
- syslog.syslog("gettor: Signed messaged to gettor. We issued some help about proper email formatting.")
- print "gettor: Signed messaged to gettor. We issued some help about proper email formatting."
- exit(0)
diff --git a/contrib/gettor/gettor_blacklist.py b/contrib/gettor/gettor_blacklist.py
deleted file mode 100755
index f31327ead3..0000000000
--- a/contrib/gettor/gettor_blacklist.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/python2.5
-"""
-This library implements all of the black listing features needed for gettor.
-"""
-
-import hashlib
-import os
-
-stateDir = "/tmp/gettor/"
-blStateDir = stateDir + "bl/"
-
-def blackList(address, createEntry=False):
- """
- Check to see if an address is on our blacklist. If it is - we'll return true.
- If requested, we'll attempt to create a blacklist entry and return true if
- everything works out.
- """
- # XXX TODO: Eventually we may want to sort entries with netcom
- # style /tmp/gettor/2-digits-of-hash/2-more-digits/rest-of-hash files
-
- privateAddress = makeAddressPrivate(address)
- blackListed = lookupBlackListEntry(privateAddress)
-
- if blackListed:
- return True
- elif createEntry:
- return createBlackListEntry(privateAddress)
-
- return False
-
-def lookupBlackListEntry(privateAddress, stateDir="/tmp/gettor/bl/"):
- """ Check to see if we have a blacklist entry for the given address. """
- entry = stateDir + str(privateAddress)
- try:
- entry = os.stat(entry)
- except OSError:
- return False
- return True
-
-def createBlackListEntry(privateAddress, stateDir="/tmp/gettor/bl/"):
- """ Create a zero byte file that represents the address in our blacklist. """
- entry = stateDir + str(privateAddress)
- stat = None
- try:
- stat = os.stat(entry)
- except OSError:
- try:
- fd = open(entry, 'w')
- fd.close()
- return True
- except:
- print "Entry not found. We were unable to create an entry."
- return False
- print "It appears that we already had an entry."
- return False
-
-def removeBlackListEntry(privateAddress, stateDir="/tmp/gettor/bl/"):
- """ Remove the zero byte file that represents an entry in our blacklist."""
- entry = stateDir + str(privateAddress)
- stat = None
- try:
- entry = os.unlink(entry)
- except OSError:
- return False
- return True
-
-def makeAddressPrivate(address):
- """ Creates a unique identifier for the user. """
- hash = hashlib.sha1(address)
- privateAddress = hash.hexdigest()
- return privateAddress
-
-def prepBLStateDir(stateDir = "/tmp/gettor/bl/"):
- print "Preparing the state directory for gettor."
- stat = None
- try:
- stat = os.stat(stateDir)
- print "We found a state directory"
- return True
- except OSError:
- try:
- os.mkdir(stateDir)
- print "No state directory was found, we created one"
- return True
- except:
- print "Unable to make a state directory"
- return False
-
-def blackListtests(address):
- """ This is a basic evaluation of our blacklist functionality """
- prepBLStateDir()
- privateAddress = makeAddressPrivate(address)
- print "We have a private address of: " + privateAddress
- print "Testing creation of blacklist entry: "
- blackListEntry = createBlackListEntry(privateAddress)
- print blackListEntry
- print "We're testing a lookup of a known positive blacklist entry: "
- blackListEntry = lookupBlackListEntry(privateAddress)
- print blackListEntry
- print "We're testing removal of a known blacklist entry: "
- blackListEntry = removeBlackListEntry(privateAddress)
- print blackListEntry
- print "We're testing a lookup of a known false blacklist entry: "
- blackListEntry = lookupBlackListEntry(privateAddress)
- print blackListEntry
- print "Now we'll test the higher level blacklist functionality..."
- print "This should not find an entry in the blacklist: "
- print blackList(address)
- print "This should add an entry to the blacklist: "
- print blackList(address, True)
- print "This should find the previous addition to the blacklist: "
- print blackList(address)
- print "Please ensure the tests match what you would expect for your environment."
-
-if __name__ == "__main__" :
- blackListtests("requestingUser@example.com")
diff --git a/contrib/gettor/gettor_requests.py b/contrib/gettor/gettor_requests.py
deleted file mode 100755
index 06df1c5424..0000000000
--- a/contrib/gettor/gettor_requests.py
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/usr/bin/python2.5
-# -*- coding: utf-8 -*-
-"""
-This library implements all of the email parsing features needed for gettor.
-"""
-
-import sys
-import email
-import dkim
-import re
-
-def getMessage():
- """ Read the message into a buffer and return it """
- rawMessage = sys.stdin.read()
- return rawMessage
-
-def verifySignature(rawMessage):
- """ Attempt to verify the DKIM signature of a message and return a positive or negative status """
- signature = False
-
- # TODO XXX:
- # This should catch DNS exceptions and fail to verify if we have a
- # dns timeout
- if dkim.verify(rawMessage):
- signature = True
- return signature
- else:
- return signature
-
-def parseMessage(message):
- """ parse an email message and return a parsed email object """
- return email.message_from_string(message)
-
-def parseReply(parsedMessage):
- """ Return an email address that we want to email """
- # TODO XXX:
- # Scrub this data
- address = parsedMessage["from"]
- return address
-
-def parseRequest(parsedMessage, packages):
- """ This parses the request and returns the first specific package name for
- sending. If we do not understand the request, we return None as the package
- name."""
- # XXX TODO:
- # Should we pick only the first line of the email body. Drop the rest?
- # It may be too unfriendly to our users
- for line in email.Iterators.body_line_iterator(parsedMessage):
- for package in packages.keys():
- print "Line is: " + line
- print "Package is " + package
- match = re.match(package, line)
- if match:
- return package
- # If we get here, we didn't find a package we're currently serving
- return None
-
-if __name__ == "__main__" :
- """ Give us an email to understand what we think of it. """
- packageList = {
- "windows-bundle": "/tmp/windows-bundle.z",
- "macosx-bundle": "/tmp/macosx-bundle.z",
- "linux-bundle": "/tmp/linux-bundle.z",
- "source-bundle": "/tmp/source-bundle.z"
- }
-
- print "Fetching raw message."
- rawMessage = getMessage()
- # This doesn't work without DNS ( no wifi on board current airplane )
- print "Verifying signature of message."
- signature = verifySignature(rawMessage)
- print "Parsing Message."
- parsedMessage = parseMessage(rawMessage)
- print "Parsing reply."
- parsedReply = parseReply(parsedMessage)
- print "Parsing package request."
- package = parseRequest(parsedMessage, packageList)
- if package == None:
- package = "help"
- else:
- package = packageList[package]
-
- print "The signature status of the email is: " + str(signature)
- print "The email requested the following reply address: " + parsedReply
- print "It looks like the email requested the following package: " + package
- print "We would select the following package file: " + package
diff --git a/contrib/gettor/gettor_responses.py b/contrib/gettor/gettor_responses.py
deleted file mode 100755
index 4e6ba80ba0..0000000000
--- a/contrib/gettor/gettor_responses.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/python2.5
-# -*- coding: utf-8 -*-
-""" This library implements all of the email replying features needed for gettor. """
-
-import smtplib
-import MimeWriter
-import syslog
-import StringIO
-import base64
-
-def sendHelp(message, source, destination):
- """ Send a helpful message to the user interacting with us """
- help = constructMessage(message, source, destination)
- try:
- print "Attempting to send the following message: "
- status = sendMessage(help, source, destination)
- except:
- print "Message sending failed."
- status = False
- return status
-
-def sendPackage(message, source, destination, filelist):
- """ Send a message with an attachment to the user interacting with us """
- package = constructMessage(message, source, destination, filelist)
- try:
- print "Attempting to send the following message: "
- status = sendMessage(package, destination)
- except:
- print "Message sending failed."
- status = False
- return status
-
-def constructMessage(messageText, ourAddress, recipient, fileList=None, fileName="requested-files.z"):
- """ Construct a multi-part mime message, including only the first part
- with plaintext."""
-
- message = StringIO.StringIO()
- mime = MimeWriter.MimeWriter(message)
- mime.addheader('MIME-Version', '1.0')
- mime.addheader('Subject', 'Your request has been processed')
- mime.addheader('To', recipient)
- mime.addheader('From', ourAddress)
- mime.startmultipartbody('mixed')
-
- firstPart = mime.nextpart()
- emailBody = firstPart.startbody('text/plain')
- emailBody.write(messageText)
-
- # Add a file if we have one
- if fileList:
- # XXX TODO: Iterate over each file eventually
- filePart = mime.nextpart()
- filePart.addheader('Content-Transfer-Encoding', 'base64')
- emailBody = filePart.startbody('application/zip; name=%s' % fileName)
- base64.encode(open(fileList, 'rb'), emailBody)
-
- # Now end the mime messsage
- mime.lastpart()
- return message
-
-def sendMessage(message, dst, src="gettor@torproject.org", smtpserver="localhost:2700"):
- try:
- smtp = smtplib.SMTP(smtpserver)
- smtp.sendmail(src, dst, message.getvalue())
- smtp.quit()
- status = True
- except:
- return False
-
- return status
-
-
diff --git a/contrib/gettor/sample-emails/negative-DKIM-header-package-sample.eml b/contrib/gettor/sample-emails/negative-DKIM-header-package-sample.eml
deleted file mode 100644
index ac113e88b0..0000000000
--- a/contrib/gettor/sample-emails/negative-DKIM-header-package-sample.eml
+++ /dev/null
@@ -1,39 +0,0 @@
-X-Account-Key: account6
-X-UIDL: 1215752284.31537.faustus,S=1469
-X-Mozilla-Status: 0001
-X-Mozilla-Status2: 02000000
-Return-Path: <jacob@appelbaum.net>
-Delivered-To: jpopped@appelbaum.net
-Received: (qmail 31535 invoked by uid 89); 11 Jul 2008 04:58:04 -0000
-Delivered-To: appelbaum.net-jacob@appelbaum.net
-Received: (qmail 31531 invoked by uid 89); 11 Jul 2008 04:58:04 -0000
-Received: from unknown (HELO moria.seul.org) (128.31.0.34)
- by 0 with (DHE-RSA-AES256-SHA encrypted) SMTP; 11 Jul 2008 04:58:04 -0000
-Received-SPF: none (0: domain at appelbaum.net does not designate permitted sender hosts)
-Received: by moria.seul.org (Postfix)
- id F09581415CD3; Fri, 11 Jul 2008 00:55:45 -0400 (EDT)
-Delivered-To: gettor@seul.org
-Received: from mail.lostinthenoise.net (mail.lostinthenoise.net [64.142.98.226])
- (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
- (No client certificate requested)
- by moria.seul.org (Postfix) with ESMTP id C464A140F476
- for <gettor@torproject.org>; Fri, 11 Jul 2008 00:55:45 -0400 (EDT)
-Received: (qmail 31524 invoked by uid 89); 11 Jul 2008 04:58:02 -0000
-Received: from unknown (HELO ?127.0.0.1?) (64.142.98.226)
- by 0 with (DHE-RSA-AES256-SHA encrypted) SMTP; 11 Jul 2008 04:58:02 -0000
-Message-ID: <4876E7D0.5050201@appelbaum.net>
-Date: Thu, 10 Jul 2008 21:55:44 -0700
-From: Jacob Appelbaum <jacob@appelbaum.net>
-User-Agent: Icedove 1.5.0.14eol (X11/20080509)
-MIME-Version: 1.0
-To: gettor@torproject.org
-Subject: negative DKIM signature
-X-Enigmail-Version: 0.94.2.0
-OpenPGP: id=9D0FACE4;
- url=http://www.appelbaum.net/gpg.asc
-Content-Type: text/plain; charset=ISO-8859-1
-Content-Transfer-Encoding: 7bit
-
-source-bundle
-
-
diff --git a/contrib/gettor/sample-emails/negative-DKIM-header.eml b/contrib/gettor/sample-emails/negative-DKIM-header.eml
deleted file mode 100644
index 543d695e2a..0000000000
--- a/contrib/gettor/sample-emails/negative-DKIM-header.eml
+++ /dev/null
@@ -1,39 +0,0 @@
-X-Account-Key: account6
-X-UIDL: 1215752284.31537.faustus,S=1469
-X-Mozilla-Status: 0001
-X-Mozilla-Status2: 02000000
-Return-Path: <jacob@appelbaum.net>
-Delivered-To: jpopped@appelbaum.net
-Received: (qmail 31535 invoked by uid 89); 11 Jul 2008 04:58:04 -0000
-Delivered-To: appelbaum.net-jacob@appelbaum.net
-Received: (qmail 31531 invoked by uid 89); 11 Jul 2008 04:58:04 -0000
-Received: from unknown (HELO moria.seul.org) (128.31.0.34)
- by 0 with (DHE-RSA-AES256-SHA encrypted) SMTP; 11 Jul 2008 04:58:04 -0000
-Received-SPF: none (0: domain at appelbaum.net does not designate permitted sender hosts)
-Received: by moria.seul.org (Postfix)
- id F09581415CD3; Fri, 11 Jul 2008 00:55:45 -0400 (EDT)
-Delivered-To: gettor@seul.org
-Received: from mail.lostinthenoise.net (mail.lostinthenoise.net [64.142.98.226])
- (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
- (No client certificate requested)
- by moria.seul.org (Postfix) with ESMTP id C464A140F476
- for <gettor@torproject.org>; Fri, 11 Jul 2008 00:55:45 -0400 (EDT)
-Received: (qmail 31524 invoked by uid 89); 11 Jul 2008 04:58:02 -0000
-Received: from unknown (HELO ?127.0.0.1?) (64.142.98.226)
- by 0 with (DHE-RSA-AES256-SHA encrypted) SMTP; 11 Jul 2008 04:58:02 -0000
-Message-ID: <4876E7D0.5050201@appelbaum.net>
-Date: Thu, 10 Jul 2008 21:55:44 -0700
-From: Jacob Appelbaum <jacob@appelbaum.net>
-User-Agent: Icedove 1.5.0.14eol (X11/20080509)
-MIME-Version: 1.0
-To: gettor@torproject.org
-Subject: negative DKIM signature
-X-Enigmail-Version: 0.94.2.0
-OpenPGP: id=9D0FACE4;
- url=http://www.appelbaum.net/gpg.asc
-Content-Type: text/plain; charset=ISO-8859-1
-Content-Transfer-Encoding: 7bit
-
-testing
-
-
diff --git a/contrib/gettor/sample-emails/positive-DKIM-header.eml b/contrib/gettor/sample-emails/positive-DKIM-header.eml
deleted file mode 100644
index 6ada7d7572..0000000000
--- a/contrib/gettor/sample-emails/positive-DKIM-header.eml
+++ /dev/null
@@ -1,57 +0,0 @@
-X-Account-Key: account6
-X-UIDL: 1214981061.25808.faustus,S=2285
-X-Mozilla-Status: 0001
-X-Mozilla-Status2: 02000000
-Return-Path: <ioerror@gmail.com>
-Delivered-To: jpopped@appelbaum.net
-Received: (qmail 25806 invoked by uid 89); 2 Jul 2008 06:44:21 -0000
-Delivered-To: appelbaum.net-jacob@appelbaum.net
-Received: (qmail 25804 invoked by uid 89); 2 Jul 2008 06:44:21 -0000
-Received: from unknown (HELO wa-out-1112.google.com) (209.85.146.180)
- by 0 with SMTP; 2 Jul 2008 06:44:21 -0000
-Received-SPF: pass (0: SPF record at _spf.google.com designates 209.85.146.180 as permitted sender)
-Received: by wa-out-1112.google.com with SMTP id j40so170432wah.1
- for <jacob@appelbaum.net>; Tue, 01 Jul 2008 23:42:01 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=gamma;
- h=domainkey-signature:received:received:message-id:date:from:to
- :subject:mime-version:content-type;
- bh=IvFqNkffeoST7vamh2ytuq/b7GpLhg2hStTrQq3I3rE=;
- b=xQR0hE/J4AXpAqH1UDXTtDrU9Izc6WM8vtFudRBzldWYyRx3Vvfh2I2Opu8+O6wbAv
- jlDi18anUMbZqlIGSgGOxvXW4CltpX/SFZm1aGL4AisQ1Bi5xEqlrc8OnX3sA2xKeM3g
- KWsWm+GVSMI4XAqnY9FYAfPx4DmOAfkdMyWCU=
-DomainKey-Signature: a=rsa-sha1; c=nofws;
- d=gmail.com; s=gamma;
- h=message-id:date:from:to:subject:mime-version:content-type;
- b=kyzDtGRDbiC5y4Bz/ylQjyHOChiOP2A6QDzybsVXc0C1hjHLImOQYR8gOxcRY+mRkN
- 1xpBaEF4UloZAxTb79khRRp4TWmjT1DagtLx2MFzIj/F6awtdE/9U3p4QyKr8S43tGcE
- ET26BSfT5u9zrXblVVAP3JedMPZ8mlIGQxyDs=
-Received: by 10.115.90.1 with SMTP id s1mr6711509wal.51.1214980921268;
- Tue, 01 Jul 2008 23:42:01 -0700 (PDT)
-Received: by 10.114.184.16 with HTTP; Tue, 1 Jul 2008 23:41:57 -0700 (PDT)
-Message-ID: <7fadd8130807012341n3b3af401mbdb4a29c80310bd3@mail.gmail.com>
-Date: Tue, 1 Jul 2008 23:41:57 -0700
-From: "Jacob Applebaum" <ioerror@gmail.com>
-To: jacob@appelbaum.net
-Subject: Positive DKIM header
-MIME-Version: 1.0
-Content-Type: multipart/alternative;
- boundary="----=_Part_462_28562233.1214980917793"
-
-------=_Part_462_28562233.1214980917793
-Content-Type: text/plain; charset=ISO-8859-1
-Content-Transfer-Encoding: 7bit
-Content-Disposition: inline
-
-This email should have a positive DKIM header.
-
-------=_Part_462_28562233.1214980917793
-Content-Type: text/html; charset=ISO-8859-1
-Content-Transfer-Encoding: 7bit
-Content-Disposition: inline
-
-This email should have a positive DKIM header.<br>
-
-------=_Part_462_28562233.1214980917793--
-
-