diff --git a/src/shared.py b/src/shared.py index 57067334..ea1e3848 100644 --- a/src/shared.py +++ b/src/shared.py @@ -202,31 +202,36 @@ def reloadMyAddressHashes(): hasEnabledKeys = False for addressInKeysFile in configSections: if addressInKeysFile <> 'bitmessagesettings': - hasEnabledKeys = True isEnabled = config.getboolean(addressInKeysFile, 'enabled') if isEnabled: - if keyfileSecure: - status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile) - if addressVersionNumber == 2 or addressVersionNumber == 3: - # Returns a simple 32 bytes of information encoded in 64 Hex characters, or null if there was an error. - privEncryptionKey = decodeWalletImportFormat( - config.get(addressInKeysFile, 'privencryptionkey')).encode('hex') + hasEnabledKeys = True + status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile) + if addressVersionNumber == 2 or addressVersionNumber == 3: + # Returns a simple 32 bytes of information encoded in 64 Hex characters, + # or null if there was an error. + privEncryptionKey = decodeWalletImportFormat( + config.get(addressInKeysFile, 'privencryptionkey')).encode('hex') - if len(privEncryptionKey) == 64:#It is 32 bytes encoded as 64 hex characters - myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(privEncryptionKey) - myAddressesByHash[hash] = addressInKeysFile - else: - sys.stderr.write('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2 or 3.\n') + if len(privEncryptionKey) == 64:#It is 32 bytes encoded as 64 hex characters + myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(privEncryptionKey) + myAddressesByHash[hash] = addressInKeysFile + + if not keyfileSecure: + # Insecure keyfile permissions. Disable key. + config.set(addressInKeysFile, 'enabled', 'false') else: - # Insecure keyfile permissions. Disable key. - config.set(addressInKeysFile, 'enabled', 'false') - try: - if not keyfileSecure: - with open(appdata + 'keys.dat', 'wb') as keyfile: - config.write(keyfile) - except: - print 'Failed to disable vulnerable keyfiles.' - raise + sys.stderr.write('Error in reloadMyAddressHashes: Can\'t handle address ' + 'versions other than 2 or 3.\n') + + if not keyfileSecure: + fixSensitiveFilePermissions(appdata + 'keys.dat', hasEnabledKeys) + if hasEnabledKeys: + try: + with open(appdata + 'keys.dat', 'wb') as keyfile: + config.write(keyfile) + except: + print 'Failed to disable vulnerable keys.' + raise def reloadBroadcastSendersForWhichImWatching(): printLock.acquire() @@ -318,53 +323,58 @@ def fixPotentiallyInvalidUTF8Data(text): output = 'Part of the message is corrupt. The message cannot be displayed the normal way.\n\n' + repr(text) return output +# Checks sensitive file permissions for inappropriate umask during keys.dat creation. +# (Or unwise subsequent chmod.) +# Returns true iff file appears to have appropriate permissions. def checkSensitiveFilePermissions(filename): if sys.platform == 'win32': # TODO: This might deserve extra checks by someone familiar with # Windows systems. - fileSecure = True + return True else: - fileSecure = secureFilePermissions(filename) - if not fileSecure: - print - print '******************************************************************' - print '** !! WARNING !! **' - print '******************************************************************' - print '** Possibly major security problem: **' - print '** Your keyfiles were vulnerable to being read by other users **' - print '** (including some untrusted daemons). You may wish to consider **' - print '** generating new keys and discontinuing use of your old ones. **' - print '** Your private keys have been disabled for your security, but **' - print '** you may re-enable them using the "Your Identities" tab in **' - print '** the default GUI or by modifying keys.dat such that your keys **' - print '** show "enabled = true". **' - try: - fixSensitiveFilePermissions(filename) - print '** The problem has been automatically fixed. **' - print '******************************************************************' - print - except Exception, e: - print '** Could NOT automatically fix permissions. **' - print '******************************************************************' - print - raise - return fileSecure - - -# Checks sensitive file permissions for inappropriate umask during keys.dat creation. -# (Or unwise subsequent chmod.) -# Returns true iff file appears to have appropriate permissions. -def secureFilePermissions(filename): - present_permissions = os.stat(filename)[0] - disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO - return present_permissions & disallowed_permissions == 0 + present_permissions = os.stat(filename)[0] + disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO + return present_permissions & disallowed_permissions == 0 # Fixes permissions on a sensitive file. -def fixSensitiveFilePermissions(filename): - present_permissions = os.stat(filename)[0] - disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO - allowed_permissions = ((1<<32)-1) ^ disallowed_permissions - new_permissions = ( - allowed_permissions & present_permissions) - os.chmod(filename, new_permissions) +def fixSensitiveFilePermissions(filename, hasEnabledKeys): + if hasEnabledKeys: + print + print '******************************************************************' + print '** !! WARNING !! **' + print '******************************************************************' + print '** Possibly major security problem: **' + print '** Your keyfile was vulnerable to being read by other users **' + print '** (including some untrusted daemons). You may wish to consider **' + print '** generating new keys and discontinuing use of your old ones. **' + print '** Your private keys have been disabled for your security, but **' + print '** you may re-enable them using the "Your Identities" tab in **' + print '** the default GUI or by modifying keys.dat such that your keys **' + print '** show "enabled = true". **' + else: + print '******************************************************************' + print '** !! WARNING !! **' + print '******************************************************************' + print '** Possibly major security problem: **' + print '** Your keyfile was vulnerable to being read by other users. **' + print '** Fortunately, you don\'t have any enabled keys, but be aware **' + print '** that any disabled keys may have been compromised by malware **' + print '** running by other users and that you should reboot before **' + print '** generating any new keys. **' + try: + present_permissions = os.stat(filename)[0] + disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO + allowed_permissions = ((1<<32)-1) ^ disallowed_permissions + new_permissions = ( + allowed_permissions & present_permissions) + os.chmod(filename, new_permissions) + + print '** The file permissions have been automatically fixed. **' + print '******************************************************************' + print + except Exception, e: + print '** Could NOT automatically fix permissions. **' + print '******************************************************************' + print + raise