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:
parent
c893b1f0cb
commit
be32b9619b
|
@ -49,6 +49,12 @@ proc secureWriteFile*[T: byte|char](path: string,
|
||||||
else:
|
else:
|
||||||
writeFile(path, data, 0o600)
|
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 =
|
proc checkAndCreateDataDir*(dataDir: string): bool =
|
||||||
when defined(posix):
|
when defined(posix):
|
||||||
let requiredPerms = 0o700
|
let requiredPerms = 0o700
|
||||||
|
|
|
@ -36,11 +36,11 @@ proc setupKey*(path: string): ?!PrivateKey =
|
||||||
res = ? PrivateKey.random(Rng.instance()[]).mapFailure(CodexKeyError)
|
res = ? PrivateKey.random(Rng.instance()[]).mapFailure(CodexKeyError)
|
||||||
bytes = ? res.getBytes().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)
|
return PrivateKey.init(bytes).mapFailure(CodexKeyError)
|
||||||
|
|
||||||
info "Found a network private key"
|
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"
|
warn "The network private key file is not safe, aborting"
|
||||||
return failure newException(
|
return failure newException(
|
||||||
CodexKeyUnsafeError, "The network private key file is not safe")
|
CodexKeyUnsafeError, "The network private key file is not safe")
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import ./utils/teststatemachine
|
import ./utils/teststatemachine
|
||||||
import ./utils/testoptionalcast
|
import ./utils/testoptionalcast
|
||||||
|
import ./utils/testkeyutils
|
||||||
|
|
||||||
{.warning[UnusedImport]: off.}
|
{.warning[UnusedImport]: off.}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue