Key file permissions #306
136
src/shared.py
136
src/shared.py
|
@ -202,31 +202,36 @@ def reloadMyAddressHashes():
|
||||||
hasEnabledKeys = False
|
hasEnabledKeys = False
|
||||||
for addressInKeysFile in configSections:
|
for addressInKeysFile in configSections:
|
||||||
if addressInKeysFile <> 'bitmessagesettings':
|
if addressInKeysFile <> 'bitmessagesettings':
|
||||||
hasEnabledKeys = True
|
|
||||||
isEnabled = config.getboolean(addressInKeysFile, 'enabled')
|
isEnabled = config.getboolean(addressInKeysFile, 'enabled')
|
||||||
if isEnabled:
|
if isEnabled:
|
||||||
if keyfileSecure:
|
hasEnabledKeys = True
|
||||||
status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile)
|
status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile)
|
||||||
if addressVersionNumber == 2 or addressVersionNumber == 3:
|
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.
|
# Returns a simple 32 bytes of information encoded in 64 Hex characters,
|
||||||
privEncryptionKey = decodeWalletImportFormat(
|
# or null if there was an error.
|
||||||
config.get(addressInKeysFile, 'privencryptionkey')).encode('hex')
|
privEncryptionKey = decodeWalletImportFormat(
|
||||||
|
config.get(addressInKeysFile, 'privencryptionkey')).encode('hex')
|
||||||
|
|
||||||
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
|
||||||
else:
|
|
||||||
sys.stderr.write('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2 or 3.\n')
|
if not keyfileSecure:
|
||||||
|
# Insecure keyfile permissions. Disable key.
|
||||||
|
config.set(addressInKeysFile, 'enabled', 'false')
|
||||||
else:
|
else:
|
||||||
# Insecure keyfile permissions. Disable key.
|
sys.stderr.write('Error in reloadMyAddressHashes: Can\'t handle address '
|
||||||
config.set(addressInKeysFile, 'enabled', 'false')
|
'versions other than 2 or 3.\n')
|
||||||
try:
|
|
||||||
if not keyfileSecure:
|
if not keyfileSecure:
|
||||||
with open(appdata + 'keys.dat', 'wb') as keyfile:
|
fixSensitiveFilePermissions(appdata + 'keys.dat', hasEnabledKeys)
|
||||||
config.write(keyfile)
|
if hasEnabledKeys:
|
||||||
except:
|
try:
|
||||||
print 'Failed to disable vulnerable keyfiles.'
|
with open(appdata + 'keys.dat', 'wb') as keyfile:
|
||||||
raise
|
config.write(keyfile)
|
||||||
|
except:
|
||||||
|
print 'Failed to disable vulnerable keys.'
|
||||||
|
raise
|
||||||
|
|
||||||
def reloadBroadcastSendersForWhichImWatching():
|
def reloadBroadcastSendersForWhichImWatching():
|
||||||
printLock.acquire()
|
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)
|
output = 'Part of the message is corrupt. The message cannot be displayed the normal way.\n\n' + repr(text)
|
||||||
return output
|
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):
|
def checkSensitiveFilePermissions(filename):
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
# TODO: This might deserve extra checks by someone familiar with
|
# TODO: This might deserve extra checks by someone familiar with
|
||||||
# Windows systems.
|
# Windows systems.
|
||||||
fileSecure = True
|
return True
|
||||||
else:
|
else:
|
||||||
fileSecure = secureFilePermissions(filename)
|
present_permissions = os.stat(filename)[0]
|
||||||
if not fileSecure:
|
disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO
|
||||||
print
|
return present_permissions & disallowed_permissions == 0
|
||||||
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
|
|
||||||
|
|
||||||
# Fixes permissions on a sensitive file.
|
# Fixes permissions on a sensitive file.
|
||||||
def fixSensitiveFilePermissions(filename):
|
def fixSensitiveFilePermissions(filename, hasEnabledKeys):
|
||||||
present_permissions = os.stat(filename)[0]
|
if hasEnabledKeys:
|
||||||
disallowed_permissions = stat.S_IRWXG | stat.S_IRWXO
|
print
|
||||||
allowed_permissions = ((1<<32)-1) ^ disallowed_permissions
|
print '******************************************************************'
|
||||||
new_permissions = (
|
print '** !! WARNING !! **'
|
||||||
allowed_permissions & present_permissions)
|
print '******************************************************************'
|
||||||
os.chmod(filename, new_permissions)
|
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
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user