Config file defaults and address unification

- bmconfigpaser.py now allows to put default values for a specific
option in the file
- addresses as sections are now detected by "BM-" rather than
just ignoring bitmessagesettings. There can now be other sections
with a cleaner config file
This commit is contained in:
Peter Šurda 2017-05-15 12:18:07 +02:00
parent 660997f8e7
commit 9f4a1fa0a4
Signed by: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87
9 changed files with 81 additions and 70 deletions

View File

@ -169,22 +169,20 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
def HandleListAddresses(self, method): def HandleListAddresses(self, method):
data = '{"addresses":[' data = '{"addresses":['
configSections = BMConfigParser().sections() for addressInKeysFile in BMConfigParser().addresses():
for addressInKeysFile in configSections: status, addressVersionNumber, streamNumber, hash01 = decodeAddress(
if addressInKeysFile != 'bitmessagesettings': addressInKeysFile)
status, addressVersionNumber, streamNumber, hash01 = decodeAddress( if len(data) > 20:
addressInKeysFile) data += ','
if len(data) > 20: if BMConfigParser().has_option(addressInKeysFile, 'chan'):
data += ',' chan = BMConfigParser().getboolean(addressInKeysFile, 'chan')
if BMConfigParser().has_option(addressInKeysFile, 'chan'): else:
chan = BMConfigParser().getboolean(addressInKeysFile, 'chan') chan = False
else: label = BMConfigParser().get(addressInKeysFile, 'label')
chan = False if method == 'listAddresses2':
label = BMConfigParser().get(addressInKeysFile, 'label') label = label.encode('base64')
if method == 'listAddresses2': data += json.dumps({'label': label, 'address': addressInKeysFile, 'stream':
label = label.encode('base64') streamNumber, 'enabled': BMConfigParser().getboolean(addressInKeysFile, 'enabled'), 'chan': chan}, indent=4, separators=(',', ': '))
data += json.dumps({'label': label, 'address': addressInKeysFile, 'stream':
streamNumber, 'enabled': BMConfigParser().getboolean(addressInKeysFile, 'enabled'), 'chan': chan}, indent=4, separators=(',', ': '))
data += ']}' data += ']}'
return data return data

View File

@ -1024,20 +1024,19 @@ def run(stdscr):
curses.init_pair(9, curses.COLOR_YELLOW, curses.COLOR_BLACK) # orangish curses.init_pair(9, curses.COLOR_YELLOW, curses.COLOR_BLACK) # orangish
# Init list of address in 'Your Identities' tab # Init list of address in 'Your Identities' tab
configSections = BMConfigParser().sections() configSections = BMConfigParser().addressses()
for addressInKeysFile in configSections: for addressInKeysFile in configSections:
if addressInKeysFile != "bitmessagesettings": isEnabled = BMConfigParser().getboolean(addressInKeysFile, "enabled")
isEnabled = BMConfigParser().getboolean(addressInKeysFile, "enabled") addresses.append([BMConfigParser().get(addressInKeysFile, "label"), isEnabled, addressInKeysFile])
addresses.append([BMConfigParser().get(addressInKeysFile, "label"), isEnabled, addressInKeysFile]) # Set address color
# Set address color if not isEnabled:
if not isEnabled: addresses[len(addresses)-1].append(8) # gray
addresses[len(addresses)-1].append(8) # gray elif BMConfigParser().safeGetBoolean(addressInKeysFile, 'chan'):
elif BMConfigParser().safeGetBoolean(addressInKeysFile, 'chan'): addresses[len(addresses)-1].append(9) # orange
addresses[len(addresses)-1].append(9) # orange elif BMConfigParser().safeGetBoolean(addressInKeysFile, 'mailinglist'):
elif BMConfigParser().safeGetBoolean(addressInKeysFile, 'mailinglist'): addresses[len(addresses)-1].append(5) # magenta
addresses[len(addresses)-1].append(5) # magenta else:
else: addresses[len(addresses)-1].append(0) # black
addresses[len(addresses)-1].append(0) # black
addresses.reverse() addresses.reverse()
stdscr.clear() stdscr.clear()

View File

@ -13,7 +13,7 @@ from utils import str_broadcast_subscribers
import time import time
def getSortedAccounts(): def getSortedAccounts():
configSections = filter(lambda x: x != 'bitmessagesettings', BMConfigParser().sections()) configSections = BMConfigParser().addresses()
configSections.sort(cmp = configSections.sort(cmp =
lambda x,y: cmp(unicode(BMConfigParser().get(x, 'label'), 'utf-8').lower(), unicode(BMConfigParser().get(y, 'label'), 'utf-8').lower()) lambda x,y: cmp(unicode(BMConfigParser().get(x, 'label'), 'utf-8').lower(), unicode(BMConfigParser().get(y, 'label'), 'utf-8').lower())
) )

View File

@ -6,6 +6,17 @@ import os
from singleton import Singleton from singleton import Singleton
import state import state
BMConfigDefaults = {
"bitmessagesettings": {
"maxaddrperstreamsend": 500,
"maxbootstrapconnections": 20,
"maxoutboundconnections": 8,
"maxtotalconnections": 200,
},
"zlib": {
'maxsize': 1048576
}
}
@Singleton @Singleton
class BMConfigParser(ConfigParser.SafeConfigParser): class BMConfigParser(ConfigParser.SafeConfigParser):
@ -21,33 +32,38 @@ class BMConfigParser(ConfigParser.SafeConfigParser):
return ConfigParser.ConfigParser.get(self, section, option, raw, vars) return ConfigParser.ConfigParser.get(self, section, option, raw, vars)
except ConfigParser.InterpolationError: except ConfigParser.InterpolationError:
return ConfigParser.ConfigParser.get(self, section, option, True, vars) return ConfigParser.ConfigParser.get(self, section, option, True, vars)
return ConfigParser.ConfigParser.get(self, section, option, True, vars) try:
return ConfigParser.ConfigParser.get(self, section, option, True, vars)
except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e:
try:
return BMConfigDefaults[section][option]
except KeyError:
raise e
def safeGetBoolean(self, section, field): def safeGetBoolean(self, section, field):
if self.has_option(section, field): try:
try: return self.getboolean(section, field)
return self.getboolean(section, field) except (ConfigParser.NoSectionError, ConfigParser.NoOptionError, ValueError):
except ValueError: return False
return False
return False
def safeGetInt(self, section, field, default=0): def safeGetInt(self, section, field, default=0):
if self.has_option(section, field): try:
try: return self.getint(section, field)
return self.getint(section, field) except (ConfigParser.NoSectionError, ConfigParser.NoOptionError, ValueError):
except ValueError: return default
return default
return default
def safeGet(self, section, option, default = None): def safeGet(self, section, option, default = None):
if self.has_option(section, option): try:
return self.get(section, option) return self.get(section, option)
else: except (ConfigParser.NoSectionError, ConfigParser.NoOptionError, ValueError):
return default return default
def items(self, section, raw=False, vars=None): def items(self, section, raw=False, vars=None):
return ConfigParser.ConfigParser.items(self, section, True, vars) return ConfigParser.ConfigParser.items(self, section, True, vars)
def addresses(self):
return filter(lambda x: x.startswith('BM-'), BMConfigParser().sections())
def save(self): def save(self):
fileName = os.path.join(state.appdata, 'keys.dat') fileName = os.path.join(state.appdata, 'keys.dat')
fileNameBak = fileName + "." + datetime.datetime.now().strftime("%Y%j%H%M%S%f") + '.bak' fileNameBak = fileName + "." + datetime.datetime.now().strftime("%Y%j%H%M%S%f") + '.bak'

View File

@ -136,7 +136,7 @@ class singleWorker(threading.Thread, StoppableThread):
def doPOWForMyV2Pubkey(self, hash): # This function also broadcasts out the pubkey message once it is done with the POW def doPOWForMyV2Pubkey(self, hash): # This function also broadcasts out the pubkey message once it is done with the POW
# Look up my stream number based on my address hash # Look up my stream number based on my address hash
"""configSections = shared.config.sections() """configSections = shared.config.addresses()
for addressInKeysFile in configSections: for addressInKeysFile in configSections:
if addressInKeysFile <> 'bitmessagesettings': if addressInKeysFile <> 'bitmessagesettings':
status,addressVersionNumber,streamNumber,hashFromThisParticularAddress = decodeAddress(addressInKeysFile) status,addressVersionNumber,streamNumber,hashFromThisParticularAddress = decodeAddress(addressInKeysFile)

View File

@ -59,7 +59,7 @@ class smtpDeliver(threading.Thread, StoppableThread):
msg = MIMEText(body, 'plain', 'utf-8') msg = MIMEText(body, 'plain', 'utf-8')
msg['Subject'] = Header(subject, 'utf-8') msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = fromAddress + '@' + SMTPDOMAIN msg['From'] = fromAddress + '@' + SMTPDOMAIN
toLabel = map (lambda y: BMConfigParser().safeGet(y, "label"), filter(lambda x: x == toAddress, BMConfigParser().sections())) toLabel = map (lambda y: BMConfigParser().safeGet(y, "label"), filter(lambda x: x == toAddress, BMConfigParser().addresses()))
if len(toLabel) > 0: if len(toLabel) > 0:
msg['To'] = "\"%s\" <%s>" % (Header(toLabel[0], 'utf-8'), toAddress + '@' + SMTPDOMAIN) msg['To'] = "\"%s\" <%s>" % (Header(toLabel[0], 'utf-8'), toAddress + '@' + SMTPDOMAIN)
else: else:

View File

@ -115,7 +115,7 @@ class smtpServerPyBitmessage(smtpd.SMTPServer):
sender, domain = p.sub(r'\1', mailfrom).split("@") sender, domain = p.sub(r'\1', mailfrom).split("@")
if domain != SMTPDOMAIN: if domain != SMTPDOMAIN:
raise Exception("Bad domain %s", domain) raise Exception("Bad domain %s", domain)
if sender not in BMConfigParser().sections(): if sender not in BMConfigParser().addresses():
raise Exception("Nonexisting user %s", sender) raise Exception("Nonexisting user %s", sender)
except Exception as err: except Exception as err:
logger.debug("Bad envelope from %s: %s", mailfrom, repr(err)) logger.debug("Bad envelope from %s: %s", mailfrom, repr(err))
@ -125,7 +125,7 @@ class smtpServerPyBitmessage(smtpd.SMTPServer):
sender, domain = msg_from.split("@") sender, domain = msg_from.split("@")
if domain != SMTPDOMAIN: if domain != SMTPDOMAIN:
raise Exception("Bad domain %s", domain) raise Exception("Bad domain %s", domain)
if sender not in BMConfigParser().sections(): if sender not in BMConfigParser().addresses():
raise Exception("Nonexisting user %s", sender) raise Exception("Nonexisting user %s", sender)
except Exception as err: except Exception as err:
logger.error("Bad headers from %s: %s", msg_from, repr(err)) logger.error("Bad headers from %s: %s", msg_from, repr(err))

View File

@ -316,7 +316,7 @@ class sqlThread(threading.Thread):
# Adjust the required POW values for each of this user's addresses to conform to protocol v3 norms. # Adjust the required POW values for each of this user's addresses to conform to protocol v3 norms.
if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 9: if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 9:
for addressInKeysFile in BMConfigParser().sections(): for addressInKeysFile in BMConfigParser().addressses():
try: try:
previousTotalDifficulty = float(BMConfigParser().getint(addressInKeysFile, 'noncetrialsperbyte')) / 320 previousTotalDifficulty = float(BMConfigParser().getint(addressInKeysFile, 'noncetrialsperbyte')) / 320
previousSmallMessageDifficulty = float(BMConfigParser().getint(addressInKeysFile, 'payloadlengthextrabytes')) / 14000 previousSmallMessageDifficulty = float(BMConfigParser().getint(addressInKeysFile, 'payloadlengthextrabytes')) / 14000

View File

@ -110,29 +110,27 @@ def reloadMyAddressHashes():
#myPrivateKeys.clear() #myPrivateKeys.clear()
keyfileSecure = checkSensitiveFilePermissions(state.appdata + 'keys.dat') keyfileSecure = checkSensitiveFilePermissions(state.appdata + 'keys.dat')
configSections = BMConfigParser().sections()
hasEnabledKeys = False hasEnabledKeys = False
for addressInKeysFile in configSections: for addressInKeysFile in BMConfigParser().addresses():
if addressInKeysFile <> 'bitmessagesettings': isEnabled = BMConfigParser().getboolean(addressInKeysFile, 'enabled')
isEnabled = BMConfigParser().getboolean(addressInKeysFile, 'enabled') if isEnabled:
if isEnabled: hasEnabledKeys = True
hasEnabledKeys = True status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile)
status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile) if addressVersionNumber == 2 or addressVersionNumber == 3 or addressVersionNumber == 4:
if addressVersionNumber == 2 or addressVersionNumber == 3 or addressVersionNumber == 4: # Returns a simple 32 bytes of information encoded in 64 Hex characters,
# Returns a simple 32 bytes of information encoded in 64 Hex characters, # or null if there was an error.
# or null if there was an error. privEncryptionKey = hexlify(decodeWalletImportFormat(
privEncryptionKey = hexlify(decodeWalletImportFormat( BMConfigParser().get(addressInKeysFile, 'privencryptionkey')))
BMConfigParser().get(addressInKeysFile, 'privencryptionkey')))
if len(privEncryptionKey) == 64:#It is 32 bytes encoded as 64 hex characters if len(privEncryptionKey) == 64:#It is 32 bytes encoded as 64 hex characters
myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(privEncryptionKey) myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(privEncryptionKey)
myAddressesByHash[hash] = addressInKeysFile myAddressesByHash[hash] = addressInKeysFile
tag = hashlib.sha512(hashlib.sha512(encodeVarint( tag = hashlib.sha512(hashlib.sha512(encodeVarint(
addressVersionNumber) + encodeVarint(streamNumber) + hash).digest()).digest()[32:] addressVersionNumber) + encodeVarint(streamNumber) + hash).digest()).digest()[32:]
myAddressesByTag[tag] = addressInKeysFile myAddressesByTag[tag] = addressInKeysFile
else: else:
logger.error('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2, 3, or 4.\n') logger.error('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2, 3, or 4.\n')
if not keyfileSecure: if not keyfileSecure:
fixSensitiveFilePermissions(state.appdata + 'keys.dat', hasEnabledKeys) fixSensitiveFilePermissions(state.appdata + 'keys.dat', hasEnabledKeys)