def get_shared_secret_txn(): # Load secret from database, if it exists. secret_in_db_hex = Config.objects.get_config("rpc_shared_secret") if secret_in_db_hex is None: secret_in_db = None else: secret_in_db = to_bin(secret_in_db_hex) # Load secret from the filesystem, if it exists. secret_on_fs = get_shared_secret_from_filesystem() if secret_in_db is None and secret_on_fs is None: secret = os.urandom(16) # 16-bytes of crypto-standard noise. Config.objects.set_config("rpc_shared_secret", to_hex(secret)) set_shared_secret_on_filesystem(secret) elif secret_in_db is None: secret = secret_on_fs Config.objects.set_config("rpc_shared_secret", to_hex(secret)) elif secret_on_fs is None: secret = secret_in_db set_shared_secret_on_filesystem(secret) elif secret_in_db == secret_on_fs: secret = secret_in_db # or secret_on_fs. else: raise AssertionError( "The secret stored in the database does not match the secret " "stored on the filesystem at %s. Please investigate." % get_shared_secret_filesystem_path()) return secret
def test__exits_zero_if_secret_exists(self): security.set_shared_secret_on_filesystem(factory.make_bytes()) print = self.patch(security, "print") error = self.assertRaises( SystemExit, security.CheckForSharedSecretScript.run, sentinel.args) self.assertEqual(0, error.code) self.assertThat( print, MockCalledOnceWith("Shared-secret is installed."))
def test__writes_with_secure_permissions(self): secret = factory.make_bytes() security.set_shared_secret_on_filesystem(secret) secret_path = security.get_shared_secret_filesystem_path() perms_observed = stat(secret_path).st_mode & 0o777 perms_expected = 0o640 self.assertEqual( perms_expected, perms_observed, "Expected %04o, got %04o." % (perms_expected, perms_observed))
def test__writes_with_lock(self): lock = FileLock(security.get_shared_secret_filesystem_path()) self.assertFalse(lock.is_locked()) def check_lock(path, data): self.assertTrue(lock.is_locked()) write_text_file = self.patch_autospec(security, "write_text_file") write_text_file.side_effect = check_lock security.set_shared_secret_on_filesystem(b"foo") self.assertThat(write_text_file, MockCalledOnceWith(ANY, ANY)) self.assertFalse(lock.is_locked())
def test__prompts_user_for_secret(self): url = factory.make_simple_http_url() expected_previous_value = factory.make_bytes() set_shared_secret_on_filesystem(expected_previous_value) InstallSharedSecretScript_mock = self.patch( register_command, "InstallSharedSecretScript") args = self.make_args(url=url, secret=None) register_command.run(args) observed = get_shared_secret_from_filesystem() self.expectThat(expected_previous_value, Equals(observed)) self.expectThat(InstallSharedSecretScript_mock.run, MockCalledOnceWith(args))
def run(args): """Register the rack controller with a region controller.""" # If stdin supplied to program URL must be passed as argument. if not stdin.isatty() and args.url is None: print( "MAAS region controller URL must be given when supplying the " "shared secret via stdin with a non-interactive shell." ) raise SystemExit(1) try: call_and_check(["systemctl", "stop", "maas-rackd"]) except ExternalProcessError as e: print("Unable to stop maas-rackd service.", file=stderr) print("Failed with error: %s." % e.output_as_unicode, file=stderr) raise SystemExit(1) # maas_id could be stale so remove it set_maas_id(None) if args.url is not None: with ClusterConfiguration.open_for_update() as config: config.maas_url = args.url else: try: url = input("MAAS region controller URL: ") except EOFError: print() # So that the shell prompt appears on the next line. raise SystemExit(1) except KeyboardInterrupt: print() # So that the shell prompt appears on the next line. raise with ClusterConfiguration.open_for_update() as config: config.maas_url = url print("MAAS region controller URL saved as %s." % url) if args.secret is not None: set_shared_secret_on_filesystem(to_bin(args.secret)) else: InstallSharedSecretScript.run(args) try: call_and_check(["systemctl", "enable", "maas-rackd"]) call_and_check(["systemctl", "start", "maas-rackd"]) except ExternalProcessError as e: print( "Unable to enable and start the maas-rackd service.", file=stderr ) print("Failed with error: %s." % e.output_as_unicode, file=stderr) raise SystemExit(1)
def test__writes_secret(self): secret = factory.make_bytes() security.set_shared_secret_on_filesystem(secret) self.assertEqual(secret, self.read_secret())
def test_reads_with_lock(self): mock_file_lock = self.patch_autospec(security, "FileLock") security.set_shared_secret_on_filesystem(b"foo") security.get_shared_secret_from_filesystem() mock_file_lock.assert_called()
def ensureSharedSecret(self): """Make sure the shared-secret is set.""" if get_shared_secret_from_filesystem() is None: set_shared_secret_on_filesystem(factory.make_bytes())