From e1182f8000e0ea107d1a73c224cb271c7cd06b9b Mon Sep 17 00:00:00 2001 From: cheatfate Date: Tue, 25 Aug 2020 13:16:31 +0300 Subject: [PATCH] Add insecure password for automated testing. Fix checkDataDir to run before setupLogging. --- beacon_chain/beacon_node.nim | 8 +-- beacon_chain/conf.nim | 12 ++++ beacon_chain/eth2_network.nim | 31 +++++++- beacon_chain/keystore_management.nim | 102 ++++++++++++++++----------- 4 files changed, 102 insertions(+), 51 deletions(-) diff --git a/beacon_chain/beacon_node.nim b/beacon_chain/beacon_node.nim index 1f3c23f07..f8cdf4d84 100644 --- a/beacon_chain/beacon_node.nim +++ b/beacon_chain/beacon_node.nim @@ -900,7 +900,7 @@ proc createPidFile(filename: string) = proc checkDataDir(conf: BeaconNodeConf) = ## Checks `conf.dataDir`. - ## If folder exists, prcoedure will check it for access and + ## If folder exists, procedure will check it for access and ## permissions `0750 (rwxr-x---)`, if folder do not exists it will be created ## with permissions `0750 (rwxr-x---)`. let dataDir = string(conf.dataDir) @@ -1136,6 +1136,8 @@ programMain: # This is ref so we can mutate it (to erase it) after the initial loading. stateSnapshotContents: ref string + checkDataDir(config) + setupLogging(config.logLevel, config.logFile) if config.eth2Network.isSome: @@ -1173,8 +1175,6 @@ programMain: case config.cmd of createTestnet: - checkDataDir(config) - let launchPadDeposits = try: Json.loadFile(config.testnetDepositsFile.string, seq[LaunchPadDeposit]) except SerializationError as err: @@ -1235,8 +1235,6 @@ programMain: cmdParams = commandLineParams(), config - checkDataDir(config) - createPidFile(config.dataDir.string / "beacon_node.pid") config.createDumpDirs() diff --git a/beacon_chain/conf.nim b/beacon_chain/conf.nim index d78df2a83..122c226e3 100644 --- a/beacon_chain/conf.nim +++ b/beacon_chain/conf.nim @@ -224,6 +224,12 @@ type "(random|) (default: random)" name: "netkey-file" }: string + netKeyInsecurePassword* {. + defaultValue: false, + desc: "Use pre-generated INSECURE password for network private key " & + "file (default: false)" + name: "insecure-netkey-password" }: bool + of createTestnet: testnetDepositsFile* {. desc: "A LaunchPad deposits file for the genesis state validators" @@ -275,6 +281,12 @@ type desc: "Output file with network private key for the network" name: "netkey-file" }: OutFile + outputNetKeyInsecurePassword* {. + defaultValue: false, + desc: "Use pre-generated INSECURE password for network private key " & + "file (default: false)" + name: "insecure-netkey-password" }: bool + of wallets: case walletsCmd* {.command.}: WalletsCmd of WalletsCmd.create: diff --git a/beacon_chain/eth2_network.nim b/beacon_chain/eth2_network.nim index b6abe9588..6b5fe2dbf 100644 --- a/beacon_chain/eth2_network.nim +++ b/beacon_chain/eth2_network.nim @@ -272,6 +272,9 @@ const when libp2p_pki_schemes != "secp256k1": {.fatal: "Incorrect building process, please use -d:\"libp2p_pki_schemes=secp256k1\"".} +const + NetworkInsecureKeyPassword = "INSECUREPASSWORD" + template libp2pProtocol*(name: string, version: int) {.pragma.} func shortLog*(peer: Peer): string = shortLog(peer.info.peerId) @@ -1221,7 +1224,15 @@ proc getPersistentNetKeys*(rng: var BrHmacDrbgContext, if fileAccessible(keyPath, {AccessFlags.Find}): info "Network key storage is present, unlocking", key_path = keyPath - let res = loadNetKeystore(keyPath) + + # Insecure password used only for automated testing. + let insecurePassword = + if conf.netKeyInsecurePassword: + some(NetworkInsecureKeyPassword) + else: + none[string]() + + let res = loadNetKeystore(keyPath, insecurePassword) if res.isNone(): fatal "Could not load network key file" quit QuitFailure @@ -1242,7 +1253,14 @@ proc getPersistentNetKeys*(rng: var BrHmacDrbgContext, let privKey = rres.get() let pubKey = privKey.getKey().tryGet() - let sres = saveNetKeystore(rng, keyPath, privKey) + # Insecure password used only for automated testing. + let insecurePassword = + if conf.netKeyInsecurePassword: + some(NetworkInsecureKeyPassword) + else: + none[string]() + + let sres = saveNetKeystore(rng, keyPath, privKey, insecurePassword) if sres.isErr(): fatal "Could not create network key file", key_path = keyPath quit QuitFailure @@ -1267,7 +1285,14 @@ proc getPersistentNetKeys*(rng: var BrHmacDrbgContext, let privKey = rres.get() let pubKey = privKey.getKey().tryGet() - let sres = saveNetKeystore(rng, keyPath, privKey) + # Insecure password used only for automated testing. + let insecurePassword = + if conf.outputNetKeyInsecurePassword: + some(NetworkInsecureKeyPassword) + else: + none[string]() + + let sres = saveNetKeystore(rng, keyPath, privKey, insecurePassword) if sres.isErr(): fatal "Could not create network key file" quit QuitFailure diff --git a/beacon_chain/keystore_management.nim b/beacon_chain/keystore_management.nim index e661894d0..6831a884d 100644 --- a/beacon_chain/keystore_management.nim +++ b/beacon_chain/keystore_management.nim @@ -131,7 +131,8 @@ type FailedToCreateSecretFile FailedToCreateKeystoreFile -proc loadNetKeystore*(keyStorePath: string): Option[lcrypto.PrivateKey] = +proc loadNetKeystore*(keyStorePath: string, + insecurePwd: Option[string]): Option[lcrypto.PrivateKey] = when defined(windows): # Windows do not support per-user permissions, skiping verification part. discard @@ -167,60 +168,75 @@ proc loadNetKeystore*(keyStorePath: string): Option[lcrypto.PrivateKey] = error "Invalid network keystore", err = err.formatMsg(keystorePath) return - var remainingAttempts = 3 - var counter = 0 - var prompt = "Please enter passphrase to unlock networking key: " - while remainingAttempts > 0: - let passphrase = KeystorePass: - try: - readPasswordFromStdin(prompt) - except IOError: - error "Could not read password from stdin" - return - - let decrypted = decryptNetKeystore(keystore, passphrase) + if insecurePwd.isSome(): + warn "Using insecure password to unlock networking key" + let decrypted = decryptNetKeystore(keystore, KeystorePass insecurePwd.get()) if decrypted.isOk: return some(decrypted.get()) else: - dec remainingAttempts - inc counter - os.sleep(1000 * counter) error "Network keystore decryption failed", key_store = keyStorePath + return + else: + var remainingAttempts = 3 + var counter = 0 + var prompt = "Please enter passphrase to unlock networking key: " + while remainingAttempts > 0: + let passphrase = KeystorePass: + try: + readPasswordFromStdin(prompt) + except IOError: + error "Could not read password from stdin" + return + + let decrypted = decryptNetKeystore(keystore, passphrase) + if decrypted.isOk: + return some(decrypted.get()) + else: + dec remainingAttempts + inc counter + os.sleep(1000 * counter) + error "Network keystore decryption failed", key_store = keyStorePath proc saveNetKeystore*(rng: var BrHmacDrbgContext, keyStorePath: string, - netKey: lcrypto.PrivateKey): Result[void, KeystoreGenerationError] = + netKey: lcrypto.PrivateKey, insecurePwd: Option[string] + ): Result[void, KeystoreGenerationError] = var password, confirmedPassword: TaintedString - while true: - let prompt = "Please enter NEW password to lock network key storage: " + if insecurePwd.isSome(): + warn "Using insecure password to lock networking key" + password = insecurePwd.get() + else: + while true: + let prompt = "Please enter NEW password to lock network key storage: " - password = - try: - readPasswordFromStdin(prompt) - except IOError: - error "Could not read password from stdin" - return err(FailedToCreateKeystoreFile) + password = + try: + readPasswordFromStdin(prompt) + except IOError: + error "Could not read password from stdin" + return err(FailedToCreateKeystoreFile) - if len(password) < minPasswordLen: - echo "The entered password should be at least ", minPasswordLen, - " characters" - continue - elif password in mostCommonPasswords: - echo80 "The entered password is too commonly used and it would be easy " & - "to brute-force with automated tools." - continue + if len(password) < minPasswordLen: + echo "The entered password should be at least ", minPasswordLen, + " characters" + continue + elif password in mostCommonPasswords: + echo80 "The entered password is too commonly used and it would be " & + "easy to brute-force with automated tools." + continue - confirmedPassword = - try: - readPasswordFromStdin("Please confirm, network key storage password: ") - except IOError: - error "Could not read password from stdin" - return err(FailedToCreateKeystoreFile) + confirmedPassword = + try: + readPasswordFromStdin("Please confirm, network key storage " & + "password: ") + except IOError: + error "Could not read password from stdin" + return err(FailedToCreateKeystoreFile) - if password != confirmedPassword: - echo "Passwords don't match, please try again" - continue + if password != confirmedPassword: + echo "Passwords don't match, please try again" + continue - break + break let keyStore = createNetKeystore(kdfScrypt, rng, netKey, KeystorePass password)