Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_steel/tests/rig/make_wallet.py

2.6 KiB, 1 run

created by r1870400018:14551, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1#!/usr/bin/env python3
2"""Create a Steel wallet in the rig.
3
4Wallet creation reads a choice and an admin name from stdin, then prompts twice
5for a passphrase through crossterm's raw mode -- which needs a real terminal, so
6a pipe will not do. This gives it a pty. In raw mode Enter arrives as a carriage
7return, not a newline; a newline is not a submit and the prompt simply waits.
8
9The passphrase is a throwaway for a wallet that lives for thirty seconds and
10holds nothing.
11"""
12
13import os
14import pty
15import re
16import select
17import sys
18import time
19
20RIG = os.environ.get("RIG_DIR") or sys.exit("RIG_DIR is not set")
21PASS = "rig-test-passphrase-not-a-secret"
22NAME = "rig"
23
24pid, fd = pty.fork()
25if pid == 0:
26 os.chdir(RIG)
27 os.environ["TERM"] = "xterm"
28 os.execv(RIG + "/steel", [RIG + "/steel"])
29
30log = []
31sent = set()
32deadline = time.time() + 60
33
34def feed(what, tag):
35 if tag in sent:
36 return
37 sent.add(tag)
38 os.write(fd, what.encode())
39
40while time.time() < deadline:
41 r, _, _ = select.select([fd], [], [], 0.5)
42 if not r:
43 continue
44 try:
45 chunk = os.read(fd, 4096).decode("utf-8", "replace")
46 except OSError:
47 break
48 if not chunk:
49 break
50 log.append(chunk)
51 sys.stdout.write(chunk)
52 sys.stdout.flush()
53 blob = "".join(log)
54
55 # The menu: choose to create a new wallet.
56 if re.search(r"2\s*[.):]", blob) and "choice" not in sent:
57 sent.add("choice")
58 time.sleep(0.3)
59 os.write(fd, b"2\n")
60 continue
61 # The admin's name.
62 if re.search(r"(name|user)", blob, re.I) and "choice" in sent and "name" not in sent:
63 sent.add("name")
64 time.sleep(0.3)
65 os.write(fd, (NAME + "\n").encode())
66 continue
67 # Two passphrase prompts. These are read in crossterm raw mode, where Enter
68 # arrives as a carriage return -- a newline is not a submit and the prompt
69 # simply waits.
70 if blob.count("Enter a passphrase") >= 1 and "p1" not in sent:
71 sent.add("p1")
72 time.sleep(0.5)
73 os.write(fd, (PASS + "\r").encode())
74 continue
75 if blob.count("Re-enter") >= 1 and "p2" not in sent:
76 sent.add("p2")
77 time.sleep(0.5)
78 os.write(fd, (PASS + "\r").encode())
79 continue
80 # Done: leave the shell.
81 if ("p2" in sent) and re.search(r"(>|\$|shell|Steel)", blob) and "exit" not in sent:
82 sent.add("exit")
83 time.sleep(1.0)
84 os.write(fd, b"exit\n")
85 break
86
87time.sleep(1.5)
88os.close(fd)
89print("\n--- steps taken:", sorted(sent))
90print("--- wallet.jdat:", "PRESENT" if os.path.exists(RIG + "/wallet.jdat") else "ABSENT")