From ba5caf3fdad5e996bcef5d1077fb69608bdaa0c8 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Sat, 3 Mar 2018 17:31:49 +0200 Subject: [PATCH] Sorted out configuration loading/updating a bit: - used BMConfigParser.safeGet.. methods instead of try .. except - moved all config checks from class_sqlThread into helper_startup - commented out initialization of settings which are then rewritten by updateConfig() --- src/bitmessageqt/account.py | 4 +- src/bitmessageqt/languagebox.py | 10 +- src/bitmessageqt/support.py | 17 +- src/bitmessageqt/utils.py | 30 ++-- src/class_sqlThread.py | 203 +++++++----------------- src/helper_startup.py | 271 +++++++++++++++++++++++++++----- 6 files changed, 315 insertions(+), 220 deletions(-) diff --git a/src/bitmessageqt/account.py b/src/bitmessageqt/account.py index cf3373db..50ea3548 100644 --- a/src/bitmessageqt/account.py +++ b/src/bitmessageqt/account.py @@ -150,9 +150,7 @@ class BMAccount(object): """Get a label for this bitmessage account""" if address is None: address = self.address - label = address - if BMConfigParser().has_section(address): - label = BMConfigParser().get(address, 'label') + label = BMConfigParser().safeGet(address, 'label', address) queryreturn = sqlQuery( '''select label from addressbook where address=?''', address) if queryreturn != []: diff --git a/src/bitmessageqt/languagebox.py b/src/bitmessageqt/languagebox.py index 552e0350..9032cc42 100644 --- a/src/bitmessageqt/languagebox.py +++ b/src/bitmessageqt/languagebox.py @@ -12,26 +12,24 @@ class LanguageBox(QtGui.QComboBox): self.populate() def populate(self): - self.languages = [] self.clear() localesPath = os.path.join (paths.codePath(), 'translations') - configuredLocale = "system" - try: - configuredLocale = BMConfigParser().get('bitmessagesettings', 'userlocale', "system") - except: - pass self.addItem(QtGui.QApplication.translate("settingsDialog", "System Settings", "system"), "system") self.setCurrentIndex(0) self.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically) for translationFile in sorted(glob.glob(os.path.join(localesPath, "bitmessage_*.qm"))): localeShort = os.path.split(translationFile)[1].split("_", 1)[1][:-3] locale = QtCore.QLocale(QtCore.QString(localeShort)) + if localeShort in LanguageBox.languageName: self.addItem(LanguageBox.languageName[localeShort], localeShort) elif locale.nativeLanguageName() == "": self.addItem(localeShort, localeShort) else: self.addItem(locale.nativeLanguageName(), localeShort) + + configuredLocale = BMConfigParser().safeGet( + 'bitmessagesettings', 'userlocale', "system") for i in range(self.count()): if self.itemData(i) == configuredLocale: self.setCurrentIndex(i) diff --git a/src/bitmessageqt/support.py b/src/bitmessageqt/support.py index 25c6113d..2a1ddb18 100644 --- a/src/bitmessageqt/support.py +++ b/src/bitmessageqt/support.py @@ -114,18 +114,13 @@ def createSupportMessage(myapp): frozen = paths.frozen portablemode = "True" if state.appdata == paths.lookupExeFolder() else "False" cpow = "True" if proofofwork.bmpow else "False" - #cpow = QtGui.QApplication.translate("Support", cpow) - openclpow = str(BMConfigParser().safeGet('bitmessagesettings', 'opencl')) if openclEnabled() else "None" - #openclpow = QtGui.QApplication.translate("Support", openclpow) + openclpow = str( + BMConfigParser().safeGet('bitmessagesettings', 'opencl') + ) if openclEnabled() else "None" locale = getTranslationLanguage() - try: - socks = BMConfigParser().get('bitmessagesettings', 'socksproxytype') - except: - socks = "N/A" - try: - upnp = BMConfigParser().get('bitmessagesettings', 'upnp') - except: - upnp = "N/A" + socks = BMConfigParser().safeGet( + 'bitmessagesettings', 'socksproxytype', "N/A") + upnp = BMConfigParser().safeGet('bitmessagesettings', 'upnp', "N/A") connectedhosts = len(network.stats.connectedHostsList()) myapp.ui.textEditMessage.setText(str(QtGui.QApplication.translate("Support", SUPPORT_MESSAGE)).format(version, os, architecture, pythonversion, opensslversion, frozen, portablemode, cpow, openclpow, locale, socks, upnp, connectedhosts)) diff --git a/src/bitmessageqt/utils.py b/src/bitmessageqt/utils.py index 369d05ef..564dbc8b 100644 --- a/src/bitmessageqt/utils.py +++ b/src/bitmessageqt/utils.py @@ -10,26 +10,24 @@ str_chan = '[chan]' def identiconize(address): size = 48 - - # If you include another identicon library, please generate an + + if not BMConfigParser().getboolean('bitmessagesettings', 'useidenticons'): + return QtGui.QIcon() + + # If you include another identicon library, please generate an # example identicon with the following md5 hash: # 3fd4bf901b9d4ea1394f0fb358725b28 - - try: - identicon_lib = BMConfigParser().get('bitmessagesettings', 'identiconlib') - except: - # default to qidenticon_two_x - identicon_lib = 'qidenticon_two_x' - # As an 'identiconsuffix' you could put "@bitmessge.ch" or "@bm.addr" to make it compatible with other identicon generators. (Note however, that E-Mail programs might convert the BM-address to lowercase first.) - # It can be used as a pseudo-password to salt the generation of the identicons to decrease the risk - # of attacks where someone creates an address to mimic someone else's identicon. + identicon_lib = BMConfigParser().safeGet( + 'bitmessagesettings', 'identiconlib', 'qidenticon_two_x') + + # As an 'identiconsuffix' you could put "@bitmessge.ch" or "@bm.addr" + # to make it compatible with other identicon generators. (Note however, + # that E-Mail programs might convert the BM-address to lowercase first.) + # It can be used as a pseudo-password to salt the generation of + # the identicons to decrease the risk of attacks where someone creates + # an address to mimic someone else's identicon. identiconsuffix = BMConfigParser().get('bitmessagesettings', 'identiconsuffix') - - if not BMConfigParser().getboolean('bitmessagesettings', 'useidenticons'): - idcon = QtGui.QIcon() - return idcon - if (identicon_lib[:len('qidenticon')] == 'qidenticon'): # print identicon_lib # originally by: diff --git a/src/class_sqlThread.py b/src/class_sqlThread.py index 45c4d8c0..a45571e0 100644 --- a/src/class_sqlThread.py +++ b/src/class_sqlThread.py @@ -6,14 +6,13 @@ import shutil # used for moving the messages.dat file import sys import os from debug import logger -import defaults import helper_sql -from namecoin import ensureNamecoinOptions +import helper_startup import paths import queues import state -import tr#anslate -import helper_random +import tr + # This thread exists because SQLITE3 is so un-threadsafe that we must # submit queries to it and it puts results back in a different queue. They # won't let us just use locks. @@ -68,35 +67,26 @@ class sqlThread(threading.Thread): 'ERROR trying to create database file (message.dat). Error message: %s\n' % str(err)) os._exit(0) - if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 1: - BMConfigParser().set('bitmessagesettings', 'settingsversion', '2') - # If the settings version is equal to 2 or 3 then the - # sqlThread will modify the pubkeys table and change - # the settings version to 4. - BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'none') - BMConfigParser().set('bitmessagesettings', 'sockshostname', 'localhost') - BMConfigParser().set('bitmessagesettings', 'socksport', '9050') - BMConfigParser().set('bitmessagesettings', 'socksauthentication', 'false') - BMConfigParser().set('bitmessagesettings', 'socksusername', '') - BMConfigParser().set('bitmessagesettings', 'sockspassword', '') - BMConfigParser().set('bitmessagesettings', 'sockslisten', 'false') - BMConfigParser().set('bitmessagesettings', 'keysencrypted', 'false') - BMConfigParser().set('bitmessagesettings', 'messagesencrypted', 'false') + # If the settings version is equal to 2 or 3 then the + # sqlThread will modify the pubkeys table and change + # the settings version to 4. + settingsversion = BMConfigParser().getint( + 'bitmessagesettings', 'settingsversion') # People running earlier versions of PyBitmessage do not have the # usedpersonally field in their pubkeys table. Let's add it. - if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 2: + if settingsversion == 2: item = '''ALTER TABLE pubkeys ADD usedpersonally text DEFAULT 'no' ''' parameters = '' self.cur.execute(item, parameters) self.conn.commit() - BMConfigParser().set('bitmessagesettings', 'settingsversion', '3') + settingsversion = 3 # People running earlier versions of PyBitmessage do not have the # encodingtype field in their inbox and sent tables or the read field # in the inbox table. Let's add them. - if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 3: + if settingsversion == 3: item = '''ALTER TABLE inbox ADD encodingtype int DEFAULT '2' ''' parameters = '' self.cur.execute(item, parameters) @@ -110,21 +100,13 @@ class sqlThread(threading.Thread): self.cur.execute(item, parameters) self.conn.commit() - BMConfigParser().set('bitmessagesettings', 'settingsversion', '4') + settingsversion = 4 - if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 4: - BMConfigParser().set('bitmessagesettings', 'defaultnoncetrialsperbyte', str( - defaults.networkDefaultProofOfWorkNonceTrialsPerByte)) - BMConfigParser().set('bitmessagesettings', 'defaultpayloadlengthextrabytes', str( - defaults.networkDefaultPayloadLengthExtraBytes)) - BMConfigParser().set('bitmessagesettings', 'settingsversion', '5') + BMConfigParser().set( + 'bitmessagesettings', 'settingsversion', str(settingsversion)) + BMConfigParser().save() - if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 5: - BMConfigParser().set( - 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte', '0') - BMConfigParser().set( - 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', '0') - BMConfigParser().set('bitmessagesettings', 'settingsversion', '6') + helper_startup.updateConfig() # From now on, let us keep a 'version' embedded in the messages.dat # file so that when we make changes to the database, the database @@ -135,7 +117,8 @@ class sqlThread(threading.Thread): self.cur.execute(item, parameters) if self.cur.fetchall() == []: # The settings table doesn't exist. We need to make it. - logger.debug('In messages.dat database, creating new \'settings\' table.') + logger.debug( + "In messages.dat database, creating new 'settings' table.") self.cur.execute( '''CREATE TABLE settings (key text, value blob, UNIQUE(key) ON CONFLICT REPLACE)''' ) self.cur.execute( '''INSERT INTO settings VALUES('version','1')''') @@ -177,17 +160,15 @@ class sqlThread(threading.Thread): '''update sent set status='broadcastqueued' where status='broadcastpending' ''') self.conn.commit() - if not BMConfigParser().has_option('bitmessagesettings', 'sockslisten'): - BMConfigParser().set('bitmessagesettings', 'sockslisten', 'false') - - ensureNamecoinOptions() - - # Let's get rid of the first20bytesofencryptedmessage field in the inventory table. + # Let's get rid of the first20bytesofencryptedmessage field in + # the inventory table. item = '''SELECT value FROM settings WHERE key='version';''' parameters = '' self.cur.execute(item, parameters) if int(self.cur.fetchall()[0][0]) == 2: - logger.debug('In messages.dat database, removing an obsolete field from the inventory table.') + logger.debug( + 'In messages.dat database, removing an obsolete field from' + ' the inventory table.') self.cur.execute( '''CREATE TEMPORARY TABLE inventory_backup(hash blob, objecttype text, streamnumber int, payload blob, receivedtime integer, UNIQUE(hash) ON CONFLICT REPLACE);''') self.cur.execute( @@ -208,7 +189,9 @@ class sqlThread(threading.Thread): self.cur.execute(item, parameters) currentVersion = int(self.cur.fetchall()[0][0]) if currentVersion == 1 or currentVersion == 3: - logger.debug('In messages.dat database, adding tag field to the inventory table.') + logger.debug( + 'In messages.dat database, adding tag field to' + ' the inventory table.') item = '''ALTER TABLE inventory ADD tag blob DEFAULT '' ''' parameters = '' self.cur.execute(item, parameters) @@ -216,16 +199,6 @@ class sqlThread(threading.Thread): parameters = (4,) self.cur.execute(item, parameters) - if not BMConfigParser().has_option('bitmessagesettings', 'userlocale'): - BMConfigParser().set('bitmessagesettings', 'userlocale', 'system') - if not BMConfigParser().has_option('bitmessagesettings', 'sendoutgoingconnections'): - BMConfigParser().set('bitmessagesettings', 'sendoutgoingconnections', 'True') - - # Raise the default required difficulty from 1 to 2 - # With the change to protocol v3, this is obsolete. - if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 6: - BMConfigParser().set('bitmessagesettings', 'settingsversion', '7') - # Add a new column to the pubkeys table to store the address version. # We're going to trash all of our pubkeys and let them be redownloaded. item = '''SELECT value FROM settings WHERE key='version';''' @@ -233,28 +206,15 @@ class sqlThread(threading.Thread): self.cur.execute(item, parameters) currentVersion = int(self.cur.fetchall()[0][0]) if currentVersion == 4: - self.cur.execute( '''DROP TABLE pubkeys''') + self.cur.execute('''DROP TABLE pubkeys''') self.cur.execute( - '''CREATE TABLE pubkeys (hash blob, addressversion int, transmitdata blob, time int, usedpersonally text, UNIQUE(hash, addressversion) ON CONFLICT REPLACE)''' ) + '''CREATE TABLE pubkeys (hash blob, addressversion int, transmitdata blob, time int, usedpersonally text, UNIQUE(hash, addressversion) ON CONFLICT REPLACE)''') self.cur.execute( '''delete from inventory where objecttype = 'pubkey';''') item = '''update settings set value=? WHERE key='version';''' parameters = (5,) self.cur.execute(item, parameters) - if not BMConfigParser().has_option('bitmessagesettings', 'useidenticons'): - BMConfigParser().set('bitmessagesettings', 'useidenticons', 'True') - if not BMConfigParser().has_option('bitmessagesettings', 'identiconsuffix'): # acts as a salt - BMConfigParser().set('bitmessagesettings', 'identiconsuffix', ''.join(helper_random.randomchoice("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") for x in range(12)))# a twelve character pseudo-password to salt the identicons - - #Add settings to support no longer resending messages after a certain period of time even if we never get an ack - if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 7: - BMConfigParser().set( - 'bitmessagesettings', 'stopresendingafterxdays', '') - BMConfigParser().set( - 'bitmessagesettings', 'stopresendingafterxmonths', '') - BMConfigParser().set('bitmessagesettings', 'settingsversion', '8') - # Add a new table: objectprocessorqueue with which to hold objects # that have yet to be processed if the user shuts down Bitmessage. item = '''SELECT value FROM settings WHERE key='version';''' @@ -262,21 +222,24 @@ class sqlThread(threading.Thread): self.cur.execute(item, parameters) currentVersion = int(self.cur.fetchall()[0][0]) if currentVersion == 5: - self.cur.execute( '''DROP TABLE knownnodes''') + self.cur.execute('''DROP TABLE knownnodes''') self.cur.execute( - '''CREATE TABLE objectprocessorqueue (objecttype text, data blob, UNIQUE(objecttype, data) ON CONFLICT REPLACE)''' ) + '''CREATE TABLE objectprocessorqueue (objecttype text, data blob, UNIQUE(objecttype, data) ON CONFLICT REPLACE)''') item = '''update settings set value=? WHERE key='version';''' parameters = (6,) self.cur.execute(item, parameters) # changes related to protocol v3 - # In table inventory and objectprocessorqueue, objecttype is now an integer (it was a human-friendly string previously) + # In table inventory and objectprocessorqueue, objecttype is now + # an integer (it was a human-friendly string previously) item = '''SELECT value FROM settings WHERE key='version';''' parameters = '' self.cur.execute(item, parameters) currentVersion = int(self.cur.fetchall()[0][0]) if currentVersion == 6: - logger.debug('In messages.dat database, dropping and recreating the inventory table.') + logger.debug( + 'In messages.dat database, dropping and recreating' + ' the inventory table.') self.cur.execute( '''DROP TABLE inventory''') self.cur.execute( '''CREATE TABLE inventory (hash blob, objecttype int, streamnumber int, payload blob, expirestime integer, tag blob, UNIQUE(hash) ON CONFLICT REPLACE)''' ) self.cur.execute( '''DROP TABLE objectprocessorqueue''') @@ -284,57 +247,26 @@ class sqlThread(threading.Thread): item = '''update settings set value=? WHERE key='version';''' parameters = (7,) self.cur.execute(item, parameters) - logger.debug('Finished dropping and recreating the inventory table.') - - # With the change to protocol version 3, reset the user-settable difficulties to 1 - if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 8: - BMConfigParser().set('bitmessagesettings','defaultnoncetrialsperbyte', str(defaults.networkDefaultProofOfWorkNonceTrialsPerByte)) - BMConfigParser().set('bitmessagesettings','defaultpayloadlengthextrabytes', str(defaults.networkDefaultPayloadLengthExtraBytes)) - previousTotalDifficulty = int(BMConfigParser().getint('bitmessagesettings', 'maxacceptablenoncetrialsperbyte')) / 320 - previousSmallMessageDifficulty = int(BMConfigParser().getint('bitmessagesettings', 'maxacceptablepayloadlengthextrabytes')) / 14000 - BMConfigParser().set('bitmessagesettings','maxacceptablenoncetrialsperbyte', str(previousTotalDifficulty * 1000)) - BMConfigParser().set('bitmessagesettings','maxacceptablepayloadlengthextrabytes', str(previousSmallMessageDifficulty * 1000)) - BMConfigParser().set('bitmessagesettings', 'settingsversion', '9') - - # Adjust the required POW values for each of this user's addresses to conform to protocol v3 norms. - if BMConfigParser().getint('bitmessagesettings', 'settingsversion') == 9: - for addressInKeysFile in BMConfigParser().addressses(): - try: - previousTotalDifficulty = float(BMConfigParser().getint(addressInKeysFile, 'noncetrialsperbyte')) / 320 - previousSmallMessageDifficulty = float(BMConfigParser().getint(addressInKeysFile, 'payloadlengthextrabytes')) / 14000 - if previousTotalDifficulty <= 2: - previousTotalDifficulty = 1 - if previousSmallMessageDifficulty < 1: - previousSmallMessageDifficulty = 1 - BMConfigParser().set(addressInKeysFile,'noncetrialsperbyte', str(int(previousTotalDifficulty * 1000))) - BMConfigParser().set(addressInKeysFile,'payloadlengthextrabytes', str(int(previousSmallMessageDifficulty * 1000))) - except: - continue - BMConfigParser().set('bitmessagesettings', 'maxdownloadrate', '0') - BMConfigParser().set('bitmessagesettings', 'maxuploadrate', '0') - BMConfigParser().set('bitmessagesettings', 'settingsversion', '10') - BMConfigParser().save() - - # sanity check - if BMConfigParser().getint('bitmessagesettings', 'maxacceptablenoncetrialsperbyte') == 0: - BMConfigParser().set('bitmessagesettings','maxacceptablenoncetrialsperbyte', str(defaults.ridiculousDifficulty * defaults.networkDefaultProofOfWorkNonceTrialsPerByte)) - if BMConfigParser().getint('bitmessagesettings', 'maxacceptablepayloadlengthextrabytes') == 0: - BMConfigParser().set('bitmessagesettings','maxacceptablepayloadlengthextrabytes', str(defaults.ridiculousDifficulty * defaults.networkDefaultPayloadLengthExtraBytes)) + logger.debug( + 'Finished dropping and recreating the inventory table.') # The format of data stored in the pubkeys table has changed. Let's - # clear it, and the pubkeys from inventory, so that they'll be re-downloaded. + # clear it, and the pubkeys from inventory, so that they'll + # be re-downloaded. item = '''SELECT value FROM settings WHERE key='version';''' parameters = '' self.cur.execute(item, parameters) currentVersion = int(self.cur.fetchall()[0][0]) if currentVersion == 7: - logger.debug('In messages.dat database, clearing pubkeys table because the data format has been updated.') + logger.debug( + 'In messages.dat database, clearing pubkeys table' + ' because the data format has been updated.') self.cur.execute( '''delete from inventory where objecttype = 1;''') self.cur.execute( '''delete from pubkeys;''') - # Any sending messages for which we *thought* that we had the pubkey must - # be rechecked. + # Any sending messages for which we *thought* that we had + # the pubkey must be rechecked. self.cur.execute( '''UPDATE sent SET status='msgqueued' WHERE status='doingmsgpow' or status='badkey';''') query = '''update settings set value=? WHERE key='version';''' @@ -342,14 +274,17 @@ class sqlThread(threading.Thread): self.cur.execute(query, parameters) logger.debug('Finished clearing currently held pubkeys.') - # Add a new column to the inbox table to store the hash of the message signature. - # We'll use this as temporary message UUID in order to detect duplicates. + # Add a new column to the inbox table to store the hash of + # the message signature. We'll use this as temporary message UUID + # in order to detect duplicates. item = '''SELECT value FROM settings WHERE key='version';''' parameters = '' self.cur.execute(item, parameters) currentVersion = int(self.cur.fetchall()[0][0]) if currentVersion == 8: - logger.debug('In messages.dat database, adding sighash field to the inbox table.') + logger.debug( + 'In messages.dat database, adding sighash field to' + ' the inbox table.') item = '''ALTER TABLE inbox ADD sighash blob DEFAULT '' ''' parameters = '' self.cur.execute(item, parameters) @@ -357,17 +292,18 @@ class sqlThread(threading.Thread): parameters = (9,) self.cur.execute(item, parameters) - # TTL is now user-specifiable. Let's add an option to save whatever the user selects. - if not BMConfigParser().has_option('bitmessagesettings', 'ttl'): - BMConfigParser().set('bitmessagesettings', 'ttl', '367200') - # We'll also need a `sleeptill` field and a `ttl` field. Also we can combine - # the pubkeyretrynumber and msgretrynumber into one. + # We'll also need a `sleeptill` field and a `ttl` field. Also we + # can combine the pubkeyretrynumber and msgretrynumber into one. item = '''SELECT value FROM settings WHERE key='version';''' parameters = '' self.cur.execute(item, parameters) currentVersion = int(self.cur.fetchall()[0][0]) if currentVersion == 9: - logger.info('In messages.dat database, making TTL-related changes: combining the pubkeyretrynumber and msgretrynumber fields into the retrynumber field and adding the sleeptill and ttl fields...') + logger.info( + 'In messages.dat database, making TTL-related changes:' + ' combining the pubkeyretrynumber and msgretrynumber' + ' fields into the retrynumber field and adding the' + ' sleeptill and ttl fields...') self.cur.execute( '''CREATE TEMPORARY TABLE sent_backup (msgid blob, toaddress text, toripe blob, fromaddress text, subject text, message text, ackdata blob, lastactiontime integer, status text, retrynumber integer, folder text, encodingtype int)''' ) self.cur.execute( @@ -406,30 +342,9 @@ class sqlThread(threading.Thread): logger.debug('In messages.dat database, done adding address field to the pubkeys table and removing the hash field.') self.cur.execute('''update settings set value=10 WHERE key='version';''') - if not BMConfigParser().has_option('bitmessagesettings', 'onionhostname'): - BMConfigParser().set('bitmessagesettings', 'onionhostname', '') - if not BMConfigParser().has_option('bitmessagesettings', 'onionport'): - BMConfigParser().set('bitmessagesettings', 'onionport', '8444') - if not BMConfigParser().has_option('bitmessagesettings', 'onionbindip'): - BMConfigParser().set('bitmessagesettings', 'onionbindip', '127.0.0.1') - if not BMConfigParser().has_option('bitmessagesettings', 'smtpdeliver'): - BMConfigParser().set('bitmessagesettings', 'smtpdeliver', '') - if not BMConfigParser().has_option('bitmessagesettings', 'hidetrayconnectionnotifications'): - BMConfigParser().set('bitmessagesettings', 'hidetrayconnectionnotifications', 'false') - if BMConfigParser().has_option('bitmessagesettings', 'maxoutboundconnections'): - try: - if BMConfigParser().getint('bitmessagesettings', 'maxoutboundconnections') < 1: raise ValueError - except ValueError as err: - BMConfigParser().remove_option('bitmessagesettings', 'maxoutboundconnections') - logger.error('Your maximum outbound connections must be a number.') - if not BMConfigParser().has_option('bitmessagesettings', 'maxoutboundconnections'): - logger.info('Setting maximum outbound connections to 8.') - BMConfigParser().set('bitmessagesettings', 'maxoutboundconnections', '8') - - BMConfigParser().save() - # Are you hoping to add a new option to the keys.dat file of existing - # Bitmessage users or modify the SQLite database? Add it right above this line! + # Bitmessage users or modify the SQLite database? Add it right + # above this line! try: testpayload = '\x00\x00' diff --git a/src/helper_startup.py b/src/helper_startup.py index b7772a30..93a37658 100644 --- a/src/helper_startup.py +++ b/src/helper_startup.py @@ -12,9 +12,9 @@ import paths import state import helper_random +# The user may de-select Portable Mode in the settings if they want +# the config files to stay in the application data folder. StoreConfigFilesInSameDirectoryAsProgramByDefault = False -# The user may de-select Portable Mode in the settings if they want the config -# files to stay in the application data folder. def _loadTrustedPeer(): @@ -33,13 +33,12 @@ def loadConfig(): if state.appdata: BMConfigParser().read(state.appdata + 'keys.dat') # state.appdata must have been specified as a startup option. - try: - BMConfigParser().get('bitmessagesettings', 'settingsversion') - print 'Loading config files from directory specified on startup: ' + state.appdata - needToCreateKeysFile = False - except Exception: - needToCreateKeysFile = True - + needToCreateKeysFile = BMConfigParser().safeGet( + 'bitmessagesettings', 'settingsversion') is None + if not needToCreateKeysFile: + print( + 'Loading config files from directory specified' + ' on startup: %s' % state.appdata) else: BMConfigParser().read(paths.lookupExeFolder() + 'keys.dat') try: @@ -47,19 +46,18 @@ def loadConfig(): print 'Loading config files from same directory as program.' needToCreateKeysFile = False state.appdata = paths.lookupExeFolder() - except Exception: + except: # Could not load the keys.dat file in the program directory. # Perhaps it is in the appdata directory. state.appdata = paths.lookupAppdataFolder() BMConfigParser().read(state.appdata + 'keys.dat') - try: - BMConfigParser().get('bitmessagesettings', 'settingsversion') + needToCreateKeysFile = BMConfigParser().safeGet( + 'bitmessagesettings', 'settingsversion') is None + if not needToCreateKeysFile: print 'Loading existing config files from', state.appdata - needToCreateKeysFile = False - except Exception: - needToCreateKeysFile = True if needToCreateKeysFile: + # This appears to be the first time running the program; there is # no config file (or it cannot be accessed). Create config file. BMConfigParser().add_section('bitmessagesettings') @@ -72,9 +70,9 @@ def loadConfig(): if 'linux' in sys.platform: BMConfigParser().set( 'bitmessagesettings', 'minimizetotray', 'false') - # This isn't implimented yet and when True on - # Ubuntu causes Bitmessage to disappear while - # running when minimized. + # This isn't implimented yet and when True on + # Ubuntu causes Bitmessage to disappear while + # running when minimized. else: BMConfigParser().set( 'bitmessagesettings', 'minimizetotray', 'true') @@ -87,46 +85,54 @@ def loadConfig(): BMConfigParser().set('bitmessagesettings', 'socksport', '9050') BMConfigParser().set( 'bitmessagesettings', 'socksauthentication', 'false') - BMConfigParser().set( - 'bitmessagesettings', 'sockslisten', 'false') + # BMConfigParser().set( + # 'bitmessagesettings', 'sockslisten', 'false') BMConfigParser().set('bitmessagesettings', 'socksusername', '') BMConfigParser().set('bitmessagesettings', 'sockspassword', '') BMConfigParser().set('bitmessagesettings', 'keysencrypted', 'false') BMConfigParser().set( 'bitmessagesettings', 'messagesencrypted', 'false') - BMConfigParser().set('bitmessagesettings', 'defaultnoncetrialsperbyte', str( - defaults.networkDefaultProofOfWorkNonceTrialsPerByte)) - BMConfigParser().set('bitmessagesettings', 'defaultpayloadlengthextrabytes', str( - defaults.networkDefaultPayloadLengthExtraBytes)) + BMConfigParser().set( + 'bitmessagesettings', 'defaultnoncetrialsperbyte', + str(defaults.networkDefaultProofOfWorkNonceTrialsPerByte)) + BMConfigParser().set( + 'bitmessagesettings', 'defaultpayloadlengthextrabytes', + str(defaults.networkDefaultPayloadLengthExtraBytes)) BMConfigParser().set('bitmessagesettings', 'minimizeonclose', 'false') - BMConfigParser().set( - 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte', '0') - BMConfigParser().set( - 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', '0') + # BMConfigParser().set( + # 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte', '0') + # BMConfigParser().set( + # 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', + # '0') BMConfigParser().set('bitmessagesettings', 'dontconnect', 'true') - BMConfigParser().set('bitmessagesettings', 'userlocale', 'system') - BMConfigParser().set('bitmessagesettings', 'useidenticons', 'True') - BMConfigParser().set('bitmessagesettings', 'identiconsuffix', ''.join(helper_random.randomchoice("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") for x in range(12)))# a twelve character pseudo-password to salt the identicons + # BMConfigParser().set('bitmessagesettings', 'userlocale', 'system') + # BMConfigParser().set('bitmessagesettings', 'useidenticons', 'True') + # BMConfigParser().set( + # 'bitmessagesettings', 'identiconsuffix', + # ''.join(helper_random.randomchoice( + # "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" + # ) for x in range(12) + # )) # a twelve character pseudo-password to salt the identicons BMConfigParser().set('bitmessagesettings', 'replybelow', 'False') BMConfigParser().set('bitmessagesettings', 'maxdownloadrate', '0') BMConfigParser().set('bitmessagesettings', 'maxuploadrate', '0') - BMConfigParser().set('bitmessagesettings', 'maxoutboundconnections', '8') - BMConfigParser().set('bitmessagesettings', 'ttl', '367200') + # BMConfigParser().set( + # 'bitmessagesettings', 'maxoutboundconnections', '8') + # BMConfigParser().set('bitmessagesettings', 'ttl', '367200') - #start:UI setting to stop trying to send messages after X days/months + # UI setting to stop trying to send messages after X days/months BMConfigParser().set( 'bitmessagesettings', 'stopresendingafterxdays', '') BMConfigParser().set( 'bitmessagesettings', 'stopresendingafterxmonths', '') - #BMConfigParser().set( + # BMConfigParser().set( # 'bitmessagesettings', 'timeperiod', '-1') - #end # Are you hoping to add a new option to the keys.dat file? You're in # the right place for adding it to users who install the software for # the first time. But you must also add it to the keys.dat file of - # existing users. To do that, search the class_sqlThread.py file for the - # text: "right above this line!" + # existing users. To do that, search the class_sqlThread.py file + # for the text: "right above this line!" if StoreConfigFilesInSameDirectoryAsProgramByDefault: # Just use the same directory as the program and forget about @@ -140,15 +146,200 @@ def loadConfig(): if not sys.platform.startswith('win'): os.umask(0o077) BMConfigParser().save() + else: + updateConfig() _loadTrustedPeer() +def updateConfig(): + settingsversion = BMConfigParser().getint( + 'bitmessagesettings', 'settingsversion') + if settingsversion == 1: + BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'none') + BMConfigParser().set( + 'bitmessagesettings', 'sockshostname', 'localhost') + BMConfigParser().set('bitmessagesettings', 'socksport', '9050') + BMConfigParser().set( + 'bitmessagesettings', 'socksauthentication', 'false') + BMConfigParser().set('bitmessagesettings', 'socksusername', '') + BMConfigParser().set('bitmessagesettings', 'sockspassword', '') + BMConfigParser().set('bitmessagesettings', 'sockslisten', 'false') + BMConfigParser().set('bitmessagesettings', 'keysencrypted', 'false') + BMConfigParser().set( + 'bitmessagesettings', 'messagesencrypted', 'false') + settingsversion = 2 + # let class_sqlThread update SQL and continue + elif settingsversion == 4: + BMConfigParser().set( + 'bitmessagesettings', 'defaultnoncetrialsperbyte', + str(defaults.networkDefaultProofOfWorkNonceTrialsPerByte)) + BMConfigParser().set( + 'bitmessagesettings', 'defaultpayloadlengthextrabytes', + str(defaults.networkDefaultPayloadLengthExtraBytes)) + settingsversion = 5 + + if settingsversion == 5: + BMConfigParser().set( + 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte', '0') + BMConfigParser().set( + 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', '0') + settingsversion = 7 + + # Raise the default required difficulty from 1 to 2 + # With the change to protocol v3, this is obsolete. + # if settingsversion == 6: + # if int(shared.config.get( + # 'bitmessagesettings', 'defaultnoncetrialsperbyte' + # )) == defaults.networkDefaultProofOfWorkNonceTrialsPerByte: + # shared.config.set( + # 'bitmessagesettings', 'defaultnoncetrialsperbyte', + # str( + # defaults.networkDefaultProofOfWorkNonceTrialsPerByte + # * 2) + # ) + # settingsversion = 7 + + if not BMConfigParser().has_option('bitmessagesettings', 'sockslisten'): + BMConfigParser().set('bitmessagesettings', 'sockslisten', 'false') + + if not BMConfigParser().has_option('bitmessagesettings', 'userlocale'): + BMConfigParser().set('bitmessagesettings', 'userlocale', 'system') + + if not BMConfigParser().has_option( + 'bitmessagesettings', 'sendoutgoingconnections'): + BMConfigParser().set( + 'bitmessagesettings', 'sendoutgoingconnections', 'True') + + if not BMConfigParser().has_option( + 'bitmessagesettings', 'useidenticons'): + BMConfigParser().set('bitmessagesettings', 'useidenticons', 'True') + if not BMConfigParser().has_option( + 'bitmessagesettings', 'identiconsuffix'): + # acts as a salt + BMConfigParser().set( + 'bitmessagesettings', 'identiconsuffix', + ''.join(helper_random.randomchoice( + "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" + ) for x in range(12) + )) # a twelve character pseudo-password to salt the identicons + + # Add settings to support no longer resending messages after + # a certain period of time even if we never get an ack + if settingsversion == 7: + BMConfigParser().set( + 'bitmessagesettings', 'stopresendingafterxdays', '') + BMConfigParser().set( + 'bitmessagesettings', 'stopresendingafterxmonths', '') + settingsversion = 8 + + # With the change to protocol version 3, reset the user-settable + # difficulties to 1 + if settingsversion == 8: + BMConfigParser().set( + 'bitmessagesettings', 'defaultnoncetrialsperbyte', + str(defaults.networkDefaultProofOfWorkNonceTrialsPerByte)) + BMConfigParser().set( + 'bitmessagesettings', 'defaultpayloadlengthextrabytes', + str(defaults.networkDefaultPayloadLengthExtraBytes)) + previousTotalDifficulty = int( + BMConfigParser().getint( + 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte') + ) / 320 + previousSmallMessageDifficulty = int( + BMConfigParser().getint( + 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes') + ) / 14000 + BMConfigParser().set( + 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte', + str(previousTotalDifficulty * 1000)) + BMConfigParser().set( + 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', + str(previousSmallMessageDifficulty * 1000)) + settingsversion = 9 + + # Adjust the required POW values for each of this user's addresses + # to conform to protocol v3 norms. + if settingsversion == 9: + for addressInKeysFile in BMConfigParser().addresses(): + try: + previousTotalDifficulty = float( + BMConfigParser().getint( + addressInKeysFile, 'noncetrialsperbyte')) / 320 + previousSmallMessageDifficulty = float( + BMConfigParser().getint( + addressInKeysFile, 'payloadlengthextrabytes')) / 14000 + if previousTotalDifficulty <= 2: + previousTotalDifficulty = 1 + if previousSmallMessageDifficulty < 1: + previousSmallMessageDifficulty = 1 + BMConfigParser().set( + addressInKeysFile, 'noncetrialsperbyte', + str(int(previousTotalDifficulty * 1000))) + BMConfigParser().set( + addressInKeysFile, 'payloadlengthextrabytes', + str(int(previousSmallMessageDifficulty * 1000))) + except Exception: + continue + BMConfigParser().set('bitmessagesettings', 'maxdownloadrate', '0') + BMConfigParser().set('bitmessagesettings', 'maxuploadrate', '0') + settingsversion = 10 + + # sanity check + if BMConfigParser().safeGetInt( + 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte') == 0: + BMConfigParser().set( + 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte', + str( + defaults.ridiculousDifficulty + * defaults.networkDefaultProofOfWorkNonceTrialsPerByte) + ) + if BMConfigParser().safeGetInt( + 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes' + ) == 0: + BMConfigParser().set( + 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', + str( + defaults.ridiculousDifficulty + * defaults.networkDefaultPayloadLengthExtraBytes) + ) + + if not BMConfigParser().has_option('bitmessagesettings', 'onionhostname'): + BMConfigParser().set('bitmessagesettings', 'onionhostname', '') + if not BMConfigParser().has_option('bitmessagesettings', 'onionport'): + BMConfigParser().set('bitmessagesettings', 'onionport', '8444') + if not BMConfigParser().has_option('bitmessagesettings', 'onionbindip'): + BMConfigParser().set('bitmessagesettings', 'onionbindip', '127.0.0.1') + if not BMConfigParser().has_option('bitmessagesettings', 'smtpdeliver'): + BMConfigParser().set('bitmessagesettings', 'smtpdeliver', '') + if not BMConfigParser().has_option( + 'bitmessagesettings', 'hidetrayconnectionnotifications'): + BMConfigParser().set( + 'bitmessagesettings', 'hidetrayconnectionnotifications', 'false') + if BMConfigParser().safeGetInt( + 'bitmessagesettings', 'maxoutboundconnections') < 1: + BMConfigParser().set( + 'bitmessagesettings', 'maxoutboundconnections', '8') + print('WARNING: your maximum outbound connections must be a number.') + + # TTL is now user-specifiable. Let's add an option to save + # whatever the user selects. + if not BMConfigParser().has_option('bitmessagesettings', 'ttl'): + BMConfigParser().set('bitmessagesettings', 'ttl', '367200') + + BMConfigParser().set( + 'bitmessagesettings', 'settingsversion', str(settingsversion)) + BMConfigParser().save() + + def isOurOperatingSystemLimitedToHavingVeryFewHalfOpenConnections(): try: if sys.platform[0:3] == "win": VER_THIS = StrictVersion(platform.version()) - return StrictVersion("5.1.2600")<=VER_THIS and StrictVersion("6.0.6000")>=VER_THIS + return ( + StrictVersion("5.1.2600") <= VER_THIS and + StrictVersion("6.0.6000") >= VER_THIS + ) return False except Exception: - return False + pass