New address format that uses a capitalization int as the username. This takes care of possible case-insenstive email clients.

This commit is contained in:
Chuck 2013-07-05 02:41:07 +07:00
parent 3855b6c3c7
commit 7434913727
6 changed files with 131 additions and 24 deletions

View File

@ -199,6 +199,26 @@ def addBMIfNotPresent(address):
else: else:
return address return address
def getBase58Capitaliation(address):
if address[:3] == 'BM-':
address = address[3:]
i = []
for c in address:
i.append('1' if c.isupper() else '0')
return int(''.join(i), 2)
def applyBase58Capitalization(address, capitalization):
address = address.lower()
if address.startswith('bm-'):
address = address[3:]
n = []
for i, c in enumerate(address):
if (capitalization & (1 << (len(address)-i-1))) != 0:
n.append(c.upper())
else:
n.append(c)
return 'BM-' + ''.join(n)
def addressStream(address): def addressStream(address):
#returns the stream number of an address or False if there is a problem with the address. #returns the stream number of an address or False if there is a problem with the address.

View File

@ -2873,7 +2873,6 @@ class settingsDialog(QtGui.QDialog):
def comboBoxEmailIdentitiesChanged(self, comboBoxIndex): def comboBoxEmailIdentitiesChanged(self, comboBoxIndex):
address = str(self.ui.comboBoxEmailIdentities.itemData(comboBoxIndex).toPyObject()) address = str(self.ui.comboBoxEmailIdentities.itemData(comboBoxIndex).toPyObject())
self.ui.labelEmailIdentity.setText(address)
try: try:
shared.config.get(address, 'smtppop3password') shared.config.get(address, 'smtppop3password')
@ -2883,6 +2882,8 @@ class settingsDialog(QtGui.QDialog):
self.ui.labelAccountStatus.setText('Account inaccessible via SMTP/POP3. Set a password to grant access.') self.ui.labelAccountStatus.setText('Account inaccessible via SMTP/POP3. Set a password to grant access.')
self.ui.pushButtonClearPassword.setEnabled(False) self.ui.pushButtonClearPassword.setEnabled(False)
self.ui.lineEditEmailAddress.setText('{}@{}'.format(getBase58Capitaliation(address), address))
def click_ClearPassword(self): def click_ClearPassword(self):
comboBoxIndex = self.ui.comboBoxEmailIdentities.currentIndex() comboBoxIndex = self.ui.comboBoxEmailIdentities.currentIndex()
address = str(self.ui.comboBoxEmailIdentities.itemData(comboBoxIndex).toPyObject()) address = str(self.ui.comboBoxEmailIdentities.itemData(comboBoxIndex).toPyObject())

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'settings.ui' # Form implementation generated from reading ui file 'settings.ui'
# #
# Created: Thu Jul 04 16:56:12 2013 # Created: Fri Jul 05 01:56:20 2013
# by: PyQt4 UI code generator 4.10.1 # by: PyQt4 UI code generator 4.10.1
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -253,12 +253,9 @@ class Ui_settingsDialog(object):
self.labelAccountStatus = QtGui.QLabel(self.groupBox_3) self.labelAccountStatus = QtGui.QLabel(self.groupBox_3)
self.labelAccountStatus.setObjectName(_fromUtf8("labelAccountStatus")) self.labelAccountStatus.setObjectName(_fromUtf8("labelAccountStatus"))
self.horizontalLayout_2.addWidget(self.labelAccountStatus) self.horizontalLayout_2.addWidget(self.labelAccountStatus)
self.gridLayout_9.addLayout(self.horizontalLayout_2, 1, 0, 1, 3) self.gridLayout_9.addLayout(self.horizontalLayout_2, 2, 0, 1, 2)
spacerItem10 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) spacerItem10 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_9.addItem(spacerItem10, 0, 2, 1, 1) self.gridLayout_9.addItem(spacerItem10, 0, 1, 1, 1)
self.labelEmailIdentity = QtGui.QLabel(self.groupBox_3)
self.labelEmailIdentity.setObjectName(_fromUtf8("labelEmailIdentity"))
self.gridLayout_9.addWidget(self.labelEmailIdentity, 0, 1, 1, 1)
self.comboBoxEmailIdentities = QtGui.QComboBox(self.groupBox_3) self.comboBoxEmailIdentities = QtGui.QComboBox(self.groupBox_3)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -267,6 +264,29 @@ class Ui_settingsDialog(object):
self.comboBoxEmailIdentities.setSizePolicy(sizePolicy) self.comboBoxEmailIdentities.setSizePolicy(sizePolicy)
self.comboBoxEmailIdentities.setObjectName(_fromUtf8("comboBoxEmailIdentities")) self.comboBoxEmailIdentities.setObjectName(_fromUtf8("comboBoxEmailIdentities"))
self.gridLayout_9.addWidget(self.comboBoxEmailIdentities, 0, 0, 1, 1) self.gridLayout_9.addWidget(self.comboBoxEmailIdentities, 0, 0, 1, 1)
self.horizontalLayout_5 = QtGui.QHBoxLayout()
self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5"))
self.label_18 = QtGui.QLabel(self.groupBox_3)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(1)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_18.sizePolicy().hasHeightForWidth())
self.label_18.setSizePolicy(sizePolicy)
self.label_18.setMaximumSize(QtCore.QSize(153, 16777215))
self.label_18.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.label_18.setObjectName(_fromUtf8("label_18"))
self.horizontalLayout_5.addWidget(self.label_18)
self.lineEditEmailAddress = QtGui.QLineEdit(self.groupBox_3)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lineEditEmailAddress.sizePolicy().hasHeightForWidth())
self.lineEditEmailAddress.setSizePolicy(sizePolicy)
self.lineEditEmailAddress.setMinimumSize(QtCore.QSize(0, 0))
self.lineEditEmailAddress.setReadOnly(True)
self.lineEditEmailAddress.setObjectName(_fromUtf8("lineEditEmailAddress"))
self.horizontalLayout_5.addWidget(self.lineEditEmailAddress)
self.gridLayout_9.addLayout(self.horizontalLayout_5, 1, 0, 1, 2)
self.gridLayout_8.addWidget(self.groupBox_3, 7, 0, 1, 4) self.gridLayout_8.addWidget(self.groupBox_3, 7, 0, 1, 4)
self.label_17 = QtGui.QLabel(self.tab_3) self.label_17 = QtGui.QLabel(self.tab_3)
self.label_17.setObjectName(_fromUtf8("label_17")) self.label_17.setObjectName(_fromUtf8("label_17"))
@ -376,7 +396,8 @@ class Ui_settingsDialog(object):
self.pushButtonSetPassword.setText(_translate("settingsDialog", "Set Password...", None)) self.pushButtonSetPassword.setText(_translate("settingsDialog", "Set Password...", None))
self.pushButtonClearPassword.setText(_translate("settingsDialog", "Clear Password", None)) self.pushButtonClearPassword.setText(_translate("settingsDialog", "Clear Password", None))
self.labelAccountStatus.setText(_translate("settingsDialog", "Account Inaccessible via SMTP/POP3. Set a password to allow access.", None)) self.labelAccountStatus.setText(_translate("settingsDialog", "Account Inaccessible via SMTP/POP3. Set a password to allow access.", None))
self.labelEmailIdentity.setText(_translate("settingsDialog", "TextLabel", None)) self.label_18.setText(_translate("settingsDialog", "E-Mail Address for this Identity:", None))
self.lineEditEmailAddress.setText(_translate("settingsDialog", "fsdpffffffffffffffffffffffffffffffffffffffffffffffasdpofiasjdf", None))
self.label_17.setText(_translate("settingsDialog", "POP3 Port", None)) self.label_17.setText(_translate("settingsDialog", "POP3 Port", None))
self.label_16.setText(_translate("settingsDialog", "SMTP Port:", None)) self.label_16.setText(_translate("settingsDialog", "SMTP Port:", None))
self.checkBoxEnablePOP3SSL.setText(_translate("settingsDialog", "SSL", None)) self.checkBoxEnablePOP3SSL.setText(_translate("settingsDialog", "SSL", None))

View File

@ -526,7 +526,7 @@
<string>Identities</string> <string>Identities</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_9"> <layout class="QGridLayout" name="gridLayout_9">
<item row="1" column="0" colspan="3"> <item row="2" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
<widget class="QPushButton" name="pushButtonSetPassword"> <widget class="QPushButton" name="pushButtonSetPassword">
@ -564,7 +564,7 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="0" column="2"> <item row="0" column="1">
<spacer name="horizontalSpacer_8"> <spacer name="horizontalSpacer_8">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -577,13 +577,6 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="0" column="1">
<widget class="QLabel" name="labelEmailIdentity">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QComboBox" name="comboBoxEmailIdentities"> <widget class="QComboBox" name="comboBoxEmailIdentities">
<property name="sizePolicy"> <property name="sizePolicy">
@ -594,6 +587,54 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_18">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>153</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>E-Mail Address for this Identity:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditEmailAddress">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>fsdpffffffffffffffffffffffffffffffffffffffffffffffasdpofiasjdf</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View File

@ -161,7 +161,12 @@ class bitmessagePOP3Connection(asyncore.dispatcher):
if self.loggedin: if self.loggedin:
raise Exception("Cannot login twice") raise Exception("Cannot login twice")
self.address = data if '@' not in data:
yield "-ERR access denied"
return
capitalization, address = data.split('@', 1)
self.address = applyBase58Capitalization(address, int(capitalization))
status, addressVersionNumber, streamNumber, ripe = decodeAddress(self.address) status, addressVersionNumber, streamNumber, ripe = decodeAddress(self.address)
if status != 'success': if status != 'success':
@ -176,7 +181,12 @@ class bitmessagePOP3Connection(asyncore.dispatcher):
shared.printLock.release() shared.printLock.release()
raise Exception("Invalid Bitmessage address: {}".format(self.address)) raise Exception("Invalid Bitmessage address: {}".format(self.address))
self.address = addBMIfNotPresent(self.address) username = '{}@{}'.format(getBase58Capitaliation(self.address), self.address)
# Must login with the full E-mail address
if data != username:
yield "-ERR access denied"
return
# Each identity must be enabled independly by setting the smtppop3password for the identity # Each identity must be enabled independly by setting the smtppop3password for the identity
# If no password is set, then the identity is not available for SMTP/POP3 access. # If no password is set, then the identity is not available for SMTP/POP3 access.

View File

@ -131,12 +131,20 @@ class bitmessageSMTPChannel(asynchat.async_chat):
self.close_when_done() self.close_when_done()
return return
z, self.address, pw = base64.b64decode(pw).split('\x00') z, username, pw = base64.b64decode(pw).split('\x00')
if z != '': if z != '':
self.push('501 encoding not understood') self.push('501 encoding not understood')
self.close_when_done() self.close_when_done()
return return
if '@' not in username:
self.push('530 Access denied.')
self.close_when_done()
return
capitalization, address = username.split('@', 1)
self.address = applyBase58Capitalization(address, int(capitalization))
status, addressVersionNumber, streamNumber, ripe = decodeAddress(self.address) status, addressVersionNumber, streamNumber, ripe = decodeAddress(self.address)
if status != 'success': if status != 'success':
shared.printLock.acquire() shared.printLock.acquire()
@ -150,7 +158,12 @@ class bitmessageSMTPChannel(asynchat.async_chat):
shared.printLock.release() shared.printLock.release()
raise Exception("Invalid Bitmessage address: {}".format(self.address)) raise Exception("Invalid Bitmessage address: {}".format(self.address))
self.address = addBMIfNotPresent(self.address) self.fullUsername = '{}@{}'.format(getBase58Capitaliation(self.address), address)
if username != self.fullUsername:
self.push('530 Access denied.')
self.close_when_done()
return
# Each identity must be enabled independly by setting the smtppop3password for the identity # Each identity must be enabled independly by setting the smtppop3password for the identity
# If no password is set, then the identity is not available for SMTP/POP3 access. # If no password is set, then the identity is not available for SMTP/POP3 access.
@ -206,8 +219,7 @@ class bitmessageSMTPChannel(asynchat.async_chat):
if self.__mailfrom: if self.__mailfrom:
self.push('503 Error: nested MAIL command') self.push('503 Error: nested MAIL command')
return return
_, domain = address.split('@', 1) if address != self.fullUsername:
if domain != self.address:
self.push('530 Access denied: address domain must match Bitmessage identity') self.push('530 Access denied: address domain must match Bitmessage identity')
return return
self.__mailfrom = address self.__mailfrom = address
@ -228,7 +240,9 @@ class bitmessageSMTPChannel(asynchat.async_chat):
if not address: if not address:
self.push('501 Syntax: RCPT TO: <address>') self.push('501 Syntax: RCPT TO: <address>')
return return
self.__rcpttos.append(address) capitalization, address = address.split('@', 1)
realAddress = applyBase58Capitalization(address, int(capitalization))
self.__rcpttos.append('{}@{}'.format(getBase58Capitaliation(realAddress), realAddress))
print >> smtpd.DEBUGSTREAM, 'recips:', self.__rcpttos print >> smtpd.DEBUGSTREAM, 'recips:', self.__rcpttos
self.push('250 Ok') self.push('250 Ok')