fix: preserve user email in reissued cert subject via EASYRSA_REQ_EMAIL

build_client_full now passes EASYRSA_REQ_EMAIL in the subprocess
environment so EasyRSA bakes the user's email into the new cert's
subject DN, matching what was shown in the form.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Vlad Doloman
2026-06-24 23:12:31 +03:00
parent c610aed01d
commit 24cae3de6a

View File

@@ -191,8 +191,13 @@ class EasyRSAError(Exception):
pass pass
def _run_easyrsa(cmd: list[str], cwd: str) -> None: def _run_easyrsa(cmd: list[str], cwd: str,
result = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True) extra_env: Optional[dict[str, str]] = None) -> None:
env = None
if extra_env:
env = os.environ.copy()
env.update(extra_env)
result = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True, env=env)
if result.returncode != 0: if result.returncode != 0:
# Find the first non-flag argument after the binary (the actual easyrsa verb) # Find the first non-flag argument after the binary (the actual easyrsa verb)
verb = next((c for c in cmd[1:] if not c.startswith("-")), "unknown") verb = next((c for c in cmd[1:] if not c.startswith("-")), "unknown")
@@ -219,12 +224,14 @@ def revoke_issued(
def build_client_full( def build_client_full(
easyrsa_dir: str, pki_dir: str, cn: str, easyrsa_dir: str, pki_dir: str, cn: str,
key_passphrase: str, ca_passphrase: str, key_passphrase: str, ca_passphrase: str, email: str = "",
) -> None: ) -> None:
extra_env = {"EASYRSA_REQ_EMAIL": email} if email else None
_run_easyrsa( _run_easyrsa(
_base_cmd(easyrsa_dir, pki_dir, ca_passphrase) _base_cmd(easyrsa_dir, pki_dir, ca_passphrase)
+ [f"--passout=pass:{key_passphrase}", "build-client-full", cn], + [f"--passout=pass:{key_passphrase}", "build-client-full", cn],
cwd=easyrsa_dir, cwd=easyrsa_dir,
extra_env=extra_env,
) )
@@ -992,7 +999,8 @@ class CursesApp:
try: try:
build_client_full(EASYRSA_DIR, EASYRSA_PKI_DIR, build_client_full(EASYRSA_DIR, EASYRSA_PKI_DIR,
final_cn, form.password, CA_PASSPHRASE) final_cn, form.password, CA_PASSPHRASE,
email=form.email)
except EasyRSAError as exc: except EasyRSAError as exc:
if is_renewal: if is_renewal:
self._error( self._error(
@@ -1203,7 +1211,8 @@ class CliRunner:
print(f"Building certificate for {cn}", file=sys.stderr) print(f"Building certificate for {cn}", file=sys.stderr)
try: try:
build_client_full(EASYRSA_DIR, EASYRSA_PKI_DIR, cn, password, CA_PASSPHRASE) build_client_full(EASYRSA_DIR, EASYRSA_PKI_DIR, cn, password, CA_PASSPHRASE,
email=email_addr)
except EasyRSAError as exc: except EasyRSAError as exc:
if is_renewal: if is_renewal:
print( print(