Test that exposesecret plugin correctly handles hsm-passphrase option
(node_factory)
| 4775 | |
| 4776 | @unittest.skipIf(VALGRIND, "It does not play well with prompt and key derivation.") |
| 4777 | def test_exposesecret_with_hsm_passphrase(node_factory): |
| 4778 | """Test that exposesecret plugin correctly handles hsm-passphrase option""" |
| 4779 | # Create a node with exposesecret-passphrase option |
| 4780 | l1 = node_factory.get_node(options={ |
| 4781 | 'exposesecret-passphrase': "test_exposesecret", |
| 4782 | }, start=False) |
| 4783 | |
| 4784 | hsm_path = os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, "hsm_secret") |
| 4785 | if os.path.exists(hsm_path): |
| 4786 | os.remove(hsm_path) |
| 4787 | |
| 4788 | # Generate hsm_secret with mnemonic and passphrase using hsmtool |
| 4789 | mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" |
| 4790 | hsm_passphrase = "test_hsm_passphrase" # Any passphrase, since we expect exposesecret to fail |
| 4791 | expected_format = "mnemonic with passphrase" |
| 4792 | |
| 4793 | hsmtool = HsmTool(node_factory.directory, "generatehsm", hsm_path) |
| 4794 | master_fd, slave_fd = os.openpty() |
| 4795 | hsmtool.start(stdin=slave_fd) |
| 4796 | hsmtool.wait_for_log(r"Introduce your BIP39 word list") |
| 4797 | write_all(master_fd, f"{mnemonic}\n".encode("utf-8")) |
| 4798 | hsmtool.wait_for_log(r"Enter your passphrase:") |
| 4799 | write_all(master_fd, f"{hsm_passphrase}\n".encode("utf-8")) |
| 4800 | assert hsmtool.proc.wait(WAIT_TIMEOUT) == 0 |
| 4801 | hsmtool.is_in_log(r"New hsm_secret file created") |
| 4802 | hsmtool.is_in_log(f"Format: {expected_format}") |
| 4803 | os.close(master_fd) |
| 4804 | os.close(slave_fd) |
| 4805 | |
| 4806 | # Add --hsm-passphrase option to trigger interactive prompting |
| 4807 | l1.daemon.opts["hsm-passphrase"] = None |
| 4808 | |
| 4809 | # Create a pty to handle the interactive passphrase prompt |
| 4810 | master_fd2, slave_fd2 = os.openpty() |
| 4811 | l1.daemon.start(stdin=slave_fd2, wait_for_initialized=False) |
| 4812 | |
| 4813 | # Wait for the passphrase prompt and provide it |
| 4814 | l1.daemon.wait_for_log("Enter hsm_secret passphrase:") |
| 4815 | print(f"DEBUG: About to send passphrase: '{hsm_passphrase}'") |
| 4816 | passphrase_bytes = f"{hsm_passphrase}\n".encode("utf-8") |
| 4817 | print(f"DEBUG: Passphrase bytes: {passphrase_bytes}") |
| 4818 | write_all(master_fd2, passphrase_bytes) |
| 4819 | print("DEBUG: Passphrase sent!") |
| 4820 | |
| 4821 | # Wait for the node to be ready |
| 4822 | l1.daemon.wait_for_log("Server started with public key") |
| 4823 | |
| 4824 | os.close(master_fd2) |
| 4825 | os.close(slave_fd2) |
| 4826 | |
| 4827 | # Test that exposesecret fails with mnemonic+passphrase format since it needs a passphrase |
| 4828 | with pytest.raises(RpcError, match="Secret with passphrase is not supported"): |
| 4829 | l1.rpc.exposesecret(passphrase="test_exposesecret") |
| 4830 | |
| 4831 | |
| 4832 | @unittest.skipIf(VALGRIND, "It does not play well with prompt and key derivation.") |