瀏覽代碼

fix: generate web panel certs per build and clean up mqtt env flags

Jared Dohrman 4 月之前
父節點
當前提交
ca63ea923a
共有 4 個文件被更改,包括 95 次插入14 次删除
  1. 1 0
      .gitignore
  2. 77 0
      arch/esp32/extra_scripts/generate_web_panel_cert.py
  3. 3 1
      platformio.ini
  4. 14 13
      src/helpers/mqtt/WebPanelCert.h

+ 1 - 0
.gitignore

@@ -17,3 +17,4 @@ compile_commands.json
 .venv/
 venv/
 platformio.local.ini
+src/helpers/mqtt/WebPanelCert.h

+ 77 - 0
arch/esp32/extra_scripts/generate_web_panel_cert.py

@@ -0,0 +1,77 @@
+Import("env")
+
+from pathlib import Path
+import subprocess
+import tempfile
+
+
+def render_pem_array(name, pem_text):
+    lines = []
+    for chunk in pem_text.splitlines(keepends=True):
+        escaped = chunk.replace("\\", "\\\\").replace('"', '\\"').replace("\n", "\\n")
+        lines.append(f'    "{escaped}"')
+    joined = "\n".join(lines) if lines else '    ""'
+    return f"static const char {name}[] =\n{joined};\n"
+
+
+project_dir = Path(env["PROJECT_DIR"])
+header_path = project_dir / "src/helpers/mqtt/WebPanelCert.h"
+
+if header_path.exists():
+    existing = header_path.read_text()
+    if "AUTO-GENERATED BY generate_web_panel_cert.py" in existing and "kServerKeyPem" in existing:
+        Return()
+
+with tempfile.TemporaryDirectory() as tmp:
+    tmp_path = Path(tmp)
+    key_path = tmp_path / "web-panel-key.pem"
+    cert_path = tmp_path / "web-panel-cert.pem"
+
+    try:
+        subprocess.run(
+            ["openssl", "ecparam", "-name", "prime256v1", "-genkey", "-noout", "-out", str(key_path)],
+            check=True,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE,
+            text=True,
+        )
+        subprocess.run(
+            [
+                "openssl",
+                "req",
+                "-new",
+                "-x509",
+                "-key",
+                str(key_path),
+                "-out",
+                str(cert_path),
+                "-days",
+                "3650",
+                "-subj",
+                "/CN=meshcore-local",
+            ],
+            check=True,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE,
+            text=True,
+        )
+    except FileNotFoundError as exc:
+        raise RuntimeError("openssl is required to generate the web panel certificate header") from exc
+    except subprocess.CalledProcessError as exc:
+        raise RuntimeError(
+            f"openssl failed while generating the web panel certificate header: {exc.stderr.strip()}"
+        ) from exc
+
+    cert_pem = cert_path.read_text()
+    key_pem = key_path.read_text()
+
+header_path.parent.mkdir(parents=True, exist_ok=True)
+header_path.write_text(
+    "#pragma once\n\n"
+    "// AUTO-GENERATED BY generate_web_panel_cert.py. DO NOT COMMIT.\n\n"
+    "namespace mqtt_web_panel_cert {\n\n"
+    f"{render_pem_array('kServerCertPem', cert_pem)}\n"
+    f"{render_pem_array('kServerKeyPem', key_pem)}"
+    "}\n",
+    encoding="utf-8",
+)

+ 3 - 1
platformio.ini

@@ -58,7 +58,9 @@ build_src_filter =
 extends = arduino_base
 platform = platformio/espressif32@6.11.0
 monitor_filters = esp32_exception_decoder
-extra_scripts = merge-bin.py
+extra_scripts =
+  pre:arch/esp32/extra_scripts/generate_web_panel_cert.py
+  merge-bin.py
 build_flags = ${arduino_base.build_flags}
   -D ESP32_PLATFORM
 ;  -D ESP32_CPU_FREQ=80          ; change it to your need

+ 14 - 13
src/helpers/mqtt/WebPanelCert.h

@@ -1,25 +1,26 @@
 #pragma once
 
+// AUTO-GENERATED BY generate_web_panel_cert.py. DO NOT COMMIT.
+
 namespace mqtt_web_panel_cert {
 
 static const char kServerCertPem[] =
     "-----BEGIN CERTIFICATE-----\n"
-    "MIIBiDCCAS2gAwIBAgIUYPagAbDjmNMHx+sqAC5qvOnlywIwCgYIKoZIzj0EAwIw\n"
-    "GTEXMBUGA1UEAwwObWVzaGNvcmUtbG9jYWwwHhcNMjYwNDA5MDE0MjAzWhcNMzYw\n"
-    "NDA2MDE0MjAzWjAZMRcwFQYDVQQDDA5tZXNoY29yZS1sb2NhbDBZMBMGByqGSM49\n"
-    "AgEGCCqGSM49AwEHA0IABJWLgQ/4sDJKykqR9a5brDLR9RikwoZ/6n1Od38rbfzV\n"
-    "ykP2LJIdrxU6zS1gzLk33klycB7AWFL1W7klStdiSpmjUzBRMB0GA1UdDgQWBBSk\n"
-    "dpP2r+UPriHT+hXLiyFdjkFgmTAfBgNVHSMEGDAWgBSkdpP2r+UPriHT+hXLiyFd\n"
-    "jkFgmTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQCWS5ZRbON4\n"
-    "71RrwcogEzGuQTNdkbtkRc+517nZ63ZOawIhAPwSy/0yMyhqAoOMpVnhIb+w995f\n"
-    "zH4nApL2Q2U0KI2l\n"
+    "MIIBiDCCAS2gAwIBAgIUFysjM9xosI98WhPpK1doyLOAkgYwCgYIKoZIzj0EAwIw\n"
+    "GTEXMBUGA1UEAwwObWVzaGNvcmUtbG9jYWwwHhcNMjYwNDA5MDUxODQ4WhcNMzYw\n"
+    "NDA2MDUxODQ4WjAZMRcwFQYDVQQDDA5tZXNoY29yZS1sb2NhbDBZMBMGByqGSM49\n"
+    "AgEGCCqGSM49AwEHA0IABBpVegwc/kZDjVtHXnl0iYbD2vdes7nLztlyRDylcfOD\n"
+    "GoR9hopoc9NernvGJLUFP/+PsjIsfEGmVrmPESnShsWjUzBRMB0GA1UdDgQWBBTi\n"
+    "oWH5V8BvTj9Kla8ki8SHb2vdSTAfBgNVHSMEGDAWgBTioWH5V8BvTj9Kla8ki8SH\n"
+    "b2vdSTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQDjNde/RApq\n"
+    "jx/FYar9+qMMxHeBMrSiOBozTFpcmFr7RgIhAMdVESr6P2urGsxzbYirwURj5H1F\n"
+    "8eej1APpWRRZvvP0\n"
     "-----END CERTIFICATE-----\n";
 
 static const char kServerKeyPem[] =
     "-----BEGIN EC PRIVATE KEY-----\n"
-    "MHcCAQEEIGX71nLSiA8qUJXuiZRNzaGizNbMqgOxALSPd/HzfzWAoAoGCCqGSM49\n"
-    "AwEHoUQDQgAElYuBD/iwMkrKSpH1rlusMtH1GKTChn/qfU53fytt/NXKQ/Yskh2v\n"
-    "FTrNLWDMuTfeSXJwHsBYUvVbuSVK12JKmQ==\n"
+    "MHcCAQEEIPQxD+WYeE2tQja5AVrOgDUHAKJ7TYfELqU55Npb7mJ1oAoGCCqGSM49\n"
+    "AwEHoUQDQgAEGlV6DBz+RkONW0deeXSJhsPa916zucvO2XJEPKVx84MahH2Gimhz\n"
+    "016ue8YktQU//4+yMix8QaZWuY8RKdKGxQ==\n"
     "-----END EC PRIVATE KEY-----\n";
-
 }