Merge pull request #752 from Atheros1/master

Backup keys.dat before writing
This commit is contained in:
Jonathan Warren 2014-12-25 21:09:16 -05:00
commit d7c0c09d1e
8 changed files with 52 additions and 64 deletions

View File

@ -431,8 +431,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
if not shared.safeConfigGetBoolean(address, 'chan'): if not shared.safeConfigGetBoolean(address, 'chan'):
raise APIError(25, 'Specified address is not a chan address. Use deleteAddress API call instead.') raise APIError(25, 'Specified address is not a chan address. Use deleteAddress API call instead.')
shared.config.remove_section(address) shared.config.remove_section(address)
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
return 'success' return 'success'
elif method == 'deleteAddress': elif method == 'deleteAddress':
@ -445,8 +444,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
if not shared.config.has_section(address): if not shared.config.has_section(address):
raise APIError(13, 'Could not find this address in your keys.dat file.') raise APIError(13, 'Could not find this address in your keys.dat file.')
shared.config.remove_section(address) shared.config.remove_section(address)
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
shared.UISignalQueue.put(('rerenderInboxFromLabels','')) shared.UISignalQueue.put(('rerenderInboxFromLabels',''))
shared.UISignalQueue.put(('rerenderSentToLabels','')) shared.UISignalQueue.put(('rerenderSentToLabels',''))
shared.reloadMyAddressHashes() shared.reloadMyAddressHashes()

View File

@ -471,15 +471,13 @@ def handlech(c, stdscr):
label = t label = t
shared.config.set(a, "label", label) shared.config.set(a, "label", label)
# Write config # Write config
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
addresses[addrcur][0] = label addresses[addrcur][0] = label
elif t == "4": # Enable address elif t == "4": # Enable address
a = addresses[addrcur][2] a = addresses[addrcur][2]
shared.config.set(a, "enabled", "true") # Set config shared.config.set(a, "enabled", "true") # Set config
# Write config # Write config
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
# Change color # Change color
if shared.safeConfigGetBoolean(a, 'chan'): if shared.safeConfigGetBoolean(a, 'chan'):
addresses[addrcur][3] = 9 # orange addresses[addrcur][3] = 9 # orange
@ -494,16 +492,14 @@ def handlech(c, stdscr):
shared.config.set(a, "enabled", "false") # Set config shared.config.set(a, "enabled", "false") # Set config
addresses[addrcur][3] = 8 # Set color to gray addresses[addrcur][3] = 8 # Set color to gray
# Write config # Write config
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
addresses[addrcur][1] = False addresses[addrcur][1] = False
shared.reloadMyAddressHashes() # Reload address hashes shared.reloadMyAddressHashes() # Reload address hashes
elif t == "6": # Delete address elif t == "6": # Delete address
r, t = d.inputbox("Type in \"I want to delete this address\"", width=50) r, t = d.inputbox("Type in \"I want to delete this address\"", width=50)
if r == d.DIALOG_OK and t == "I want to delete this address": if r == d.DIALOG_OK and t == "I want to delete this address":
shared.config.remove_section(addresses[addrcur][2]) shared.config.remove_section(addresses[addrcur][2])
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
del addresses[addrcur] del addresses[addrcur]
elif t == "7": # Special address behavior elif t == "7": # Special address behavior
a = addresses[addrcur][2] a = addresses[addrcur][2]
@ -534,8 +530,7 @@ def handlech(c, stdscr):
shared.config.set(a, "mailinglistname", mn) shared.config.set(a, "mailinglistname", mn)
addresses[addrcur][3] = 6 # Set color to magenta addresses[addrcur][3] = 6 # Set color to magenta
# Write config # Write config
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
elif menutab == 5: elif menutab == 5:
d.set_background_title("Subscriptions Dialog Box") d.set_background_title("Subscriptions Dialog Box")
r, t = d.menu("Do what with subscription to \""+subscriptions[subcur][0]+"\"?", r, t = d.menu("Do what with subscription to \""+subscriptions[subcur][0]+"\"?",

View File

@ -458,8 +458,7 @@ class MyForm(QtGui.QMainWindow):
self, 'Message', displayMsg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) self, 'Message', displayMsg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes: if reply == QtGui.QMessageBox.Yes:
shared.config.remove_section(addressInKeysFile) shared.config.remove_section(addressInKeysFile)
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
# Configure Bitmessage to start on startup (or remove the # Configure Bitmessage to start on startup (or remove the
# configuration) based on the setting in the keys.dat file # configuration) based on the setting in the keys.dat file
@ -1332,7 +1331,7 @@ class MyForm(QtGui.QMainWindow):
reply = QtGui.QMessageBox.question(self, _translate("MainWindow", "Open keys.dat?"), _translate( reply = QtGui.QMessageBox.question(self, _translate("MainWindow", "Open keys.dat?"), _translate(
"MainWindow", "You may manage your keys by editing the keys.dat file stored in\n %1 \nIt is important that you back up this file. Would you like to open the file now? (Be sure to close Bitmessage before making any changes.)").arg(shared.appdata), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) "MainWindow", "You may manage your keys by editing the keys.dat file stored in\n %1 \nIt is important that you back up this file. Would you like to open the file now? (Be sure to close Bitmessage before making any changes.)").arg(shared.appdata), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes: if reply == QtGui.QMessageBox.Yes:
self.openKeysFile() shared.openKeysFile()
def click_actionDeleteAllTrashedMessages(self): def click_actionDeleteAllTrashedMessages(self):
if QtGui.QMessageBox.question(self, _translate("MainWindow", "Delete trash?"), _translate("MainWindow", "Are you sure you want to delete all trashed messages?"), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) == QtGui.QMessageBox.No: if QtGui.QMessageBox.question(self, _translate("MainWindow", "Delete trash?"), _translate("MainWindow", "Are you sure you want to delete all trashed messages?"), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) == QtGui.QMessageBox.No:
@ -1419,17 +1418,10 @@ class MyForm(QtGui.QMainWindow):
if self.connectDialogInstance.exec_(): if self.connectDialogInstance.exec_():
if self.connectDialogInstance.ui.radioButtonConnectNow.isChecked(): if self.connectDialogInstance.ui.radioButtonConnectNow.isChecked():
shared.config.remove_option('bitmessagesettings', 'dontconnect') shared.config.remove_option('bitmessagesettings', 'dontconnect')
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
else: else:
self.click_actionSettings() self.click_actionSettings()
def openKeysFile(self):
if 'linux' in sys.platform:
subprocess.call(["xdg-open", shared.appdata + 'keys.dat'])
else:
os.startfile(shared.appdata + 'keys.dat')
def changeEvent(self, event): def changeEvent(self, event):
if event.type() == QtCore.QEvent.WindowStateChange: if event.type() == QtCore.QEvent.WindowStateChange:
if self.windowState() & QtCore.Qt.WindowMinimized: if self.windowState() & QtCore.Qt.WindowMinimized:
@ -2414,8 +2406,7 @@ class MyForm(QtGui.QMainWindow):
# shared.config.set('bitmessagesettings', 'maxcores', # shared.config.set('bitmessagesettings', 'maxcores',
# str(self.settingsDialogInstance.ui.comboBoxMaxCores.currentText())) # str(self.settingsDialogInstance.ui.comboBoxMaxCores.currentText()))
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
if 'win32' in sys.platform or 'win64' in sys.platform: if 'win32' in sys.platform or 'win64' in sys.platform:
# Auto-startup for Windows # Auto-startup for Windows
@ -2460,8 +2451,7 @@ class MyForm(QtGui.QMainWindow):
os.makedirs(shared.appdata) os.makedirs(shared.appdata)
sqlStoredProcedure('movemessagstoappdata') sqlStoredProcedure('movemessagstoappdata')
# Write the keys.dat file to disk in the new location # Write the keys.dat file to disk in the new location
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
# Write the knownnodes.dat file to disk in the new location # Write the knownnodes.dat file to disk in the new location
shared.knownNodesLock.acquire() shared.knownNodesLock.acquire()
output = open(shared.appdata + 'knownnodes.dat', 'wb') output = open(shared.appdata + 'knownnodes.dat', 'wb')
@ -2480,8 +2470,7 @@ class MyForm(QtGui.QMainWindow):
def click_radioButtonBlacklist(self): def click_radioButtonBlacklist(self):
if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'white': if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'white':
shared.config.set('bitmessagesettings', 'blackwhitelist', 'black') shared.config.set('bitmessagesettings', 'blackwhitelist', 'black')
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
# self.ui.tableWidgetBlacklist.clearContents() # self.ui.tableWidgetBlacklist.clearContents()
self.ui.tableWidgetBlacklist.setRowCount(0) self.ui.tableWidgetBlacklist.setRowCount(0)
self.loadBlackWhiteList() self.loadBlackWhiteList()
@ -2490,8 +2479,7 @@ class MyForm(QtGui.QMainWindow):
def click_radioButtonWhitelist(self): def click_radioButtonWhitelist(self):
if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'black': if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'black':
shared.config.set('bitmessagesettings', 'blackwhitelist', 'white') shared.config.set('bitmessagesettings', 'blackwhitelist', 'white')
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
# self.ui.tableWidgetBlacklist.clearContents() # self.ui.tableWidgetBlacklist.clearContents()
self.ui.tableWidgetBlacklist.setRowCount(0) self.ui.tableWidgetBlacklist.setRowCount(0)
self.loadBlackWhiteList() self.loadBlackWhiteList()
@ -2563,8 +2551,7 @@ class MyForm(QtGui.QMainWindow):
shared.config.set(str(addressAtCurrentRow), 'mailinglistname', str( shared.config.set(str(addressAtCurrentRow), 'mailinglistname', str(
self.dialog.ui.lineEditMailingListName.text().toUtf8())) self.dialog.ui.lineEditMailingListName.text().toUtf8()))
self.ui.tableWidgetYourIdentities.item(currentRow, 1).setTextColor(QtGui.QColor(137, 04, 177)) # magenta self.ui.tableWidgetYourIdentities.item(currentRow, 1).setTextColor(QtGui.QColor(137, 04, 177)) # magenta
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
self.rerenderInboxToLabels() self.rerenderInboxToLabels()
def click_NewAddressDialog(self): def click_NewAddressDialog(self):
@ -3066,8 +3053,7 @@ class MyForm(QtGui.QMainWindow):
addressAtCurrentRow = str( addressAtCurrentRow = str(
self.ui.tableWidgetYourIdentities.item(currentRow, 1).text()) self.ui.tableWidgetYourIdentities.item(currentRow, 1).text())
shared.config.set(addressAtCurrentRow, 'enabled', 'true') shared.config.set(addressAtCurrentRow, 'enabled', 'true')
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
self.ui.tableWidgetYourIdentities.item( self.ui.tableWidgetYourIdentities.item(
currentRow, 0).setTextColor(QApplication.palette().text().color()) currentRow, 0).setTextColor(QApplication.palette().text().color())
self.ui.tableWidgetYourIdentities.item( self.ui.tableWidgetYourIdentities.item(
@ -3093,8 +3079,7 @@ class MyForm(QtGui.QMainWindow):
currentRow, 2).setTextColor(QtGui.QColor(128, 128, 128)) currentRow, 2).setTextColor(QtGui.QColor(128, 128, 128))
if shared.safeConfigGetBoolean(addressAtCurrentRow, 'mailinglist'): if shared.safeConfigGetBoolean(addressAtCurrentRow, 'mailinglist'):
self.ui.tableWidgetYourIdentities.item(currentRow, 1).setTextColor(QtGui.QColor(137, 04, 177)) # magenta self.ui.tableWidgetYourIdentities.item(currentRow, 1).setTextColor(QtGui.QColor(137, 04, 177)) # magenta
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
shared.reloadMyAddressHashes() shared.reloadMyAddressHashes()
def on_action_YourIdentitiesClipboard(self): def on_action_YourIdentitiesClipboard(self):
@ -3291,8 +3276,7 @@ class MyForm(QtGui.QMainWindow):
currentRow, 1).text() currentRow, 1).text()
shared.config.set(str(addressAtCurrentRow), 'label', str( shared.config.set(str(addressAtCurrentRow), 'label', str(
self.ui.tableWidgetYourIdentities.item(currentRow, 0).text().toUtf8())) self.ui.tableWidgetYourIdentities.item(currentRow, 0).text().toUtf8()))
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
self.rerenderComboBoxSendFrom() self.rerenderComboBoxSendFrom()
# self.rerenderInboxFromLabels() # self.rerenderInboxFromLabels()
self.rerenderInboxToLabels() self.rerenderInboxToLabels()

View File

@ -129,8 +129,7 @@ class addressGenerator(threading.Thread):
address, 'privSigningKey', privSigningKeyWIF) address, 'privSigningKey', privSigningKeyWIF)
shared.config.set( shared.config.set(
address, 'privEncryptionKey', privEncryptionKeyWIF) address, 'privEncryptionKey', privEncryptionKeyWIF)
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
# The API and the join and create Chan functionality # The API and the join and create Chan functionality
# both need information back from the address generator. # both need information back from the address generator.
@ -244,8 +243,7 @@ class addressGenerator(threading.Thread):
address, 'privSigningKey', privSigningKeyWIF) address, 'privSigningKey', privSigningKeyWIF)
shared.config.set( shared.config.set(
address, 'privEncryptionKey', privEncryptionKeyWIF) address, 'privEncryptionKey', privEncryptionKeyWIF)
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
shared.UISignalQueue.put(('writeNewAddressToTable', ( shared.UISignalQueue.put(('writeNewAddressToTable', (
label, address, str(streamNumber)))) label, address, str(streamNumber))))

View File

@ -150,8 +150,7 @@ class singleWorker(threading.Thread):
try: try:
shared.config.set( shared.config.set(
myAddress, 'lastpubkeysendtime', str(int(time.time()))) myAddress, 'lastpubkeysendtime', str(int(time.time())))
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
except: except:
# The user deleted the address out of the keys.dat file before this # The user deleted the address out of the keys.dat file before this
# finished. # finished.
@ -248,8 +247,7 @@ class singleWorker(threading.Thread):
try: try:
shared.config.set( shared.config.set(
myAddress, 'lastpubkeysendtime', str(int(time.time()))) myAddress, 'lastpubkeysendtime', str(int(time.time())))
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
except: except:
# The user deleted the address out of the keys.dat file before this # The user deleted the address out of the keys.dat file before this
# finished. # finished.
@ -345,8 +343,7 @@ class singleWorker(threading.Thread):
try: try:
shared.config.set( shared.config.set(
myAddress, 'lastpubkeysendtime', str(int(time.time()))) myAddress, 'lastpubkeysendtime', str(int(time.time())))
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
except Exception as err: except Exception as err:
logger.error('Error: Couldn\'t add the lastpubkeysendtime to the keys.dat file. Error message: %s' % err) logger.error('Error: Couldn\'t add the lastpubkeysendtime to the keys.dat file. Error message: %s' % err)

View File

@ -91,8 +91,6 @@ class sqlThread(threading.Thread):
shared.config.set('bitmessagesettings', 'sockslisten', 'false') shared.config.set('bitmessagesettings', 'sockslisten', 'false')
shared.config.set('bitmessagesettings', 'keysencrypted', 'false') shared.config.set('bitmessagesettings', 'keysencrypted', 'false')
shared.config.set('bitmessagesettings', 'messagesencrypted', 'false') shared.config.set('bitmessagesettings', 'messagesencrypted', 'false')
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
shared.config.write(configfile)
# People running earlier versions of PyBitmessage do not have the # People running earlier versions of PyBitmessage do not have the
# usedpersonally field in their pubkeys table. Let's add it. # usedpersonally field in their pubkeys table. Let's add it.
@ -103,8 +101,6 @@ class sqlThread(threading.Thread):
self.conn.commit() self.conn.commit()
shared.config.set('bitmessagesettings', 'settingsversion', '3') shared.config.set('bitmessagesettings', 'settingsversion', '3')
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
shared.config.write(configfile)
# People running earlier versions of PyBitmessage do not have the # People running earlier versions of PyBitmessage do not have the
# encodingtype field in their inbox and sent tables or the read field # encodingtype field in their inbox and sent tables or the read field
@ -138,6 +134,7 @@ class sqlThread(threading.Thread):
shared.config.set( shared.config.set(
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', '0') 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', '0')
shared.config.set('bitmessagesettings', 'settingsversion', '6') shared.config.set('bitmessagesettings', 'settingsversion', '6')
# From now on, let us keep a 'version' embedded in the messages.dat # 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 # file so that when we make changes to the database, the database
# version we are on can stay embedded in the messages.dat file. Let us # version we are on can stay embedded in the messages.dat file. Let us
@ -281,10 +278,7 @@ class sqlThread(threading.Thread):
'bitmessagesettings', 'stopresendingafterxdays', '') 'bitmessagesettings', 'stopresendingafterxdays', '')
shared.config.set( shared.config.set(
'bitmessagesettings', 'stopresendingafterxmonths', '') 'bitmessagesettings', 'stopresendingafterxmonths', '')
#shared.config.set(
shared.config.set('bitmessagesettings', 'settingsversion', '8') shared.config.set('bitmessagesettings', 'settingsversion', '8')
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
shared.config.write(configfile)
# Add a new table: objectprocessorqueue with which to hold objects # Add a new table: objectprocessorqueue with which to hold objects
# that have yet to be processed if the user shuts down Bitmessage. # that have yet to be processed if the user shuts down Bitmessage.
@ -344,9 +338,7 @@ class sqlThread(threading.Thread):
shared.config.set('bitmessagesettings', 'maxdownloadrate', '0') shared.config.set('bitmessagesettings', 'maxdownloadrate', '0')
shared.config.set('bitmessagesettings', 'maxuploadrate', '0') shared.config.set('bitmessagesettings', 'maxuploadrate', '0')
shared.config.set('bitmessagesettings', 'settingsversion', '10') shared.config.set('bitmessagesettings', 'settingsversion', '10')
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
# The format of data stored in the pubkeys table has changed. Let's # 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.

View File

@ -133,8 +133,7 @@ def loadConfig():
os.makedirs(shared.appdata) os.makedirs(shared.appdata)
if not sys.platform.startswith('win'): if not sys.platform.startswith('win'):
os.umask(0o077) os.umask(0o077)
with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.writeKeysFile()
shared.config.write(configfile)
_loadTrustedPeer() _loadTrustedPeer()

View File

@ -18,6 +18,8 @@ import sys
import stat import stat
import threading import threading
import time import time
import shutil # used for moving the data folder and copying keys.dat
import datetime
from os import path, environ from os import path, environ
from struct import Struct from struct import Struct
import traceback import traceback
@ -838,4 +840,27 @@ def _checkAndShareBroadcastWithPeers(data):
shared.objectProcessorQueueSize += len(data) shared.objectProcessorQueueSize += len(data)
objectProcessorQueue.put((objectType,data)) objectProcessorQueue.put((objectType,data))
def openKeysFile():
if 'linux' in sys.platform:
subprocess.call(["xdg-open", shared.appdata + 'keys.dat'])
else:
os.startfile(shared.appdata + 'keys.dat')
def writeKeysFile():
fileName = shared.appdata + 'keys.dat'
fileNameBak = fileName + "." + datetime.datetime.now().strftime("%Y%j%H%M%S%f") + '.bak'
# create a backup copy to prevent the accidental loss due to the disk write failure
try:
shutil.copyfile(fileName, fileNameBak)
# The backup succeeded. This can fail if the file didn't exist before.
existingFileNameExisted = True
except:
existingFileNameExisted = False
# write the file
with open(fileName, 'wb') as configfile:
shared.config.write(configfile)
# delete a backup
if existingFileNameExisted:
os.remove(fileNameBak)
from debug import logger from debug import logger