Test that exposesecret plugin correctly handles hsm-passphrase option
(node_factory)
| 4735 | |
| 4736 | @unittest.skipIf(VALGRIND, "It does not play well with prompt and key derivation.") |
| 4737 | def test_exposesecret_with_hsm_passphrase(node_factory): |
| 4738 | """Test that exposesecret plugin correctly handles hsm-passphrase option""" |
| 4739 | # Create a node with exposesecret-passphrase option |
| 4740 | l1 = node_factory.get_node(options={ |
| 4741 | 'exposesecret-passphrase': "test_exposesecret", |
| 4742 | }, start=False) |
| 4743 | |
| 4744 | hsm_path = os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, "hsm_secret") |
| 4745 | if os.path.exists(hsm_path): |
| 4746 | os.remove(hsm_path) |
| 4747 | |
| 4748 | # Generate hsm_secret with mnemonic and passphrase using hsmtool |
| 4749 | mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" |
| 4750 | hsm_passphrase = "test_hsm_passphrase" # Any passphrase, since we expect exposesecret to fail |
| 4751 | expected_format = "mnemonic with passphrase" |
| 4752 | |
| 4753 | hsmtool = HsmTool(node_factory.directory, "generatehsm", hsm_path) |
| 4754 | master_fd, slave_fd = os.openpty() |
| 4755 | hsmtool.start(stdin=slave_fd) |
| 4756 | hsmtool.wait_for_log(r"Introduce your BIP39 word list") |
| 4757 | write_all(master_fd, f"{mnemonic}\n".encode("utf-8")) |
| 4758 | hsmtool.wait_for_log(r"Enter your passphrase:") |
| 4759 | write_all(master_fd, f"{hsm_passphrase}\n".encode("utf-8")) |
| 4760 | assert hsmtool.proc.wait(WAIT_TIMEOUT) == 0 |
| 4761 | hsmtool.is_in_log(r"New hsm_secret file created") |
| 4762 | hsmtool.is_in_log(f"Format: {expected_format}") |
| 4763 | os.close(master_fd) |
| 4764 | os.close(slave_fd) |
| 4765 | |
| 4766 | # Add --hsm-passphrase option to trigger interactive prompting |
| 4767 | l1.daemon.opts["hsm-passphrase"] = None |
| 4768 | |
| 4769 | # Create a pty to handle the interactive passphrase prompt |
| 4770 | master_fd2, slave_fd2 = os.openpty() |
| 4771 | l1.daemon.start(stdin=slave_fd2, wait_for_initialized=False) |
| 4772 | |
| 4773 | # Wait for the passphrase prompt and provide it |
| 4774 | l1.daemon.wait_for_log("Enter hsm_secret passphrase:") |
| 4775 | print(f"DEBUG: About to send passphrase: '{hsm_passphrase}'") |
| 4776 | passphrase_bytes = f"{hsm_passphrase}\n".encode("utf-8") |
| 4777 | print(f"DEBUG: Passphrase bytes: {passphrase_bytes}") |
| 4778 | write_all(master_fd2, passphrase_bytes) |
| 4779 | print("DEBUG: Passphrase sent!") |
| 4780 | |
| 4781 | # Wait for the node to be ready |
| 4782 | l1.daemon.wait_for_log("Server started with public key") |
| 4783 | |
| 4784 | os.close(master_fd2) |
| 4785 | os.close(slave_fd2) |
| 4786 | |
| 4787 | # Test that exposesecret fails with mnemonic+passphrase format since it needs a passphrase |
| 4788 | with pytest.raises(RpcError, match="Secret with passphrase is not supported"): |
| 4789 | l1.rpc.exposesecret(passphrase="test_exposesecret") |
| 4790 | |
| 4791 | |
| 4792 | @unittest.skipIf(VALGRIND, "It does not play well with prompt and key derivation.") |