diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py
index 78966a84..68234f08 100644
--- a/src/bitmessageqt/__init__.py
+++ b/src/bitmessageqt/__init__.py
@@ -1962,6 +1962,7 @@ class MyForm(QtGui.QMainWindow):
shared.config.set(str(addressAtCurrentRow), 'mailinglistname', str(
self.dialog.ui.lineEditMailingListName.text().toUtf8()))
self.ui.tableWidgetYourIdentities.item(currentRow, 1).setTextColor(QtGui.QColor(137, 04, 177))
+ shared.config.set(str(addressAtCurrentRow), 'foremail', str(self.dialog.ui.checkBoxWrapMessagesWithEmailHeaders.isChecked()))
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
shared.config.write(configfile)
self.rerenderInboxToLabels()
@@ -2997,6 +2998,9 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog):
addressAtCurrentRow, 'mailinglistname')
except:
mailingListName = ''
+
+ self.ui.checkBoxWrapMessagesWithEmailHeaders.setChecked(
+ shared.safeConfigGetBoolean(addressAtCurrentRow, 'foremail'))
self.ui.lineEditMailingListName.setText(
unicode(mailingListName, 'utf-8'))
QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self))
diff --git a/src/bitmessageqt/specialaddressbehavior.py b/src/bitmessageqt/specialaddressbehavior.py
index 78ff890d..75360076 100644
--- a/src/bitmessageqt/specialaddressbehavior.py
+++ b/src/bitmessageqt/specialaddressbehavior.py
@@ -1,64 +1,77 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'specialaddressbehavior.ui'
-#
-# Created: Fri Apr 26 17:43:31 2013
-# by: PyQt4 UI code generator 4.9.4
-#
-# WARNING! All changes made in this file will be lost!
-
-from PyQt4 import QtCore, QtGui
-
-try:
- _fromUtf8 = QtCore.QString.fromUtf8
-except AttributeError:
- _fromUtf8 = lambda s: s
-
-class Ui_SpecialAddressBehaviorDialog(object):
- def setupUi(self, SpecialAddressBehaviorDialog):
- SpecialAddressBehaviorDialog.setObjectName(_fromUtf8("SpecialAddressBehaviorDialog"))
- SpecialAddressBehaviorDialog.resize(386, 172)
- self.gridLayout = QtGui.QGridLayout(SpecialAddressBehaviorDialog)
- self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
- self.radioButtonBehaveNormalAddress = QtGui.QRadioButton(SpecialAddressBehaviorDialog)
- self.radioButtonBehaveNormalAddress.setChecked(True)
- self.radioButtonBehaveNormalAddress.setObjectName(_fromUtf8("radioButtonBehaveNormalAddress"))
- self.gridLayout.addWidget(self.radioButtonBehaveNormalAddress, 0, 0, 1, 1)
- self.radioButtonBehaviorMailingList = QtGui.QRadioButton(SpecialAddressBehaviorDialog)
- self.radioButtonBehaviorMailingList.setObjectName(_fromUtf8("radioButtonBehaviorMailingList"))
- self.gridLayout.addWidget(self.radioButtonBehaviorMailingList, 1, 0, 1, 1)
- self.label = QtGui.QLabel(SpecialAddressBehaviorDialog)
- self.label.setWordWrap(True)
- self.label.setObjectName(_fromUtf8("label"))
- self.gridLayout.addWidget(self.label, 2, 0, 1, 1)
- self.label_2 = QtGui.QLabel(SpecialAddressBehaviorDialog)
- self.label_2.setObjectName(_fromUtf8("label_2"))
- self.gridLayout.addWidget(self.label_2, 3, 0, 1, 1)
- self.lineEditMailingListName = QtGui.QLineEdit(SpecialAddressBehaviorDialog)
- self.lineEditMailingListName.setEnabled(False)
- self.lineEditMailingListName.setObjectName(_fromUtf8("lineEditMailingListName"))
- self.gridLayout.addWidget(self.lineEditMailingListName, 4, 0, 1, 1)
- self.buttonBox = QtGui.QDialogButtonBox(SpecialAddressBehaviorDialog)
- self.buttonBox.setMinimumSize(QtCore.QSize(368, 0))
- self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
- self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
- self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
- self.gridLayout.addWidget(self.buttonBox, 5, 0, 1, 1)
-
- self.retranslateUi(SpecialAddressBehaviorDialog)
- QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), SpecialAddressBehaviorDialog.accept)
- QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), SpecialAddressBehaviorDialog.reject)
- QtCore.QObject.connect(self.radioButtonBehaviorMailingList, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.lineEditMailingListName.setEnabled)
- QtCore.QObject.connect(self.radioButtonBehaveNormalAddress, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.lineEditMailingListName.setDisabled)
- QtCore.QMetaObject.connectSlotsByName(SpecialAddressBehaviorDialog)
- SpecialAddressBehaviorDialog.setTabOrder(self.radioButtonBehaveNormalAddress, self.radioButtonBehaviorMailingList)
- SpecialAddressBehaviorDialog.setTabOrder(self.radioButtonBehaviorMailingList, self.lineEditMailingListName)
- SpecialAddressBehaviorDialog.setTabOrder(self.lineEditMailingListName, self.buttonBox)
-
- def retranslateUi(self, SpecialAddressBehaviorDialog):
- SpecialAddressBehaviorDialog.setWindowTitle(QtGui.QApplication.translate("SpecialAddressBehaviorDialog", "Special Address Behavior", None, QtGui.QApplication.UnicodeUTF8))
- self.radioButtonBehaveNormalAddress.setText(QtGui.QApplication.translate("SpecialAddressBehaviorDialog", "Behave as a normal address", None, QtGui.QApplication.UnicodeUTF8))
- self.radioButtonBehaviorMailingList.setText(QtGui.QApplication.translate("SpecialAddressBehaviorDialog", "Behave as a pseudo-mailing-list address", None, QtGui.QApplication.UnicodeUTF8))
- self.label.setText(QtGui.QApplication.translate("SpecialAddressBehaviorDialog", "Mail received to a pseudo-mailing-list address will be automatically broadcast to subscribers (and thus will be public).", None, QtGui.QApplication.UnicodeUTF8))
- self.label_2.setText(QtGui.QApplication.translate("SpecialAddressBehaviorDialog", "Name of the pseudo-mailing-list:", None, QtGui.QApplication.UnicodeUTF8))
-
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'specialaddressbehavior.ui'
+#
+# Created: Wed Jul 10 15:20:02 2013
+# by: PyQt4 UI code generator 4.10.1
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt4 import QtCore, QtGui
+
+try:
+ _fromUtf8 = QtCore.QString.fromUtf8
+except AttributeError:
+ def _fromUtf8(s):
+ return s
+
+try:
+ _encoding = QtGui.QApplication.UnicodeUTF8
+ def _translate(context, text, disambig):
+ return QtGui.QApplication.translate(context, text, disambig, _encoding)
+except AttributeError:
+ def _translate(context, text, disambig):
+ return QtGui.QApplication.translate(context, text, disambig)
+
+class Ui_SpecialAddressBehaviorDialog(object):
+ def setupUi(self, SpecialAddressBehaviorDialog):
+ SpecialAddressBehaviorDialog.setObjectName(_fromUtf8("SpecialAddressBehaviorDialog"))
+ SpecialAddressBehaviorDialog.resize(386, 186)
+ self.gridLayout = QtGui.QGridLayout(SpecialAddressBehaviorDialog)
+ self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
+ self.radioButtonBehaveNormalAddress = QtGui.QRadioButton(SpecialAddressBehaviorDialog)
+ self.radioButtonBehaveNormalAddress.setChecked(True)
+ self.radioButtonBehaveNormalAddress.setObjectName(_fromUtf8("radioButtonBehaveNormalAddress"))
+ self.gridLayout.addWidget(self.radioButtonBehaveNormalAddress, 0, 0, 1, 1)
+ self.radioButtonBehaviorMailingList = QtGui.QRadioButton(SpecialAddressBehaviorDialog)
+ self.radioButtonBehaviorMailingList.setObjectName(_fromUtf8("radioButtonBehaviorMailingList"))
+ self.gridLayout.addWidget(self.radioButtonBehaviorMailingList, 1, 0, 1, 1)
+ self.label = QtGui.QLabel(SpecialAddressBehaviorDialog)
+ self.label.setWordWrap(True)
+ self.label.setObjectName(_fromUtf8("label"))
+ self.gridLayout.addWidget(self.label, 3, 0, 1, 1)
+ self.label_2 = QtGui.QLabel(SpecialAddressBehaviorDialog)
+ self.label_2.setObjectName(_fromUtf8("label_2"))
+ self.gridLayout.addWidget(self.label_2, 4, 0, 1, 1)
+ self.lineEditMailingListName = QtGui.QLineEdit(SpecialAddressBehaviorDialog)
+ self.lineEditMailingListName.setEnabled(False)
+ self.lineEditMailingListName.setObjectName(_fromUtf8("lineEditMailingListName"))
+ self.gridLayout.addWidget(self.lineEditMailingListName, 5, 0, 1, 1)
+ self.buttonBox = QtGui.QDialogButtonBox(SpecialAddressBehaviorDialog)
+ self.buttonBox.setMinimumSize(QtCore.QSize(368, 0))
+ self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
+ self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
+ self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
+ self.gridLayout.addWidget(self.buttonBox, 6, 0, 1, 1)
+ self.checkBoxWrapMessagesWithEmailHeaders = QtGui.QCheckBox(SpecialAddressBehaviorDialog)
+ self.checkBoxWrapMessagesWithEmailHeaders.setObjectName(_fromUtf8("checkBoxWrapMessagesWithEmailHeaders"))
+ self.gridLayout.addWidget(self.checkBoxWrapMessagesWithEmailHeaders, 2, 0, 1, 1)
+
+ self.retranslateUi(SpecialAddressBehaviorDialog)
+ QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), SpecialAddressBehaviorDialog.accept)
+ QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), SpecialAddressBehaviorDialog.reject)
+ QtCore.QObject.connect(self.radioButtonBehaviorMailingList, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.lineEditMailingListName.setEnabled)
+ QtCore.QObject.connect(self.radioButtonBehaveNormalAddress, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.lineEditMailingListName.setDisabled)
+ QtCore.QMetaObject.connectSlotsByName(SpecialAddressBehaviorDialog)
+ SpecialAddressBehaviorDialog.setTabOrder(self.radioButtonBehaveNormalAddress, self.radioButtonBehaviorMailingList)
+ SpecialAddressBehaviorDialog.setTabOrder(self.radioButtonBehaviorMailingList, self.lineEditMailingListName)
+ SpecialAddressBehaviorDialog.setTabOrder(self.lineEditMailingListName, self.buttonBox)
+
+ def retranslateUi(self, SpecialAddressBehaviorDialog):
+ SpecialAddressBehaviorDialog.setWindowTitle(_translate("SpecialAddressBehaviorDialog", "Special Address Behavior", None))
+ self.radioButtonBehaveNormalAddress.setText(_translate("SpecialAddressBehaviorDialog", "Behave as a normal address", None))
+ self.radioButtonBehaviorMailingList.setText(_translate("SpecialAddressBehaviorDialog", "Behave as a pseudo-mailing-list address", None))
+ self.label.setText(_translate("SpecialAddressBehaviorDialog", "Mail received to a pseudo-mailing-list address will be automatically broadcast to subscribers (and thus will be public).", None))
+ self.label_2.setText(_translate("SpecialAddressBehaviorDialog", "Name of the pseudo-mailing-list:", None))
+ self.checkBoxWrapMessagesWithEmailHeaders.setText(_translate("SpecialAddressBehaviorDialog", "Ensure all incoming messages have standard E-mail headers", None))
+
diff --git a/src/bitmessageqt/specialaddressbehavior.ui b/src/bitmessageqt/specialaddressbehavior.ui
index eddc1184..8de5c528 100644
--- a/src/bitmessageqt/specialaddressbehavior.ui
+++ b/src/bitmessageqt/specialaddressbehavior.ui
@@ -7,7 +7,7 @@
0
0
386
- 172
+ 186
@@ -31,7 +31,7 @@
- -
+
-
Mail received to a pseudo-mailing-list address will be automatically broadcast to subscribers (and thus will be public).
@@ -41,21 +41,21 @@
- -
+
-
Name of the pseudo-mailing-list:
- -
+
-
false
- -
+
-
@@ -71,6 +71,13 @@
+ -
+
+
+ Ensure all incoming messages have standard E-mail headers
+
+
+
diff --git a/src/class_pop3Server.py b/src/class_pop3Server.py
index de27e5db..76e25358 100644
--- a/src/class_pop3Server.py
+++ b/src/class_pop3Server.py
@@ -293,7 +293,7 @@ class bitmessagePOP3Server(asyncore.dispatcher):
_ = bitmessagePOP3Connection(sock, peer_address, debug=self.debug)
@staticmethod
- def reformatMessageForEmail(toAddress, fromAddress, body, subject):
+ def reformatMessageForReceipt(toAddress, fromAddress, body, subject):
message = parser.Parser().parsestr(body)
print(message)
@@ -307,7 +307,7 @@ class bitmessagePOP3Server(asyncore.dispatcher):
flags = tmp[i-21:i]
checksum = int(flags[-4:], 16)
- # Checksum to makesure incoming message hasn't been tampered with
+ # Checksum to make sure incoming message hasn't been tampered with
c = hashlib.sha256(body).digest()[:2]
c = (ord(checksum[0]) << 8) | ord(checksum[1])
@@ -338,9 +338,7 @@ class bitmessagePOP3Server(asyncore.dispatcher):
message['From'] = fromLabel
message['Date'] = utils.formatdate()
- #if subject_is_valid and body_is_valid:
- # return body, subject
-
+ message['X-Bitmessage-Subject'] = subject
if not subject_is_valid and 'Subject' not in message:
message['Subject'] = subject
@@ -377,4 +375,102 @@ class bitmessagePOP3Server(asyncore.dispatcher):
subject = "".format(checksum) # Reserved flags.
return message_as_text, subject
-
+
+ @staticmethod
+ def addMailingListNameToSubject(subject, mailingListName):
+ withoutre = subject = subject.strip()
+ re = ''
+ if subject[:3] == 'Re:' or subject[:3] == 'RE:':
+ re = subject[:3] + ' '
+ withoutre = subject[3:].strip()
+ a = '[' + mailingListName + ']'
+ if withoutre.startswith(a):
+ return subject
+ else:
+ return re + a + ' ' + subject
+
+ @staticmethod
+ def reformatMessageForMailingList(toAddress, fromAddress, body, subject, mailingListName):
+ message = parser.Parser().parsestr(body)
+ print(message)
+
+ subject_is_valid = False
+
+ i = subject.find('= 0:
+ tmp = subject[i:]
+ i = tmp.find('>')
+ if i >= 0:
+ flags = tmp[i-21:i]
+ checksum = int(flags[-4:], 16)
+
+ # Checksum to make sure incoming message hasn't been tampered with
+ c = hashlib.sha256(body).digest()[:2]
+ c = (ord(checksum[0]) << 8) | ord(checksum[1])
+
+ # Valid Bitmessage subject line already
+ if c == checksum:
+ subject_is_valid = True
+ else:
+ with shared.printLock:
+ print 'Got E-Mail formatted message with incorrect checksum...'
+
+ # The mailing list code will override some headers, including Date and From, so
+ # that the trust can be moved from the original sender to the mailing list owner.
+ fromLabel = '{}@{}'.format(getBase58Capitaliation(fromAddress), fromAddress)
+
+ if 'From' in message:
+ originalFrom = message['From']
+ message['X-Original-From'] = originalFrom
+
+ i = originalFrom.find('<' + fromLabel + '>')
+ if i >= 0:
+ fromLabel = '{} <{}>'.format(originalFrom[:i].strip(), fromLabel)
+
+ message['From'] = fromLabel
+ message['Date'] = utils.formatdate()
+
+ message['X-Bitmessage-Subject'] = subject
+ if 'Subject' not in message:
+ if not subject_is_valid:
+ message['Subject'] = bitmessagePOP3Server.addMailingListNameToSubject(subject, mailingListName)
+ else:
+ # TODO - strip from bitmessage subject?
+ message['Subject'] = bitmessagePOP3Server.addMailingListNameToSubject('', mailingListName)
+ else:
+ message['Subject'] = bitmessagePOP3Server.addMailingListNameToSubject(message['Subject'], mailingListName)
+
+ toLabel = '{}@{}'.format(getBase58Capitaliation(toAddress), toAddress)
+ try:
+ toLabel = '{} <{}>'.format(shared.config.get(toAddress, 'label'), toLabel)
+ except:
+ pass
+
+ if 'To' in message:
+ message['X-Original-To'] = message['To']
+ message['To'] = toLabel
+
+ # X-Bitmessage-MailingList-Name
+ message['X-Bitmessage-MailingList-Name'] = mailingListName
+
+ # X-Bitmessage-MailingList-Address
+ mailingListAddress = "{}@{}".format(getBase58Capitaliation(toAddress), toAddress)
+ message['X-Bitmessage-MailingList-Address'] = mailingListAddress
+
+ # X-Bitmessage-MailingList-Version
+ message["X-Bitmessage-MailingList-Version"] = shared.softwareVersion
+
+ fp = StringIO()
+ gen = generator.Generator(fp, mangle_from_=False, maxheaderlen=128)
+ gen.flatten(message)
+
+ message_as_text = fp.getvalue()
+
+ # Checksum to makesure incoming message hasn't been tampered with
+ # TODO - if subject_is_valid, then don't completely overwrite the subject, instead include all the data outside of <> too
+ checksum = hashlib.sha256(message_as_text).digest()[:2]
+ checksum = (ord(checksum[0]) << 8) | ord(checksum[1])
+ subject = bitmessagePOP3Server.addMailingListNameToSubject("".format(checksum), mailingListAddress)
+
+ return message_as_text, subject
+
diff --git a/src/class_receiveDataThread.py b/src/class_receiveDataThread.py
index e97bdd4b..8fee0ad5 100644
--- a/src/class_receiveDataThread.py
+++ b/src/class_receiveDataThread.py
@@ -1031,17 +1031,18 @@ class receiveDataThread(threading.Thread):
body = 'Unknown encoding type.\n\n' + repr(message)
subject = ''
+ formattedBody, formattedSubject = body, subject
if isEmailAddress:
# The above 'message/subject' formatting may give us weird values if messageEncodingType is bad
- body, subject = bitmessagePOP3Server.reformatMessageForEmail(toAddress, fromAddress, body, subject)
+ formattedBody, formattedSubject = bitmessagePOP3Server.reformatMessageForReceipt(toAddress, fromAddress, body, subject)
if messageEncodingType != 0:
- t = (self.inventoryHash, toAddress, fromAddress, subject, int(
- time.time()), body, 'inbox', messageEncodingType, 0)
+ t = (self.inventoryHash, toAddress, fromAddress, formattedSubject, int(
+ time.time()), formattedBody, 'inbox', messageEncodingType, 0)
helper_inbox.insert(t)
shared.UISignalQueue.put(('displayNewInboxMessage', (
- self.inventoryHash, toAddress, fromAddress, subject, body)))
+ self.inventoryHash, toAddress, fromAddress, formattedSubject, formattedBody)))
# If we are behaving as an API then we might need to run an
# outside command to let some program know that a new message
@@ -1063,12 +1064,18 @@ class receiveDataThread(threading.Thread):
toAddress, 'mailinglistname')
except:
mailingListName = ''
- # Let us send out this message as a broadcast
- subject = self.addMailingListNameToSubject(
- subject, mailingListName)
- # Let us now send this message out as a broadcast
- message = time.strftime("%a, %Y-%m-%d %H:%M:%S UTC", time.gmtime(
- )) + ' Message ostensibly from ' + fromAddress + ':\n\n' + body
+
+ if isEmailAddress:
+ # The above 'message/subject' formatting may give us weird values if messageEncodingType is bad
+ message, subject = bitmessagePOP3Server.reformatMessageForMailingList(toAddress, fromAddress, body, subject, mailingListName)
+ else:
+ # Let us send out this message as a broadcast
+ subject = self.addMailingListNameToSubject(
+ subject, mailingListName)
+ # Let us now send this message out as a broadcast
+ message = time.strftime("%a, %Y-%m-%d %H:%M:%S UTC", time.gmtime(
+ )) + ' Message ostensibly from ' + fromAddress + ':\n\n' + body
+
fromAddress = toAddress # The fromAddress for the broadcast that we are about to send is the toAddress (my address) for the msg message we are currently processing.
ackdata = OpenSSL.rand(
32) # We don't actually need the ackdata for acknowledgement since this is a broadcast message but we can use it to update the user interface when the POW is done generating.