From 24cae3de6a0f12d0fd845551f476bed804cec334 Mon Sep 17 00:00:00 2001 From: Vlad Doloman Date: Wed, 24 Jun 2026 23:12:31 +0300 Subject: [PATCH] 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 --- openvpncertupdate.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/openvpncertupdate.py b/openvpncertupdate.py index 500b0ce..6d98e9a 100644 --- a/openvpncertupdate.py +++ b/openvpncertupdate.py @@ -191,8 +191,13 @@ class EasyRSAError(Exception): pass -def _run_easyrsa(cmd: list[str], cwd: str) -> None: - result = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True) +def _run_easyrsa(cmd: list[str], cwd: str, + 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: # 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") @@ -219,12 +224,14 @@ def revoke_issued( def build_client_full( easyrsa_dir: str, pki_dir: str, cn: str, - key_passphrase: str, ca_passphrase: str, + key_passphrase: str, ca_passphrase: str, email: str = "", ) -> None: + extra_env = {"EASYRSA_REQ_EMAIL": email} if email else None _run_easyrsa( _base_cmd(easyrsa_dir, pki_dir, ca_passphrase) + [f"--passout=pass:{key_passphrase}", "build-client-full", cn], cwd=easyrsa_dir, + extra_env=extra_env, ) @@ -992,7 +999,8 @@ class CursesApp: try: 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: if is_renewal: self._error( @@ -1203,7 +1211,8 @@ class CliRunner: print(f"Building certificate for {cn}…", file=sys.stderr) 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: if is_renewal: print(