Fixes loading of private key on Windows (#299)

Unix permissions don't work on Windows; 
adds check for correct ACL settings in Windows.
This commit is contained in:
markspanbroek 2022-11-07 09:54:24 -05:00 committed by GitHub
parent c893b1f0cb
commit be32b9619b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 2 deletions

View File

@ -49,6 +49,12 @@ proc secureWriteFile*[T: byte|char](path: string,
else:
writeFile(path, data, 0o600)
proc checkSecureFile*(path: string): IOResult[bool] =
when defined(windows):
checkCurrentUserOnlyACL(path)
else:
ok (? getPermissionsSet(path) == {UserRead, UserWrite})
proc checkAndCreateDataDir*(dataDir: string): bool =
when defined(posix):
let requiredPerms = 0o700

View File

@ -36,11 +36,11 @@ proc setupKey*(path: string): ?!PrivateKey =
res = ? PrivateKey.random(Rng.instance()[]).mapFailure(CodexKeyError)
bytes = ? res.getBytes().mapFailure(CodexKeyError)
? path.writeFile(bytes, SafePermissions.toInt()).mapFailure(CodexKeyError)
? path.secureWriteFile(bytes).mapFailure(CodexKeyError)
return PrivateKey.init(bytes).mapFailure(CodexKeyError)
info "Found a network private key"
if path.getPermissionsSet().get() != SafePermissions:
if not ? checkSecureFile(path).mapFailure(CodexKeyError):
warn "The network private key file is not safe, aborting"
return failure newException(
CodexKeyUnsafeError, "The network private key file is not safe")

View File

@ -1,4 +1,5 @@
import ./utils/teststatemachine
import ./utils/testoptionalcast
import ./utils/testkeyutils
{.warning[UnusedImport]: off.}

View File

@ -0,0 +1,34 @@
import std/unittest
import std/os
import pkg/libp2p
import pkg/questionable/results
import codex/utils/keyutils
when defined(windows):
import stew/windows/acl
suite "keyutils":
let path = getTempDir() / "CodexTest"
setup:
os.createDir(path)
teardown:
os.removeDir(path)
test "creates a key file when it does not exist yet":
check setupKey(path / "keyfile").isSuccess
check fileExists(path / "keyfile")
test "stores key in a file that's only readable by the user":
discard !setupKey(path / "keyfile")
when defined(posix):
check getFilePermissions(path / "keyfile") == {fpUserRead, fpUserWrite}
when defined(windows):
check checkCurrentUserOnlyACL(path / "keyfile").get()
test "reads key file when it does exist":
let key = !setupKey(path / "keyfile")
check !setupKey(path / "keyfile") == key