@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,599 @@
|
|
|
1
|
+
// VENDORED: @voxgig/sekreto sdk-20260908-1556-0 (c/plugins/httpjson.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
|
+
/* Just enough HTTP to ask a vault for a secret: the shared HTTP-JSON
|
|
5
|
+
* helper every store above it is written against.
|
|
6
|
+
*
|
|
7
|
+
* It lives under `plugins/` with the stores that use it, because a chain
|
|
8
|
+
* of the four built-in kinds must never link a socket. `sek_fetch` is
|
|
9
|
+
* published from here rather than from the core for the same reason: the
|
|
10
|
+
* CLI needs an HTTP client to call the API it just fetched a token for,
|
|
11
|
+
* and every other port reaches for its platform's.
|
|
12
|
+
*
|
|
13
|
+
* C has no HTTP client, so this speaks HTTP/1.1 over a POSIX socket
|
|
14
|
+
* directly: a GET or POST with headers and an optional body, a status
|
|
15
|
+
* line, and a response body delimited by Content-Length, by chunks, or by
|
|
16
|
+
* the connection closing. https hands the connected socket to tls.c and
|
|
17
|
+
* then speaks exactly the same framing over it.
|
|
18
|
+
*
|
|
19
|
+
* The framing is hand-rolled and stays hand-rolled: the dependency
|
|
20
|
+
* exception covers cryptographic transport, and HTTP is not that. This is
|
|
21
|
+
* also why the binding is OpenSSL rather than libcurl - libcurl is an
|
|
22
|
+
* HTTP client, and taking it would carry the framing across the line the
|
|
23
|
+
* rule draws.
|
|
24
|
+
*
|
|
25
|
+
* It is not a general-purpose client, deliberately:
|
|
26
|
+
*
|
|
27
|
+
* NO REDIRECTS. A followed redirect carries X-Vault-Token to a host
|
|
28
|
+
* checkaddr never saw, and can downgrade https to http.
|
|
29
|
+
*
|
|
30
|
+
* NO PROXIES. http_proxy in an environment has sent a Vault token in
|
|
31
|
+
* the clear before, and the GCP and Azure metadata endpoints are not
|
|
32
|
+
* loopback, so a blanket proxy would capture them too.
|
|
33
|
+
*
|
|
34
|
+
* NO KEEP-ALIVE, no client certificates, no cookies.
|
|
35
|
+
*
|
|
36
|
+
* A port of rust/src/http.rs.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
#define _POSIX_C_SOURCE 200809L
|
|
40
|
+
|
|
41
|
+
#include <errno.h>
|
|
42
|
+
#include <fcntl.h>
|
|
43
|
+
#include <netdb.h>
|
|
44
|
+
#include <netinet/in.h>
|
|
45
|
+
#include <netinet/tcp.h>
|
|
46
|
+
#include <poll.h>
|
|
47
|
+
#include <stdio.h>
|
|
48
|
+
#include <stdlib.h>
|
|
49
|
+
#include <string.h>
|
|
50
|
+
#include <sys/socket.h>
|
|
51
|
+
#include <sys/time.h>
|
|
52
|
+
#include <time.h>
|
|
53
|
+
#include <unistd.h>
|
|
54
|
+
|
|
55
|
+
#include "support.h"
|
|
56
|
+
|
|
57
|
+
/* A url split into the parts a request needs. */
|
|
58
|
+
typedef struct {
|
|
59
|
+
char *host; /* bare: what is connected to and what the certificate
|
|
60
|
+
* is checked against; an IPv6 literal without its
|
|
61
|
+
* brackets. */
|
|
62
|
+
char *authority; /* as it goes in `Host:`; an IPv6 literal keeps its
|
|
63
|
+
* brackets, because `Host: 2001:db8::1:8200` is not a
|
|
64
|
+
* valid authority. */
|
|
65
|
+
int port;
|
|
66
|
+
char *path;
|
|
67
|
+
int tls;
|
|
68
|
+
} target;
|
|
69
|
+
|
|
70
|
+
static sek_err split(sek_pool *pool, const char *url, target *out) {
|
|
71
|
+
const char *rest;
|
|
72
|
+
const char *slash;
|
|
73
|
+
char *authority;
|
|
74
|
+
const char *colon;
|
|
75
|
+
int defaultport;
|
|
76
|
+
|
|
77
|
+
if (sek_has_prefix(url, "https://")) {
|
|
78
|
+
rest = url + 8;
|
|
79
|
+
out->tls = 1;
|
|
80
|
+
defaultport = 443;
|
|
81
|
+
} else if (sek_has_prefix(url, "http://")) {
|
|
82
|
+
rest = url + 7;
|
|
83
|
+
out->tls = 0;
|
|
84
|
+
defaultport = 80;
|
|
85
|
+
} else {
|
|
86
|
+
return sek_fmt(pool, "sekreto: not an http url: %s", sek_bareurl(pool, url));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
slash = strchr(rest, '/');
|
|
90
|
+
if (NULL == slash) {
|
|
91
|
+
authority = sek_strdup(pool, rest);
|
|
92
|
+
out->path = sek_strdup(pool, "/");
|
|
93
|
+
} else {
|
|
94
|
+
authority = sek_strndup(pool, rest, (size_t)(slash - rest));
|
|
95
|
+
out->path = sek_strdup(pool, slash);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
out->port = defaultport;
|
|
99
|
+
|
|
100
|
+
/* Searched from the RIGHT, so an IPv6 literal's own colons are not read
|
|
101
|
+
* as a port separator. */
|
|
102
|
+
colon = strrchr(authority, ':');
|
|
103
|
+
if (NULL != colon && '\0' != colon[1] && '\0' != authority[0] &&
|
|
104
|
+
']' != authority[strlen(authority) - 1]) {
|
|
105
|
+
char *stop = NULL;
|
|
106
|
+
long port = strtol(colon + 1, &stop, 10);
|
|
107
|
+
|
|
108
|
+
if (NULL == stop || '\0' != *stop || 0 >= port || 65535 < port) {
|
|
109
|
+
return sek_fmt(pool, "sekreto: bad port: %s", sek_bareurl(pool, url));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
out->port = (int)port;
|
|
113
|
+
authority = sek_strndup(pool, authority, (size_t)(colon - authority));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
{
|
|
117
|
+
size_t len = strlen(authority);
|
|
118
|
+
if (2 <= len && '[' == authority[0] && ']' == authority[len - 1]) {
|
|
119
|
+
out->host = sek_strndup(pool, authority + 1, len - 2);
|
|
120
|
+
out->authority = authority;
|
|
121
|
+
} else {
|
|
122
|
+
out->host = authority;
|
|
123
|
+
/* Re-bracketed only if it really is an IPv6 literal. */
|
|
124
|
+
out->authority = NULL != strchr(authority, ':') ? sek_fmt(pool, "[%s]", authority)
|
|
125
|
+
: authority;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return NULL;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Connect within one shared deadline.
|
|
133
|
+
*
|
|
134
|
+
* The bound is on the WHOLE attempt, not on each address. A name commonly
|
|
135
|
+
* resolves to several - a dual-stack host answers with both an A and an
|
|
136
|
+
* AAAA - and giving each the full ten seconds makes the real bound ten
|
|
137
|
+
* seconds times however many addresses the name cares to return, which is
|
|
138
|
+
* not a bound at all when the name is the attacker's.
|
|
139
|
+
*
|
|
140
|
+
* A blocking connect() has no bound of its own: against an address that
|
|
141
|
+
* swallows SYNs it blocks for however long the kernel retries, which on
|
|
142
|
+
* Linux is a little over two minutes. So the socket is put in
|
|
143
|
+
* non-blocking mode, connect() is started, and poll() carries what is
|
|
144
|
+
* left of the deadline. */
|
|
145
|
+
static sek_err dial(sek_pool *pool, const target *to, const char *url, long long deadline,
|
|
146
|
+
int *out) {
|
|
147
|
+
struct addrinfo hints;
|
|
148
|
+
struct addrinfo *found = NULL;
|
|
149
|
+
struct addrinfo *at;
|
|
150
|
+
char service[16];
|
|
151
|
+
int code;
|
|
152
|
+
const char *last = "no address";
|
|
153
|
+
|
|
154
|
+
memset(&hints, 0, sizeof(hints));
|
|
155
|
+
hints.ai_family = AF_UNSPEC;
|
|
156
|
+
hints.ai_socktype = SOCK_STREAM;
|
|
157
|
+
|
|
158
|
+
snprintf(service, sizeof(service), "%d", to->port);
|
|
159
|
+
|
|
160
|
+
code = getaddrinfo(to->host, service, &hints, &found);
|
|
161
|
+
if (0 != code) {
|
|
162
|
+
return sek_fmt(pool, "sekreto: cannot reach %s: %s", sek_bareurl(pool, url),
|
|
163
|
+
gai_strerror(code));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
for (at = found; NULL != at; at = at->ai_next) {
|
|
167
|
+
int fd;
|
|
168
|
+
long long left = deadline - sek_nowms();
|
|
169
|
+
int flags;
|
|
170
|
+
|
|
171
|
+
if (0 >= left) {
|
|
172
|
+
last = "timed out";
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
fd = socket(at->ai_family, at->ai_socktype, at->ai_protocol);
|
|
177
|
+
if (0 > fd) {
|
|
178
|
+
last = strerror(errno);
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
flags = fcntl(fd, F_GETFL, 0);
|
|
183
|
+
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
|
184
|
+
|
|
185
|
+
if (0 == connect(fd, at->ai_addr, at->ai_addrlen)) {
|
|
186
|
+
fcntl(fd, F_SETFL, flags);
|
|
187
|
+
freeaddrinfo(found);
|
|
188
|
+
*out = fd;
|
|
189
|
+
return NULL;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (EINPROGRESS == errno) {
|
|
193
|
+
struct pollfd waiting;
|
|
194
|
+
int ready;
|
|
195
|
+
|
|
196
|
+
waiting.fd = fd;
|
|
197
|
+
waiting.events = POLLOUT;
|
|
198
|
+
waiting.revents = 0;
|
|
199
|
+
|
|
200
|
+
ready = poll(&waiting, 1, (int)left);
|
|
201
|
+
|
|
202
|
+
if (0 < ready) {
|
|
203
|
+
int problem = 0;
|
|
204
|
+
socklen_t size = sizeof(problem);
|
|
205
|
+
|
|
206
|
+
if (0 == getsockopt(fd, SOL_SOCKET, SO_ERROR, &problem, &size) && 0 == problem) {
|
|
207
|
+
fcntl(fd, F_SETFL, flags);
|
|
208
|
+
freeaddrinfo(found);
|
|
209
|
+
*out = fd;
|
|
210
|
+
return NULL;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
last = 0 == problem ? "connection failed" : strerror(problem);
|
|
214
|
+
} else if (0 == ready) {
|
|
215
|
+
last = "timed out";
|
|
216
|
+
} else {
|
|
217
|
+
last = strerror(errno);
|
|
218
|
+
}
|
|
219
|
+
} else {
|
|
220
|
+
last = strerror(errno);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
close(fd);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
freeaddrinfo(found);
|
|
227
|
+
|
|
228
|
+
return sek_fmt(pool, "sekreto: cannot reach %s: %s", sek_bareurl(pool, url), last);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/* Both transports behind one pair of calls, so the framing below is
|
|
232
|
+
* written once. */
|
|
233
|
+
typedef struct {
|
|
234
|
+
int fd;
|
|
235
|
+
sek_tls_conn *tls;
|
|
236
|
+
} channel;
|
|
237
|
+
|
|
238
|
+
static sek_err sendall(channel *ch, const char *data, size_t len) {
|
|
239
|
+
size_t at = 0;
|
|
240
|
+
|
|
241
|
+
while (at < len) {
|
|
242
|
+
long wrote;
|
|
243
|
+
|
|
244
|
+
if (NULL != ch->tls) {
|
|
245
|
+
sek_err err = NULL;
|
|
246
|
+
wrote = sek_tls_write(ch->tls, data + at, len - at, &err);
|
|
247
|
+
if (0 > wrote) {
|
|
248
|
+
return NULL == err ? "write failed" : err;
|
|
249
|
+
}
|
|
250
|
+
} else {
|
|
251
|
+
ssize_t got = send(ch->fd, data + at, len - at, 0);
|
|
252
|
+
if (0 > got) {
|
|
253
|
+
if (EINTR == errno) {
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
return strerror(errno);
|
|
257
|
+
}
|
|
258
|
+
wrote = (long)got;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
at += (size_t)wrote;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return NULL;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
static long receive(channel *ch, char *data, size_t len, sek_err *err) {
|
|
268
|
+
if (NULL != ch->tls) {
|
|
269
|
+
return sek_tls_read(ch->tls, data, len, err);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
for (;;) {
|
|
273
|
+
ssize_t got = recv(ch->fd, data, len, 0);
|
|
274
|
+
|
|
275
|
+
if (0 <= got) {
|
|
276
|
+
return (long)got;
|
|
277
|
+
}
|
|
278
|
+
if (EINTR == errno) {
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
*err = strerror(errno);
|
|
283
|
+
return -1;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
static const char *findbytes(const char *hay, size_t haylen, const char *needle, size_t len) {
|
|
288
|
+
size_t index;
|
|
289
|
+
|
|
290
|
+
if (haylen < len) {
|
|
291
|
+
return NULL;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
for (index = 0; index + len <= haylen; index++) {
|
|
295
|
+
if (0 == memcmp(hay + index, needle, len)) {
|
|
296
|
+
return hay + index;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return NULL;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/* Join a chunked body back together: a hex length (any `;`-separated
|
|
304
|
+
* extension dropped), CRLF, that many BYTES, CRLF; a zero length ends the
|
|
305
|
+
* body and any trailer is ignored.
|
|
306
|
+
*
|
|
307
|
+
* Bytes, not characters. A chunk length counts bytes and a boundary may
|
|
308
|
+
* fall inside a multibyte character, so a secret with any non-ASCII
|
|
309
|
+
* character in it would otherwise come back mangled or take the process
|
|
310
|
+
* down. */
|
|
311
|
+
static int dechunk(sek_pool *pool, const char *raw, size_t len, sek_buf *out) {
|
|
312
|
+
const char *rest = raw;
|
|
313
|
+
size_t left = len;
|
|
314
|
+
|
|
315
|
+
sek_buf_init(out, pool);
|
|
316
|
+
|
|
317
|
+
for (;;) {
|
|
318
|
+
const char *crlf = findbytes(rest, left, "\r\n", 2);
|
|
319
|
+
char *header;
|
|
320
|
+
char *stop = NULL;
|
|
321
|
+
unsigned long size;
|
|
322
|
+
size_t headlen;
|
|
323
|
+
|
|
324
|
+
if (NULL == crlf) {
|
|
325
|
+
return 0;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
headlen = (size_t)(crlf - rest);
|
|
329
|
+
header = sek_strndup(pool, rest, headlen);
|
|
330
|
+
{
|
|
331
|
+
char *semi = strchr(header, ';');
|
|
332
|
+
if (NULL != semi) {
|
|
333
|
+
*semi = '\0';
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
size = strtoul(header, &stop, 16);
|
|
338
|
+
if (stop == header) {
|
|
339
|
+
return 0;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
left -= headlen + 2;
|
|
343
|
+
rest = crlf + 2;
|
|
344
|
+
|
|
345
|
+
if (0 == size) {
|
|
346
|
+
return 1;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (left < size) {
|
|
350
|
+
return 0;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
sek_buf_addn(out, rest, size);
|
|
354
|
+
|
|
355
|
+
if (left < size + 2) {
|
|
356
|
+
return 0;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
rest += size + 2;
|
|
360
|
+
left -= size + 2;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
sek_err sek_http(sek_pool *pool, const char *method, const char *url, const sek_map *headers,
|
|
365
|
+
const char *body, sek_response *out) {
|
|
366
|
+
target to;
|
|
367
|
+
sek_err err;
|
|
368
|
+
channel ch;
|
|
369
|
+
int fd = -1;
|
|
370
|
+
long long deadline = sek_nowms() + SEK_TIMEOUT_MS;
|
|
371
|
+
sek_buf request;
|
|
372
|
+
sek_buf raw;
|
|
373
|
+
const char *split_at;
|
|
374
|
+
char *head;
|
|
375
|
+
size_t index;
|
|
376
|
+
int chunked = 0;
|
|
377
|
+
const char *bare = sek_bareurl(pool, url);
|
|
378
|
+
|
|
379
|
+
memset(&to, 0, sizeof(to));
|
|
380
|
+
memset(&ch, 0, sizeof(ch));
|
|
381
|
+
out->status = 0;
|
|
382
|
+
out->body = NULL;
|
|
383
|
+
out->bodylen = 0;
|
|
384
|
+
|
|
385
|
+
err = split(pool, url, &to);
|
|
386
|
+
if (NULL != err) {
|
|
387
|
+
return err;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
err = dial(pool, &to, url, deadline, &fd);
|
|
391
|
+
if (NULL != err) {
|
|
392
|
+
return err;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/* The read and write halves are both bounded. Only bounding the read
|
|
396
|
+
* leaves a write blocked forever once the peer's receive window fills
|
|
397
|
+
* and it stops reading. */
|
|
398
|
+
{
|
|
399
|
+
struct timeval bound;
|
|
400
|
+
bound.tv_sec = SEK_TIMEOUT_MS / 1000;
|
|
401
|
+
bound.tv_usec = (SEK_TIMEOUT_MS % 1000) * 1000;
|
|
402
|
+
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &bound, sizeof(bound));
|
|
403
|
+
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &bound, sizeof(bound));
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
ch.fd = fd;
|
|
407
|
+
|
|
408
|
+
if (to.tls) {
|
|
409
|
+
if (!sek_tls_available()) {
|
|
410
|
+
close(fd);
|
|
411
|
+
return sek_fmt(pool, "sekreto: cannot reach %s: this build has no TLS backend", bare);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
err = sek_tls_open(pool, fd, to.host, &ch.tls);
|
|
415
|
+
if (NULL != err) {
|
|
416
|
+
close(fd);
|
|
417
|
+
/* A handshake failure is a refusal to TRUST the server, so it
|
|
418
|
+
* surfaces as an error and never as a missing secret. */
|
|
419
|
+
return sek_fmt(pool, "sekreto: cannot reach %s: %s", bare, err);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/* A default port stays implicit in the Host header, the way a URL
|
|
424
|
+
* normalises it: a SigV4 signature covers `host`, and `Host: x:443` is
|
|
425
|
+
* not what was signed. */
|
|
426
|
+
sek_buf_init(&request, pool);
|
|
427
|
+
sek_buf_addfmt(&request, "%s %s HTTP/1.1\r\n", method, to.path);
|
|
428
|
+
if ((to.tls && 443 == to.port) || (!to.tls && 80 == to.port)) {
|
|
429
|
+
sek_buf_addfmt(&request, "Host: %s\r\n", to.authority);
|
|
430
|
+
} else {
|
|
431
|
+
sek_buf_addfmt(&request, "Host: %s:%d\r\n", to.authority, to.port);
|
|
432
|
+
}
|
|
433
|
+
sek_buf_add(&request, "Accept: application/json\r\n");
|
|
434
|
+
sek_buf_add(&request, "Connection: close\r\n");
|
|
435
|
+
|
|
436
|
+
if (NULL != headers) {
|
|
437
|
+
for (index = 0; index < headers->len; index++) {
|
|
438
|
+
sek_buf_addfmt(&request, "%s: %s\r\n", headers->keys[index], headers->vals[index]);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (NULL != body) {
|
|
443
|
+
sek_buf_addfmt(&request, "Content-Length: %lu\r\n", (unsigned long)strlen(body));
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
sek_buf_add(&request, "\r\n");
|
|
447
|
+
|
|
448
|
+
if (NULL != body) {
|
|
449
|
+
sek_buf_add(&request, body);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
err = sendall(&ch, request.data, request.len);
|
|
453
|
+
if (NULL != err) {
|
|
454
|
+
sek_tls_close(ch.tls);
|
|
455
|
+
close(fd);
|
|
456
|
+
return sek_fmt(pool, "sekreto: cannot reach %s: %s", bare, err);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/* Bounded, not read-to-end: an endless body would otherwise be
|
|
460
|
+
* accumulated in memory until the deadline, which on a loopback or
|
|
461
|
+
* datacentre link is gigabytes. One byte over the bound is enough to
|
|
462
|
+
* know it was exceeded, and an endless body is a store that could not
|
|
463
|
+
* answer - so this is an error, never a miss. */
|
|
464
|
+
sek_buf_init(&raw, pool);
|
|
465
|
+
for (;;) {
|
|
466
|
+
char chunk[16384];
|
|
467
|
+
sek_err why = NULL;
|
|
468
|
+
long got;
|
|
469
|
+
|
|
470
|
+
if (sek_nowms() > deadline) {
|
|
471
|
+
sek_tls_close(ch.tls);
|
|
472
|
+
close(fd);
|
|
473
|
+
return sek_fmt(pool, "sekreto: cannot reach %s: timed out", bare);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
got = receive(&ch, chunk, sizeof(chunk), &why);
|
|
477
|
+
|
|
478
|
+
if (0 > got) {
|
|
479
|
+
sek_tls_close(ch.tls);
|
|
480
|
+
close(fd);
|
|
481
|
+
return sek_fmt(pool, "sekreto: cannot reach %s: %s", bare, NULL == why ? "read failed" : why);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if (0 == got) {
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
sek_buf_addn(&raw, chunk, (size_t)got);
|
|
489
|
+
|
|
490
|
+
if (SEK_MAXBODY < raw.len) {
|
|
491
|
+
sek_tls_close(ch.tls);
|
|
492
|
+
close(fd);
|
|
493
|
+
return sek_fmt(pool, "sekreto: oversized response from %s", bare);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
sek_tls_close(ch.tls);
|
|
498
|
+
close(fd);
|
|
499
|
+
|
|
500
|
+
split_at = findbytes(raw.data, raw.len, "\r\n\r\n", 4);
|
|
501
|
+
if (NULL == split_at) {
|
|
502
|
+
return sek_fmt(pool, "sekreto: malformed response from %s", bare);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/* Headers are ASCII; the body is not necessarily, so it stays bytes
|
|
506
|
+
* until every length-counted slice has been taken. */
|
|
507
|
+
head = sek_strndup(pool, raw.data, (size_t)(split_at - raw.data));
|
|
508
|
+
|
|
509
|
+
{
|
|
510
|
+
/* "HTTP/1.1 200 OK" - the status is the second whitespace-separated
|
|
511
|
+
* field of the first line. */
|
|
512
|
+
const char *space = strchr(head, ' ');
|
|
513
|
+
if (NULL == space) {
|
|
514
|
+
return sek_fmt(pool, "sekreto: malformed response from %s", bare);
|
|
515
|
+
}
|
|
516
|
+
out->status = (int)strtol(space + 1, NULL, 10);
|
|
517
|
+
if (0 == out->status) {
|
|
518
|
+
return sek_fmt(pool, "sekreto: malformed response from %s", bare);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
{
|
|
523
|
+
/* transfer-encoding, matched case-insensitively on both halves: a
|
|
524
|
+
* vault answering from a store usually chunks. */
|
|
525
|
+
char *lowered = sek_lowercase(pool, head);
|
|
526
|
+
char *line = strstr(lowered, "\ntransfer-encoding:");
|
|
527
|
+
if (NULL != line && NULL != strstr(line, "chunked")) {
|
|
528
|
+
const char *stop = strchr(line + 1, '\n');
|
|
529
|
+
char *value = NULL == stop ? sek_strdup(pool, line + 1)
|
|
530
|
+
: sek_strndup(pool, line + 1, (size_t)(stop - line - 1));
|
|
531
|
+
chunked = sek_contains(value, "chunked");
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
{
|
|
536
|
+
const char *rawbody = split_at + 4;
|
|
537
|
+
size_t bodylen = raw.len - (size_t)(rawbody - raw.data);
|
|
538
|
+
|
|
539
|
+
if (chunked) {
|
|
540
|
+
sek_buf joined;
|
|
541
|
+
if (!dechunk(pool, rawbody, bodylen, &joined)) {
|
|
542
|
+
return sek_fmt(pool, "sekreto: malformed response from %s", bare);
|
|
543
|
+
}
|
|
544
|
+
out->body = joined.data;
|
|
545
|
+
out->bodylen = joined.len;
|
|
546
|
+
} else {
|
|
547
|
+
out->body = sek_strndup(pool, rawbody, bodylen);
|
|
548
|
+
out->bodylen = bodylen;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
return NULL;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
sek_err sek_fetchjson(sek_pool *pool, const char *method, const char *url, const sek_map *headers,
|
|
556
|
+
const char *body, sek_answer *out) {
|
|
557
|
+
sek_response res;
|
|
558
|
+
sek_err err = sek_http(pool, method, url, headers, body, &res);
|
|
559
|
+
|
|
560
|
+
out->status = 0;
|
|
561
|
+
out->body = NULL;
|
|
562
|
+
|
|
563
|
+
if (NULL != err) {
|
|
564
|
+
return err;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
out->status = res.status;
|
|
568
|
+
out->body = sek_json_parse(pool, res.body);
|
|
569
|
+
|
|
570
|
+
/* A success status promised JSON. A body that does not parse means the
|
|
571
|
+
* store could not answer coherently, and treating that as a miss would
|
|
572
|
+
* fall through to a weaker store. Error statuses may carry any body -
|
|
573
|
+
* they are decided on status alone. */
|
|
574
|
+
if (200 == res.status && NULL == out->body) {
|
|
575
|
+
return sek_fmt(pool, "sekreto: malformed response from %s", sek_bareurl(pool, url));
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
return NULL;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/* The published round-trip. Thin on purpose: a consumer gets the status
|
|
582
|
+
* and the body and decides for itself, exactly as the providers do. */
|
|
583
|
+
sek_err sek_fetch(sek_pool *pool, const char *method, const char *url, const sek_map *headers,
|
|
584
|
+
const char *body, int *status, char **out) {
|
|
585
|
+
sek_response res;
|
|
586
|
+
sek_err err = sek_http(pool, method, url, headers, body, &res);
|
|
587
|
+
|
|
588
|
+
*status = 0;
|
|
589
|
+
*out = NULL;
|
|
590
|
+
|
|
591
|
+
if (NULL != err) {
|
|
592
|
+
return err;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
*status = res.status;
|
|
596
|
+
*out = res.body;
|
|
597
|
+
|
|
598
|
+
return NULL;
|
|
599
|
+
}
|