@voxgig/sdkgen 4.10.0 → 4.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/voxgig-sdkgen +1 -1
- package/package.json +1 -1
- package/project/.sdk/model/feature/secrets.aon +330 -0
- package/project/.sdk/model/target/c.aon +15 -2
- package/project/.sdk/model/target/cpp.aon +18 -0
- package/project/.sdk/model/target/lua.aon +17 -0
- package/project/.sdk/model/target/ocaml.aon +48 -5
- package/project/.sdk/model/target/zig.aon +30 -4
- package/project/.sdk/src/cmp/c/Config_c.ts +338 -1
- package/project/.sdk/src/cmp/c/Main_c.ts +57 -2
- package/project/.sdk/src/cmp/c/Package_c.ts +12 -2
- package/project/.sdk/src/cmp/cpp/Config_cpp.ts +324 -2
- package/project/.sdk/src/cmp/cpp/Gitignore_cpp.ts +2 -0
- package/project/.sdk/src/cmp/cpp/Main_cpp.ts +62 -4
- package/project/.sdk/src/cmp/cpp/Package_cpp.ts +10 -0
- package/project/.sdk/src/cmp/lua/Config_lua.ts +88 -0
- package/project/.sdk/src/cmp/lua/Gitignore_lua.ts +4 -0
- package/project/.sdk/src/cmp/lua/Main_lua.ts +93 -3
- package/project/.sdk/src/cmp/lua/Package_lua.ts +60 -0
- package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +10 -0
- package/project/.sdk/src/cmp/ocaml/Config_ocaml.ts +183 -5
- package/project/.sdk/src/cmp/ocaml/Main_ocaml.ts +160 -3
- package/project/.sdk/src/cmp/ocaml/Package_ocaml.ts +25 -1
- package/project/.sdk/src/cmp/zig/Config_zig.ts +130 -9
- package/project/.sdk/src/cmp/zig/Main_zig.ts +208 -4
- package/project/.sdk/{tm/zig/build.zig → src/cmp/zig/fragment/Build.fragment.zig} +7 -0
- package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +25 -0
- package/project/.sdk/{tm/zig/root.zig → src/cmp/zig/fragment/Root.fragment.zig} +9 -0
- package/project/.sdk/tm/c/Makefile +58 -9
- package/project/.sdk/tm/c/core/sdk.h +10 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/capability.c +133 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/capability.h +39 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/catalog.c +83 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/catalog.h +48 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/config.c +413 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/config.h +24 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/depend.c +264 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/depend.h +29 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/env.c +220 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/env.h +19 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/export.c +97 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/export.h +19 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/graph.c +237 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/graph.h +17 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/host.c +1494 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/host.h +135 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/order.c +288 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/order.h +18 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/point.c +141 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/point.h +80 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/ref.c +170 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/ref.h +52 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/resolve.c +98 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/resolve.h +18 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/types.c +150 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/types.h +104 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/value.c +649 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/value.h +135 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/version.c +151 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/version.h +34 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/aws.c +281 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/azuresecrets.c +207 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/boru.c +164 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/clock.c +75 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/doppler.c +141 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/encode.c +144 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/gcpsecrets.c +177 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/hashicorp.c +239 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/httpjson.c +599 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/infisical.c +165 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/onepassword.c +194 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/proc.c +233 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/secretspec.c +125 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/sekretoplugins.h +125 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/sha256.c +270 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/sigv4.c +382 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/support.h +153 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/tls.c +420 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/internal.h +86 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/json.c +721 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/providers.c +813 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/sekreto.c +944 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/sekreto.h +490 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/util.c +442 -0
- package/project/.sdk/tm/c/feature/secrets.c +797 -0
- package/project/.sdk/tm/c/feature/secrets.h +46 -0
- package/project/.sdk/tm/c/src/feature/secrets/.gitkeep +0 -0
- package/project/.sdk/tm/c/tests/feature/secrets/secrets_test.c +802 -0
- package/project/.sdk/tm/clojure/feature/secrets/sdk/feature/secrets.clj +38 -11
- package/project/.sdk/tm/clojure/test/sdk/test/feature/secrets.clj +40 -6
- package/project/.sdk/tm/cpp/Makefile +48 -4
- package/project/.sdk/tm/cpp/feature/secrets/plugin/capability.cpp +121 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/capability.hpp +41 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/catalog.cpp +60 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/catalog.hpp +66 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/config.cpp +376 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/config.hpp +29 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/depend.cpp +230 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/depend.hpp +31 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/env.cpp +205 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/env.hpp +25 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/export.cpp +84 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/export.hpp +24 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/graph.cpp +222 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/graph.hpp +21 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/host.cpp +1200 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/host.hpp +250 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/order.cpp +250 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/order.hpp +22 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/point.cpp +110 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/point.hpp +79 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/ref.cpp +136 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/ref.hpp +60 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/resolve.cpp +82 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/resolve.hpp +25 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/types.cpp +90 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/types.hpp +65 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/value.cpp +491 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/value.hpp +120 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/version.cpp +143 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/version.hpp +36 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Aws.cpp +248 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Aws.hpp +30 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Azuresecrets.cpp +149 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Azuresecrets.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Boru.cpp +117 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Boru.hpp +27 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Crypto.cpp +180 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Crypto.hpp +52 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Doppler.cpp +87 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Doppler.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Gcpsecrets.cpp +121 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Gcpsecrets.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Hashicorp.cpp +153 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Hashicorp.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Httpjson.cpp +666 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Httpjson.hpp +160 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Infisical.cpp +123 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Infisical.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Onepassword.cpp +125 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Onepassword.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Proc.cpp +223 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Proc.hpp +47 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Secretspec.cpp +104 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Secretspec.hpp +27 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Sigv4.cpp +242 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Sigv4.hpp +58 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Tls.cpp +260 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Tls.hpp +47 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Json.cpp +476 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Json.hpp +89 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Provider.cpp +312 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Provider.hpp +263 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Providers.cpp +354 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Providers.hpp +111 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Sekreto.cpp +613 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Sekreto.hpp +227 -0
- package/project/.sdk/tm/cpp/feature/secrets.hpp +745 -0
- package/project/.sdk/tm/cpp/src/feature/secrets/.gitkeep +0 -0
- package/project/.sdk/tm/cpp/test/feature/secrets/secrets_test.cpp +808 -0
- package/project/.sdk/tm/csharp/feature/SecretsFeature.cs +34 -8
- package/project/.sdk/tm/csharp/test/feature/secrets/SecretsFeatureTest.cs +85 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets.ex +17 -2
- package/project/.sdk/tm/elixir/test/feature/secrets/secrets_test.exs +41 -0
- package/project/.sdk/tm/go/feature/secrets_feature.go +32 -10
- package/project/.sdk/tm/go/test/feature/secrets/secrets_feature_test.go +116 -0
- package/project/.sdk/tm/java/feature/SecretsFeature.java +33 -8
- package/project/.sdk/tm/java/test/feature/secrets/SecretsFeatureTest.java +64 -0
- package/project/.sdk/tm/js/src/feature/secrets/SecretsFeature.js +34 -11
- package/project/.sdk/tm/js/test/feature/secrets/Secrets.test.js +73 -0
- package/project/.sdk/tm/kotlin/feature/SecretsFeature.kt +32 -7
- package/project/.sdk/tm/kotlin/test/feature/secrets/SecretsTest.kt +69 -0
- package/project/.sdk/tm/lua/Makefile +15 -4
- package/project/.sdk/tm/lua/feature/secrets/native/sekretonet.c +806 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/capability.lua +135 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/catalog.lua +63 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/config.lua +361 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/depend.lua +232 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/env.lua +168 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/export.lua +66 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/graph.lua +194 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/host.lua +1190 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/json.lua +169 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/order.lua +207 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/point.lua +106 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/ref.lua +115 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/resolve.lua +78 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/types.lua +275 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/version.lua +131 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin.lua +76 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/addr.lua +124 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/err.lua +47 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/name.lua +315 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/aws.lua +228 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/azuresecrets.lua +137 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/boru.lua +124 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/crypto.lua +212 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/doppler.lua +89 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/gcpsecrets.lua +129 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/hashicorp.lua +154 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/httpjson.lua +248 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/infisical.lua +113 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/json.lua +449 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/net.lua +198 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/onepassword.lua +126 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/secretspec.lua +93 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/sigv4.lua +269 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/support.lua +146 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/providers.lua +346 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto.lua +479 -0
- package/project/.sdk/tm/lua/feature/secrets_feature.lua +690 -0
- package/project/.sdk/tm/lua/src/feature/secrets/.gitkeep +0 -0
- package/project/.sdk/tm/lua/test/extend_test.lua +105 -0
- package/project/.sdk/tm/lua/test/feature/secrets/secrets_feature_test.lua +862 -0
- package/project/.sdk/tm/ocaml/Makefile +52 -8
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/capability.ml +106 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/catalog.ml +43 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/config.ml +349 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/defs.ml +143 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/depend.ml +217 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/env.ml +197 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/export.ml +89 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/graph.ml +227 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/host.ml +1112 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/order.ml +202 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/point.ml +138 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/ref.ml +126 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/resolve.ml +62 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/types.ml +97 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/value.ml +387 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/version.ml +139 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/aws.ml +171 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/azuresecrets.ml +116 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/boru.ml +95 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/crypto.ml +149 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/doppler.ml +61 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/gcpsecrets.ml +93 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/hashicorp.ml +120 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/http.ml +421 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/httpjson.ml +66 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/infisical.ml +85 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/onepassword.ml +112 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/runcmd.ml +97 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/secretspec.ml +68 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/sigv4.ml +259 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/tls.ml +44 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/tls_stubs.c +358 -0
- package/project/.sdk/tm/ocaml/feature/secrets/sekreto/json.ml +376 -0
- package/project/.sdk/tm/ocaml/feature/secrets/sekreto/provider.ml +647 -0
- package/project/.sdk/tm/ocaml/feature/secrets/sekreto/secret.ml +299 -0
- package/project/.sdk/tm/ocaml/feature/secrets/sekreto/sekreto.ml +347 -0
- package/project/.sdk/tm/ocaml/feature/secrets_feature.ml +453 -0
- package/project/.sdk/tm/ocaml/src/feature/secrets/.gitkeep +0 -0
- package/project/.sdk/tm/ocaml/test/feature/secrets/t_secrets.ml +670 -0
- package/project/.sdk/tm/perl/feature/secrets_feature.pm +33 -12
- package/project/.sdk/tm/perl/t/feature/secrets/secrets.t +47 -0
- package/project/.sdk/tm/php/feature/SecretsFeature.php +30 -6
- package/project/.sdk/tm/php/test/feature/secrets/SecretsTest.php +98 -0
- package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +28 -6
- package/project/.sdk/tm/py/test/feature/secrets/test_secrets.py +114 -0
- package/project/.sdk/tm/rb/feature/secrets_feature.rb +28 -6
- package/project/.sdk/tm/rb/test/feature/secrets/secrets_feature_test.rb +93 -0
- package/project/.sdk/tm/rust/feature/secrets.rs +33 -10
- package/project/.sdk/tm/rust/tests/feature/secrets/main.rs +96 -0
- package/project/.sdk/tm/scala/feature/SecretsFeature.scala +29 -7
- package/project/.sdk/tm/scala/sdktest/feature/secrets/SecretsTestMain.scala +71 -0
- package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +35 -12
- package/project/.sdk/tm/ts/test/feature/secrets/Secrets.test.ts +73 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/capability.zig +137 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/catalog.zig +90 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/config.zig +346 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/depend.zig +244 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/env.zig +201 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/export.zig +83 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/graph.zig +212 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/host.zig +1224 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/inst.zig +126 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/order.zig +228 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/plugin.zig +34 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/point.zig +166 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/ref.zig +147 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/resolve.zig +74 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/types.zig +140 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/value.zig +662 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/version.zig +139 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/aws.zig +294 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/azuresecrets.zig +222 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/boru.zig +188 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/doppler.zig +135 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/gcpsecrets.zig +170 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/hashicorp.zig +242 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/httpjson.zig +535 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/infisical.zig +167 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/onepassword.zig +202 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/secretspec.zig +160 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/sigv4.zig +336 -0
- package/project/.sdk/tm/zig/feature/secrets/sekreto/addr.zig +148 -0
- package/project/.sdk/tm/zig/feature/secrets/sekreto/builtins.zig +259 -0
- package/project/.sdk/tm/zig/feature/secrets/sekreto/provider.zig +440 -0
- package/project/.sdk/tm/zig/feature/secrets/sekreto/sekreto.zig +944 -0
- package/project/.sdk/tm/zig/feature/secrets.zig +854 -0
- package/project/.sdk/tm/zig/src/feature/secrets/.gitkeep +0 -0
- package/project/.sdk/tm/zig/test/feature/secrets/secrets_test.zig +891 -0
- package/project/sdkgen-package.json +1 -1
|
@@ -0,0 +1,806 @@
|
|
|
1
|
+
-- VENDORED: @voxgig/sekreto sdk-20260908-1556-0 (lua/native/sekretonet.c)
|
|
2
|
+
-- Source: https://github.com/voxgig/sekreto @ 1267ee2e5f49566bc92695bc9eb3a60ef4924998 [tag: sdk-20260908-1556-0]
|
|
3
|
+
-- License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
|
|
4
|
+
/*
|
|
5
|
+
* sekreto-net: the transport this port does not have.
|
|
6
|
+
*
|
|
7
|
+
* Lua 5.4's whole standard library is basic, coroutine, package, string,
|
|
8
|
+
* utf8, table, math, io, os and debug. There are no sockets of any kind,
|
|
9
|
+
* no TLS, and `io.popen` is unidirectional and goes through a shell. So
|
|
10
|
+
* the two things a Lua program cannot do for itself are done here, in one
|
|
11
|
+
* file, compiled by lua/Makefile:
|
|
12
|
+
*
|
|
13
|
+
* fetch connect a TCP socket (optionally TLS), write the bytes the
|
|
14
|
+
* caller framed, read the bytes back
|
|
15
|
+
* exec run a child with an argv ARRAY (never a shell), stdin closed,
|
|
16
|
+
* stdout and stderr drained concurrently
|
|
17
|
+
*
|
|
18
|
+
* What is NOT here, deliberately: HTTP. The request line, the headers,
|
|
19
|
+
* chunked decoding and the 8 MiB cap are all framed in Lua
|
|
20
|
+
* (src/sekreto/http.lua). This program moves bytes. That keeps the
|
|
21
|
+
* dependency exactly as narrow as AGENTS.md rule 3 allows -
|
|
22
|
+
* cryptographic transport, and nothing else. In particular SHA-256 and
|
|
23
|
+
* HMAC are NOT taken from libcrypto: they are hand-rolled in
|
|
24
|
+
* src/sekreto/crypto.lua, the same decision the rust port took with
|
|
25
|
+
* `ring` already inside rustls's closure.
|
|
26
|
+
*
|
|
27
|
+
* Audit surface: `-lssl -lcrypto`, and the distribution's OpenSSL is the
|
|
28
|
+
* audit surface. Nothing else is linked beyond libc.
|
|
29
|
+
*
|
|
30
|
+
* The four obligations of a TLS binding, all of them met below, because a
|
|
31
|
+
* binding that connects without verifying is worse than no TLS:
|
|
32
|
+
*
|
|
33
|
+
* 1. chain SSL_CTX_set_default_verify_paths + SSL_VERIFY_PEER, and
|
|
34
|
+
* SSL_get_verify_result checked afterwards
|
|
35
|
+
* 2. hostname SSL_set1_host for a DNS name, and
|
|
36
|
+
* X509_VERIFY_PARAM_set1_ip_asc for an IP literal - which
|
|
37
|
+
* is a different call, and the half people forget
|
|
38
|
+
* 3. SNI SSL_set_tlsext_host_name, and NOT for an IP literal
|
|
39
|
+
* (RFC 6066 forbids it)
|
|
40
|
+
* 4. roots SEKRETO_CA_BUNDLE, loaded IN ADDITION to the system
|
|
41
|
+
* store, failing open and silently
|
|
42
|
+
*
|
|
43
|
+
* Invocation: sekreto-net <requestfile>
|
|
44
|
+
*
|
|
45
|
+
* The request arrives in a file rather than on the command line because
|
|
46
|
+
* a vault token rides in the headers and the process table is world
|
|
47
|
+
* readable. The caller creates it 0600; this program unlinks it before
|
|
48
|
+
* reading a byte of it.
|
|
49
|
+
*
|
|
50
|
+
* Wire format, in and out, is length-prefixed and binary safe:
|
|
51
|
+
*
|
|
52
|
+
* request <name> <len>\n<len bytes>\n repeated
|
|
53
|
+
* answer OK <len>\n<len bytes>
|
|
54
|
+
* ERR <len>\n<len bytes>
|
|
55
|
+
* EXEC <status> <outlen> <errlen>\n<out><err>
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
#define _GNU_SOURCE
|
|
59
|
+
|
|
60
|
+
#include <arpa/inet.h>
|
|
61
|
+
#include <errno.h>
|
|
62
|
+
#include <netdb.h>
|
|
63
|
+
#include <poll.h>
|
|
64
|
+
#include <signal.h>
|
|
65
|
+
#include <stdio.h>
|
|
66
|
+
#include <stdlib.h>
|
|
67
|
+
#include <string.h>
|
|
68
|
+
#include <sys/socket.h>
|
|
69
|
+
#include <sys/time.h>
|
|
70
|
+
#include <sys/types.h>
|
|
71
|
+
#include <sys/wait.h>
|
|
72
|
+
#include <unistd.h>
|
|
73
|
+
#include <fcntl.h>
|
|
74
|
+
|
|
75
|
+
#include <openssl/err.h>
|
|
76
|
+
#include <openssl/ssl.h>
|
|
77
|
+
#include <openssl/x509v3.h>
|
|
78
|
+
|
|
79
|
+
#define MAXFIELD (16 * 1024 * 1024)
|
|
80
|
+
|
|
81
|
+
/* ------------------------------------------------------------ buffers */
|
|
82
|
+
|
|
83
|
+
typedef struct {
|
|
84
|
+
char *data;
|
|
85
|
+
size_t len;
|
|
86
|
+
size_t cap;
|
|
87
|
+
} buf;
|
|
88
|
+
|
|
89
|
+
static void bufinit(buf *b) {
|
|
90
|
+
b->data = NULL;
|
|
91
|
+
b->len = 0;
|
|
92
|
+
b->cap = 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
static int bufput(buf *b, const char *bytes, size_t n) {
|
|
96
|
+
if (b->len + n > b->cap) {
|
|
97
|
+
size_t want = b->cap ? b->cap : 4096;
|
|
98
|
+
char *grown;
|
|
99
|
+
while (want < b->len + n) {
|
|
100
|
+
want *= 2;
|
|
101
|
+
}
|
|
102
|
+
grown = realloc(b->data, want);
|
|
103
|
+
if (NULL == grown) {
|
|
104
|
+
return 0;
|
|
105
|
+
}
|
|
106
|
+
b->data = grown;
|
|
107
|
+
b->cap = want;
|
|
108
|
+
}
|
|
109
|
+
memcpy(b->data + b->len, bytes, n);
|
|
110
|
+
b->len += n;
|
|
111
|
+
return 1;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
static void buffree(buf *b) {
|
|
115
|
+
free(b->data);
|
|
116
|
+
bufinit(b);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* ------------------------------------------------------------ answers */
|
|
120
|
+
|
|
121
|
+
static void writeall(int fd, const char *bytes, size_t n) {
|
|
122
|
+
size_t at = 0;
|
|
123
|
+
while (at < n) {
|
|
124
|
+
ssize_t wrote = write(fd, bytes + at, n - at);
|
|
125
|
+
if (0 >= wrote) {
|
|
126
|
+
if (EINTR == errno) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
at += (size_t)wrote;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* A transport failure. The caller turns this into
|
|
136
|
+
* `sekreto: cannot reach <url>: <message>`. */
|
|
137
|
+
static void answererr(const char *message) {
|
|
138
|
+
char head[64];
|
|
139
|
+
int n = snprintf(head, sizeof head, "ERR %zu\n", strlen(message));
|
|
140
|
+
writeall(1, head, (size_t)n);
|
|
141
|
+
writeall(1, message, strlen(message));
|
|
142
|
+
exit(0);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
static void answerok(const char *bytes, size_t n) {
|
|
146
|
+
char head[64];
|
|
147
|
+
int head_n = snprintf(head, sizeof head, "OK %zu\n", n);
|
|
148
|
+
writeall(1, head, (size_t)head_n);
|
|
149
|
+
writeall(1, bytes, n);
|
|
150
|
+
exit(0);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/* The newest OpenSSL diagnostic, so a verification failure says which. */
|
|
154
|
+
static void answersslerr(const char *what) {
|
|
155
|
+
char message[512];
|
|
156
|
+
unsigned long code = ERR_peek_last_error();
|
|
157
|
+
|
|
158
|
+
if (0 == code) {
|
|
159
|
+
snprintf(message, sizeof message, "%s", what);
|
|
160
|
+
} else {
|
|
161
|
+
char detail[256];
|
|
162
|
+
ERR_error_string_n(code, detail, sizeof detail);
|
|
163
|
+
snprintf(message, sizeof message, "%s: %s", what, detail);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
answererr(message);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/* ------------------------------------------------------ request fields */
|
|
170
|
+
|
|
171
|
+
typedef struct {
|
|
172
|
+
char *name;
|
|
173
|
+
char *value;
|
|
174
|
+
size_t len;
|
|
175
|
+
} field;
|
|
176
|
+
|
|
177
|
+
static field *FIELDS = NULL;
|
|
178
|
+
static size_t NFIELDS = 0;
|
|
179
|
+
|
|
180
|
+
static const char *fieldof(const char *name, const char *fallback) {
|
|
181
|
+
size_t index;
|
|
182
|
+
for (index = 0; index < NFIELDS; index++) {
|
|
183
|
+
if (0 == strcmp(FIELDS[index].name, name)) {
|
|
184
|
+
return FIELDS[index].value;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return fallback;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
static long numberof(const char *name, long fallback) {
|
|
191
|
+
const char *text = fieldof(name, NULL);
|
|
192
|
+
if (NULL == text) {
|
|
193
|
+
return fallback;
|
|
194
|
+
}
|
|
195
|
+
return strtol(text, NULL, 10);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* Read the whole request file, then unlink it. */
|
|
199
|
+
static void readrequest(const char *path) {
|
|
200
|
+
FILE *handle = fopen(path, "rb");
|
|
201
|
+
buf whole;
|
|
202
|
+
size_t at;
|
|
203
|
+
|
|
204
|
+
if (NULL == handle) {
|
|
205
|
+
answererr("cannot read the transport request");
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/* Unlinked immediately: the file carries the vault token. */
|
|
209
|
+
unlink(path);
|
|
210
|
+
|
|
211
|
+
bufinit(&whole);
|
|
212
|
+
|
|
213
|
+
for (;;) {
|
|
214
|
+
char chunk[65536];
|
|
215
|
+
size_t got = fread(chunk, 1, sizeof chunk, handle);
|
|
216
|
+
if (0 == got) {
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
if (!bufput(&whole, chunk, got)) {
|
|
220
|
+
answererr("out of memory reading the transport request");
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
fclose(handle);
|
|
224
|
+
|
|
225
|
+
/* Two NUL bytes past the end, not counted, so that the terminator
|
|
226
|
+
* written over each payload's trailing newline is always in bounds. */
|
|
227
|
+
if (!bufput(&whole, "\0\0", 2)) {
|
|
228
|
+
answererr("out of memory reading the transport request");
|
|
229
|
+
}
|
|
230
|
+
whole.len -= 2;
|
|
231
|
+
|
|
232
|
+
at = 0;
|
|
233
|
+
while (at < whole.len) {
|
|
234
|
+
char *head = whole.data + at;
|
|
235
|
+
char *nl = memchr(head, '\n', whole.len - at);
|
|
236
|
+
char *space;
|
|
237
|
+
long len;
|
|
238
|
+
field *grown;
|
|
239
|
+
|
|
240
|
+
if (NULL == nl) {
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
*nl = '\0';
|
|
245
|
+
space = strchr(head, ' ');
|
|
246
|
+
if (NULL == space) {
|
|
247
|
+
answererr("malformed transport request");
|
|
248
|
+
}
|
|
249
|
+
*space = '\0';
|
|
250
|
+
|
|
251
|
+
len = strtol(space + 1, NULL, 10);
|
|
252
|
+
if (0 > len || MAXFIELD < len) {
|
|
253
|
+
answererr("malformed transport request");
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
at = (size_t)(nl - whole.data) + 1;
|
|
257
|
+
if (at + (size_t)len > whole.len) {
|
|
258
|
+
answererr("truncated transport request");
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
grown = realloc(FIELDS, (NFIELDS + 1) * sizeof(field));
|
|
262
|
+
if (NULL == grown) {
|
|
263
|
+
answererr("out of memory reading the transport request");
|
|
264
|
+
}
|
|
265
|
+
FIELDS = grown;
|
|
266
|
+
FIELDS[NFIELDS].name = head;
|
|
267
|
+
FIELDS[NFIELDS].value = whole.data + at;
|
|
268
|
+
FIELDS[NFIELDS].len = (size_t)len;
|
|
269
|
+
NFIELDS++;
|
|
270
|
+
|
|
271
|
+
at += (size_t)len;
|
|
272
|
+
/* Skip the newline that terminates the payload. */
|
|
273
|
+
if (at < whole.len && '\n' == whole.data[at]) {
|
|
274
|
+
at++;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/* Every value is NUL-terminated for the string fields; the payload
|
|
279
|
+
* fields are used with their explicit length. */
|
|
280
|
+
for (at = 0; at < NFIELDS; at++) {
|
|
281
|
+
FIELDS[at].value[FIELDS[at].len] = '\0';
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/* ---------------------------------------------------------- the clock */
|
|
286
|
+
|
|
287
|
+
static long nowms(void) {
|
|
288
|
+
struct timeval tv;
|
|
289
|
+
gettimeofday(&tv, NULL);
|
|
290
|
+
return (long)tv.tv_sec * 1000L + (long)(tv.tv_usec / 1000);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/* ------------------------------------------------------------ connect */
|
|
294
|
+
|
|
295
|
+
/*
|
|
296
|
+
* One deadline across ALL resolved addresses, not one per address.
|
|
297
|
+
* Giving each the full ten seconds makes the real bound ten seconds
|
|
298
|
+
* times however many addresses the name cares to return - which is not a
|
|
299
|
+
* bound at all when the name is the attacker's.
|
|
300
|
+
*/
|
|
301
|
+
static int dial(const char *host, const char *port, long deadline) {
|
|
302
|
+
struct addrinfo hints;
|
|
303
|
+
struct addrinfo *list = NULL;
|
|
304
|
+
struct addrinfo *entry;
|
|
305
|
+
int sock = -1;
|
|
306
|
+
|
|
307
|
+
memset(&hints, 0, sizeof hints);
|
|
308
|
+
hints.ai_family = AF_UNSPEC;
|
|
309
|
+
hints.ai_socktype = SOCK_STREAM;
|
|
310
|
+
|
|
311
|
+
if (0 != getaddrinfo(host, port, &hints, &list)) {
|
|
312
|
+
answererr("cannot resolve host");
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
for (entry = list; NULL != entry; entry = entry->ai_next) {
|
|
316
|
+
int flags;
|
|
317
|
+
int result;
|
|
318
|
+
|
|
319
|
+
if (0 >= deadline - nowms()) {
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
sock = socket(entry->ai_family, entry->ai_socktype, entry->ai_protocol);
|
|
324
|
+
if (0 > sock) {
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
flags = fcntl(sock, F_GETFL, 0);
|
|
329
|
+
fcntl(sock, F_SETFL, flags | O_NONBLOCK);
|
|
330
|
+
|
|
331
|
+
result = connect(sock, entry->ai_addr, entry->ai_addrlen);
|
|
332
|
+
|
|
333
|
+
if (0 != result && EINPROGRESS == errno) {
|
|
334
|
+
struct pollfd waiting;
|
|
335
|
+
long left = deadline - nowms();
|
|
336
|
+
|
|
337
|
+
waiting.fd = sock;
|
|
338
|
+
waiting.events = POLLOUT;
|
|
339
|
+
waiting.revents = 0;
|
|
340
|
+
|
|
341
|
+
if (0 < left && 0 < poll(&waiting, 1, (int)left)) {
|
|
342
|
+
int soerr = 0;
|
|
343
|
+
socklen_t soerrlen = sizeof soerr;
|
|
344
|
+
if (0 == getsockopt(sock, SOL_SOCKET, SO_ERROR, &soerr, &soerrlen) &&
|
|
345
|
+
0 == soerr) {
|
|
346
|
+
result = 0;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (0 == result) {
|
|
352
|
+
fcntl(sock, F_SETFL, flags);
|
|
353
|
+
freeaddrinfo(list);
|
|
354
|
+
return sock;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
close(sock);
|
|
358
|
+
sock = -1;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
freeaddrinfo(list);
|
|
362
|
+
answererr("connection refused or timed out");
|
|
363
|
+
return -1;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/* Is this host an IP literal rather than a DNS name? Hostname
|
|
367
|
+
* verification and SNI both branch on the answer. */
|
|
368
|
+
static int isipliteral(const char *host) {
|
|
369
|
+
unsigned char scratch[16];
|
|
370
|
+
|
|
371
|
+
if (1 == inet_pton(AF_INET, host, scratch)) {
|
|
372
|
+
return 1;
|
|
373
|
+
}
|
|
374
|
+
if (1 == inet_pton(AF_INET6, host, scratch)) {
|
|
375
|
+
return 1;
|
|
376
|
+
}
|
|
377
|
+
return 0;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/* ------------------------------------------------------------- fetch */
|
|
381
|
+
|
|
382
|
+
static void dofetch(void) {
|
|
383
|
+
const char *host = fieldof("host", "");
|
|
384
|
+
const char *port = fieldof("port", "443");
|
|
385
|
+
const char *body = fieldof("data", "");
|
|
386
|
+
size_t bodylen = 0;
|
|
387
|
+
long usetls = numberof("tls", 0);
|
|
388
|
+
long timeout = numberof("timeout", 10000);
|
|
389
|
+
long maxbody = numberof("maxbody", 8 * 1024 * 1024);
|
|
390
|
+
long deadline = nowms() + timeout;
|
|
391
|
+
int sock;
|
|
392
|
+
buf answer;
|
|
393
|
+
size_t at;
|
|
394
|
+
SSL_CTX *ctx = NULL;
|
|
395
|
+
SSL *ssl = NULL;
|
|
396
|
+
|
|
397
|
+
{
|
|
398
|
+
size_t index;
|
|
399
|
+
for (index = 0; index < NFIELDS; index++) {
|
|
400
|
+
if (0 == strcmp(FIELDS[index].name, "data")) {
|
|
401
|
+
bodylen = FIELDS[index].len;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
sock = dial(host, port, deadline);
|
|
407
|
+
|
|
408
|
+
if (usetls) {
|
|
409
|
+
const char *bundle = getenv("SEKRETO_CA_BUNDLE");
|
|
410
|
+
X509_VERIFY_PARAM *param;
|
|
411
|
+
X509 *peer;
|
|
412
|
+
|
|
413
|
+
ctx = SSL_CTX_new(TLS_client_method());
|
|
414
|
+
if (NULL == ctx) {
|
|
415
|
+
answererr("cannot create a TLS context");
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/* (1) Chain verification against the system trust store. The NULL
|
|
419
|
+
* callback is what makes a verification error abort the handshake
|
|
420
|
+
* rather than be reported and ignored. */
|
|
421
|
+
if (1 != SSL_CTX_set_default_verify_paths(ctx)) {
|
|
422
|
+
answersslerr("cannot load the system trust store");
|
|
423
|
+
}
|
|
424
|
+
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
|
|
425
|
+
SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
|
|
426
|
+
|
|
427
|
+
/* (4) SEKRETO_CA_BUNDLE, ADDITIVE: the default roots are already
|
|
428
|
+
* loaded above and stay loaded. A private CA is how most internal
|
|
429
|
+
* Vault deployments are set up, so a wrong path weakens nothing - it
|
|
430
|
+
* adds no roots and raises nothing. */
|
|
431
|
+
if (NULL != bundle && '\0' != bundle[0]) {
|
|
432
|
+
if (1 != SSL_CTX_load_verify_locations(ctx, bundle, NULL)) {
|
|
433
|
+
ERR_clear_error();
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
ssl = SSL_new(ctx);
|
|
438
|
+
if (NULL == ssl) {
|
|
439
|
+
answererr("cannot create a TLS connection");
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
param = SSL_get0_param(ssl);
|
|
443
|
+
X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
|
|
444
|
+
|
|
445
|
+
/* (2) Hostname verification - a SEPARATE step from the chain, and a
|
|
446
|
+
* different call for an IP literal. SSL_set1_host does DNS-name
|
|
447
|
+
* matching and will NOT match an iPAddress SAN, so an address like
|
|
448
|
+
* https://127.0.0.1:8304 needs set1_ip_asc or it is not checked at
|
|
449
|
+
* all. */
|
|
450
|
+
if (isipliteral(host)) {
|
|
451
|
+
if (1 != X509_VERIFY_PARAM_set1_ip_asc(param, host)) {
|
|
452
|
+
answererr("cannot pin the peer address");
|
|
453
|
+
}
|
|
454
|
+
} else {
|
|
455
|
+
if (1 != SSL_set1_host(ssl, host)) {
|
|
456
|
+
answererr("cannot pin the peer hostname");
|
|
457
|
+
}
|
|
458
|
+
/* (3) SNI, for a name only: RFC 6066 forbids an IP literal here,
|
|
459
|
+
* and OpenSSL will send whatever it is handed. */
|
|
460
|
+
SSL_set_tlsext_host_name(ssl, host);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
SSL_set_fd(ssl, sock);
|
|
464
|
+
|
|
465
|
+
if (1 != SSL_connect(ssl)) {
|
|
466
|
+
answersslerr("TLS handshake failed");
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/* Belt and braces. SSL_VERIFY_PEER already aborts on a bad chain, but
|
|
470
|
+
* a build or a callback that did not is worse than no TLS, so the
|
|
471
|
+
* result is read back explicitly. */
|
|
472
|
+
if (X509_V_OK != SSL_get_verify_result(ssl)) {
|
|
473
|
+
answererr("TLS certificate verification failed");
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
peer = SSL_get1_peer_certificate(ssl);
|
|
477
|
+
if (NULL == peer) {
|
|
478
|
+
answererr("TLS peer sent no certificate");
|
|
479
|
+
}
|
|
480
|
+
X509_free(peer);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/* Write the framed request. */
|
|
484
|
+
at = 0;
|
|
485
|
+
while (at < bodylen) {
|
|
486
|
+
int wrote;
|
|
487
|
+
if (0 >= deadline - nowms()) {
|
|
488
|
+
answererr("timed out sending the request");
|
|
489
|
+
}
|
|
490
|
+
if (usetls) {
|
|
491
|
+
wrote = SSL_write(ssl, body + at, (int)(bodylen - at));
|
|
492
|
+
} else {
|
|
493
|
+
wrote = (int)write(sock, body + at, bodylen - at);
|
|
494
|
+
}
|
|
495
|
+
if (0 >= wrote) {
|
|
496
|
+
if (!usetls && EINTR == errno) {
|
|
497
|
+
continue;
|
|
498
|
+
}
|
|
499
|
+
answererr("connection lost while sending the request");
|
|
500
|
+
}
|
|
501
|
+
at += (size_t)wrote;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
if (!usetls) {
|
|
505
|
+
shutdown(sock, SHUT_WR);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/* Read to EOF. The request always carries `Connection: close`, so the
|
|
509
|
+
* server closing is the end of the body. One byte over the cap is
|
|
510
|
+
* enough to know it was exceeded; the Lua side decides what that
|
|
511
|
+
* means. */
|
|
512
|
+
bufinit(&answer);
|
|
513
|
+
|
|
514
|
+
for (;;) {
|
|
515
|
+
char chunk[65536];
|
|
516
|
+
int got;
|
|
517
|
+
long left = deadline - nowms();
|
|
518
|
+
struct pollfd waiting;
|
|
519
|
+
|
|
520
|
+
if (0 >= left) {
|
|
521
|
+
answererr("timed out reading the response");
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
if (!usetls || 0 == SSL_pending(ssl)) {
|
|
525
|
+
waiting.fd = sock;
|
|
526
|
+
waiting.events = POLLIN;
|
|
527
|
+
waiting.revents = 0;
|
|
528
|
+
if (0 >= poll(&waiting, 1, (int)left)) {
|
|
529
|
+
answererr("timed out reading the response");
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
if (usetls) {
|
|
534
|
+
got = SSL_read(ssl, chunk, sizeof chunk);
|
|
535
|
+
if (0 >= got) {
|
|
536
|
+
int why = SSL_get_error(ssl, got);
|
|
537
|
+
if (SSL_ERROR_WANT_READ == why || SSL_ERROR_WANT_WRITE == why) {
|
|
538
|
+
continue;
|
|
539
|
+
}
|
|
540
|
+
break;
|
|
541
|
+
}
|
|
542
|
+
} else {
|
|
543
|
+
got = (int)read(sock, chunk, sizeof chunk);
|
|
544
|
+
if (0 > got && EINTR == errno) {
|
|
545
|
+
continue;
|
|
546
|
+
}
|
|
547
|
+
if (0 >= got) {
|
|
548
|
+
break;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
if (!bufput(&answer, chunk, (size_t)got)) {
|
|
553
|
+
answererr("out of memory reading the response");
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
if ((long)answer.len > maxbody) {
|
|
557
|
+
break;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
if (usetls) {
|
|
562
|
+
SSL_free(ssl);
|
|
563
|
+
SSL_CTX_free(ctx);
|
|
564
|
+
}
|
|
565
|
+
close(sock);
|
|
566
|
+
|
|
567
|
+
answerok(answer.data ? answer.data : "", answer.len);
|
|
568
|
+
buffree(&answer);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/* -------------------------------------------------------------- exec */
|
|
572
|
+
|
|
573
|
+
/*
|
|
574
|
+
* A child, with an argv ARRAY and no shell anywhere. The two streams are
|
|
575
|
+
* drained CONCURRENTLY through one poll: reading stdout to EOF and only
|
|
576
|
+
* then reading stderr deadlocks permanently the moment the child writes
|
|
577
|
+
* more than one pipe buffer (64 KiB) to stderr, and secretspec's
|
|
578
|
+
* box-drawn diagnostics reach that size easily.
|
|
579
|
+
*
|
|
580
|
+
* The child's stdin is /dev/null rather than a pipe nobody writes to, so
|
|
581
|
+
* a CLI that reads it - one prompting for a passphrase when its
|
|
582
|
+
* environment variable is absent - sees EOF and gives up instead of
|
|
583
|
+
* waiting forever.
|
|
584
|
+
*/
|
|
585
|
+
static void doexec(void) {
|
|
586
|
+
char **argv;
|
|
587
|
+
size_t argc = 0;
|
|
588
|
+
size_t index;
|
|
589
|
+
int outpipe[2];
|
|
590
|
+
int errpipe[2];
|
|
591
|
+
int failpipe[2];
|
|
592
|
+
char failure[256];
|
|
593
|
+
ssize_t failed;
|
|
594
|
+
pid_t child;
|
|
595
|
+
buf out;
|
|
596
|
+
buf why;
|
|
597
|
+
int status = 0;
|
|
598
|
+
int alive = 2;
|
|
599
|
+
char head[128];
|
|
600
|
+
int head_n;
|
|
601
|
+
|
|
602
|
+
for (index = 0; index < NFIELDS; index++) {
|
|
603
|
+
if (0 == strcmp(FIELDS[index].name, "arg")) {
|
|
604
|
+
argc++;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
if (0 == argc) {
|
|
609
|
+
answererr("no command given");
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
argv = calloc(argc + 1, sizeof(char *));
|
|
613
|
+
if (NULL == argv) {
|
|
614
|
+
answererr("out of memory");
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
argc = 0;
|
|
618
|
+
for (index = 0; index < NFIELDS; index++) {
|
|
619
|
+
if (0 == strcmp(FIELDS[index].name, "arg")) {
|
|
620
|
+
argv[argc++] = FIELDS[index].value;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
/* The child inherits THIS process's environment, which is the Lua
|
|
625
|
+
* process's environment, plus whatever `setenv` fields the caller sent.
|
|
626
|
+
* Lua cannot enumerate its own environment - `os.getenv` reads one name
|
|
627
|
+
* - so a caller-built environment would silently drop every variable
|
|
628
|
+
* the port did not think to name, and a child like boru reads several
|
|
629
|
+
* of its own. Inheriting and overriding is the only correct shape. */
|
|
630
|
+
for (index = 0; index < NFIELDS; index++) {
|
|
631
|
+
if (0 == strcmp(FIELDS[index].name, "setenv")) {
|
|
632
|
+
putenv(FIELDS[index].value);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
if (0 != pipe(outpipe) || 0 != pipe(errpipe) || 0 != pipe(failpipe)) {
|
|
637
|
+
answererr("cannot create a pipe");
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/* The exec status pipe: close-on-exec, so a SUCCESSFUL exec closes it
|
|
641
|
+
* with nothing written and the parent reads EOF. Anything that does
|
|
642
|
+
* arrive is the reason exec failed. Guessing from an exit code cannot
|
|
643
|
+
* do this - a real child is free to exit 127 too. */
|
|
644
|
+
if (0 != fcntl(failpipe[1], F_SETFD, FD_CLOEXEC)) {
|
|
645
|
+
answererr("cannot create a pipe");
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
child = fork();
|
|
649
|
+
if (0 > child) {
|
|
650
|
+
answererr("cannot fork");
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
if (0 == child) {
|
|
654
|
+
int devnull = open("/dev/null", O_RDONLY);
|
|
655
|
+
if (0 <= devnull) {
|
|
656
|
+
dup2(devnull, 0);
|
|
657
|
+
close(devnull);
|
|
658
|
+
} else {
|
|
659
|
+
close(0);
|
|
660
|
+
}
|
|
661
|
+
dup2(outpipe[1], 1);
|
|
662
|
+
dup2(errpipe[1], 2);
|
|
663
|
+
close(outpipe[0]);
|
|
664
|
+
close(outpipe[1]);
|
|
665
|
+
close(errpipe[0]);
|
|
666
|
+
close(errpipe[1]);
|
|
667
|
+
close(failpipe[0]);
|
|
668
|
+
execvp(argv[0], argv);
|
|
669
|
+
{
|
|
670
|
+
/* execvpe only returns on failure. */
|
|
671
|
+
const char *reason = strerror(errno);
|
|
672
|
+
ssize_t ignored = write(failpipe[1], reason, strlen(reason));
|
|
673
|
+
(void)ignored;
|
|
674
|
+
}
|
|
675
|
+
_exit(127);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
close(outpipe[1]);
|
|
679
|
+
close(errpipe[1]);
|
|
680
|
+
close(failpipe[1]);
|
|
681
|
+
|
|
682
|
+
failed = read(failpipe[0], failure, sizeof failure - 1);
|
|
683
|
+
close(failpipe[0]);
|
|
684
|
+
|
|
685
|
+
if (0 < failed) {
|
|
686
|
+
failure[failed] = '\0';
|
|
687
|
+
close(outpipe[0]);
|
|
688
|
+
close(errpipe[0]);
|
|
689
|
+
while (0 > waitpid(child, &status, 0)) {
|
|
690
|
+
if (EINTR != errno) {
|
|
691
|
+
break;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
{
|
|
695
|
+
char message[512];
|
|
696
|
+
snprintf(message, sizeof message, "EXECFAIL %s", failure);
|
|
697
|
+
answererr(message);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
bufinit(&out);
|
|
702
|
+
bufinit(&why);
|
|
703
|
+
|
|
704
|
+
while (0 < alive) {
|
|
705
|
+
struct pollfd waiting[2];
|
|
706
|
+
int count = 0;
|
|
707
|
+
int at;
|
|
708
|
+
|
|
709
|
+
if (0 <= outpipe[0]) {
|
|
710
|
+
waiting[count].fd = outpipe[0];
|
|
711
|
+
waiting[count].events = POLLIN;
|
|
712
|
+
waiting[count].revents = 0;
|
|
713
|
+
count++;
|
|
714
|
+
}
|
|
715
|
+
if (0 <= errpipe[0]) {
|
|
716
|
+
waiting[count].fd = errpipe[0];
|
|
717
|
+
waiting[count].events = POLLIN;
|
|
718
|
+
waiting[count].revents = 0;
|
|
719
|
+
count++;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
if (0 >= poll(waiting, (nfds_t)count, -1)) {
|
|
723
|
+
if (EINTR == errno) {
|
|
724
|
+
continue;
|
|
725
|
+
}
|
|
726
|
+
break;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
for (at = 0; at < count; at++) {
|
|
730
|
+
char chunk[65536];
|
|
731
|
+
ssize_t got;
|
|
732
|
+
|
|
733
|
+
if (0 == waiting[at].revents) {
|
|
734
|
+
continue;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
got = read(waiting[at].fd, chunk, sizeof chunk);
|
|
738
|
+
if (0 < got) {
|
|
739
|
+
if (!bufput(waiting[at].fd == outpipe[0] ? &out : &why, chunk, (size_t)got)) {
|
|
740
|
+
answererr("out of memory reading the child");
|
|
741
|
+
}
|
|
742
|
+
} else if (0 > got && EINTR == errno) {
|
|
743
|
+
continue;
|
|
744
|
+
} else {
|
|
745
|
+
close(waiting[at].fd);
|
|
746
|
+
if (waiting[at].fd == outpipe[0]) {
|
|
747
|
+
outpipe[0] = -1;
|
|
748
|
+
} else {
|
|
749
|
+
errpipe[0] = -1;
|
|
750
|
+
}
|
|
751
|
+
alive--;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
while (0 > waitpid(child, &status, 0)) {
|
|
757
|
+
if (EINTR != errno) {
|
|
758
|
+
break;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
{
|
|
763
|
+
int code = 0;
|
|
764
|
+
if (WIFEXITED(status)) {
|
|
765
|
+
code = WEXITSTATUS(status);
|
|
766
|
+
} else if (WIFSIGNALED(status)) {
|
|
767
|
+
code = 128 + WTERMSIG(status);
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
/* 127 is "could not be executed": the caller turns it into
|
|
771
|
+
* `sekreto: cannot run <command>: ...` rather than a store error. */
|
|
772
|
+
head_n = snprintf(head, sizeof head, "EXEC %d %zu %zu\n", code, out.len, why.len);
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
writeall(1, head, (size_t)head_n);
|
|
776
|
+
writeall(1, out.data ? out.data : "", out.len);
|
|
777
|
+
writeall(1, why.data ? why.data : "", why.len);
|
|
778
|
+
|
|
779
|
+
buffree(&out);
|
|
780
|
+
buffree(&why);
|
|
781
|
+
exit(0);
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
int main(int argc, char **argv) {
|
|
785
|
+
const char *mode;
|
|
786
|
+
|
|
787
|
+
/* A child that exits while its pipe is still being written must not
|
|
788
|
+
* take this process down with it. */
|
|
789
|
+
signal(SIGPIPE, SIG_IGN);
|
|
790
|
+
|
|
791
|
+
if (2 > argc) {
|
|
792
|
+
answererr("no transport request given");
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
readrequest(argv[1]);
|
|
796
|
+
|
|
797
|
+
mode = fieldof("mode", "fetch");
|
|
798
|
+
|
|
799
|
+
if (0 == strcmp(mode, "exec")) {
|
|
800
|
+
doexec();
|
|
801
|
+
} else {
|
|
802
|
+
dofetch();
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
return 0;
|
|
806
|
+
}
|