diff --git a/src/addresses.py b/src/addresses.py index a6a571f6..f37a068e 100644 --- a/src/addresses.py +++ b/src/addresses.py @@ -199,6 +199,26 @@ def addBMIfNotPresent(address): else: 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): #returns the stream number of an address or False if there is a problem with the address. diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index b027c7be..3c4f7ab7 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -2873,7 +2873,6 @@ class settingsDialog(QtGui.QDialog): def comboBoxEmailIdentitiesChanged(self, comboBoxIndex): address = str(self.ui.comboBoxEmailIdentities.itemData(comboBoxIndex).toPyObject()) - self.ui.labelEmailIdentity.setText(address) try: 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.pushButtonClearPassword.setEnabled(False) + self.ui.lineEditEmailAddress.setText('{}@{}'.format(getBase58Capitaliation(address), address)) + def click_ClearPassword(self): comboBoxIndex = self.ui.comboBoxEmailIdentities.currentIndex() address = str(self.ui.comboBoxEmailIdentities.itemData(comboBoxIndex).toPyObject()) diff --git a/src/bitmessageqt/settings.py b/src/bitmessageqt/settings.py index 0b55bb72..184ffb74 100644 --- a/src/bitmessageqt/settings.py +++ b/src/bitmessageqt/settings.py @@ -2,7 +2,7 @@ # 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 # # 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.setObjectName(_fromUtf8("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) - self.gridLayout_9.addItem(spacerItem10, 0, 2, 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.gridLayout_9.addItem(spacerItem10, 0, 1, 1, 1) self.comboBoxEmailIdentities = QtGui.QComboBox(self.groupBox_3) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) @@ -267,6 +264,29 @@ class Ui_settingsDialog(object): self.comboBoxEmailIdentities.setSizePolicy(sizePolicy) self.comboBoxEmailIdentities.setObjectName(_fromUtf8("comboBoxEmailIdentities")) 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.label_17 = QtGui.QLabel(self.tab_3) self.label_17.setObjectName(_fromUtf8("label_17")) @@ -376,7 +396,8 @@ class Ui_settingsDialog(object): self.pushButtonSetPassword.setText(_translate("settingsDialog", "Set 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.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_16.setText(_translate("settingsDialog", "SMTP Port:", None)) self.checkBoxEnablePOP3SSL.setText(_translate("settingsDialog", "SSL", None)) diff --git a/src/bitmessageqt/settings.ui b/src/bitmessageqt/settings.ui index 8f42e989..d03ac47f 100644 --- a/src/bitmessageqt/settings.ui +++ b/src/bitmessageqt/settings.ui @@ -526,7 +526,7 @@ Identities - + @@ -564,7 +564,7 @@ - + Qt::Horizontal @@ -577,13 +577,6 @@ - - - - TextLabel - - - @@ -594,6 +587,54 @@ + + + + + + + 1 + 0 + + + + + 153 + 16777215 + + + + E-Mail Address for this Identity: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + fsdpffffffffffffffffffffffffffffffffffffffffffffffasdpofiasjdf + + + true + + + + + diff --git a/src/class_pop3Server.py b/src/class_pop3Server.py index 61af04fa..a38249d4 100644 --- a/src/class_pop3Server.py +++ b/src/class_pop3Server.py @@ -161,7 +161,12 @@ class bitmessagePOP3Connection(asyncore.dispatcher): if self.loggedin: 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) if status != 'success': @@ -176,7 +181,12 @@ class bitmessagePOP3Connection(asyncore.dispatcher): shared.printLock.release() 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 # If no password is set, then the identity is not available for SMTP/POP3 access. diff --git a/src/class_smtpServer.py b/src/class_smtpServer.py index cfc96cde..5c8817aa 100644 --- a/src/class_smtpServer.py +++ b/src/class_smtpServer.py @@ -131,12 +131,20 @@ class bitmessageSMTPChannel(asynchat.async_chat): self.close_when_done() return - z, self.address, pw = base64.b64decode(pw).split('\x00') + z, username, pw = base64.b64decode(pw).split('\x00') if z != '': self.push('501 encoding not understood') self.close_when_done() 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) if status != 'success': shared.printLock.acquire() @@ -150,7 +158,12 @@ class bitmessageSMTPChannel(asynchat.async_chat): shared.printLock.release() 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 # 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: self.push('503 Error: nested MAIL command') return - _, domain = address.split('@', 1) - if domain != self.address: + if address != self.fullUsername: self.push('530 Access denied: address domain must match Bitmessage identity') return self.__mailfrom = address @@ -228,7 +240,9 @@ class bitmessageSMTPChannel(asynchat.async_chat): if not address: self.push('501 Syntax: RCPT TO:
') 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 self.push('250 Ok')