mirror of
https://github.com/neondatabase/neon.git
synced 2026-02-10 06:00:38 +00:00
Compare commits
7 Commits
conrad/ref
...
funbringer
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f8751191b | ||
|
|
aba8cec279 | ||
|
|
67e1d6f6fc | ||
|
|
febce3903a | ||
|
|
a271ca6c8c | ||
|
|
cee9c726d2 | ||
|
|
a12c85449a |
268
Cargo.lock
generated
268
Cargo.lock
generated
@@ -2,6 +2,37 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "abnf"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33741baa462d86e43fdec5e8ffca7c6ac82847ad06cbfb382c1bdbf527de9e6b"
|
||||
dependencies = [
|
||||
"abnf-core",
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "abnf-core"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c44e09c43ae1c368fb91a03a566472d0087c26cf7e1b9e8e289c14ede681dd7d"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "abnf_to_pest"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "939d59666dd9a7964a3a5312b9d24c9c107630752ee64f2dd5038189a23fe331"
|
||||
dependencies = [
|
||||
"abnf",
|
||||
"indexmap",
|
||||
"itertools",
|
||||
"pretty",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.19.0"
|
||||
@@ -63,6 +94,15 @@ version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
|
||||
|
||||
[[package]]
|
||||
name = "annotate-snippets"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3b9d411ecbaf79885c6df4d75fff75858d5995ff25385657a28af47e82f9c36"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.68"
|
||||
@@ -81,6 +121,12 @@ dependencies = [
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "asn1-rs"
|
||||
version = "0.5.1"
|
||||
@@ -737,7 +783,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b"
|
||||
dependencies = [
|
||||
"ciborium-io",
|
||||
"half",
|
||||
"half 1.8.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1084,6 +1130,12 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
@@ -1216,6 +1268,42 @@ dependencies = [
|
||||
"rusticata-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dhall"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec26264de25a8e3642fbb37abb24a6c6be9e19795444e6cf1bb88be5c2d55cc7"
|
||||
dependencies = [
|
||||
"abnf_to_pest",
|
||||
"annotate-snippets",
|
||||
"elsa",
|
||||
"half 2.2.1",
|
||||
"hex",
|
||||
"home",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"minicbor",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pest",
|
||||
"pest_consume",
|
||||
"pest_generator",
|
||||
"quote",
|
||||
"sha2",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dhall_proc_macros"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efcdb228bf802b21cd843e5ac3959b6255966238e5ec06d2e4bc6b9935475653"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.6"
|
||||
@@ -1238,12 +1326,27 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "doc-comment"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
|
||||
|
||||
[[package]]
|
||||
name = "elsa"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f74077c3c3aedb99a2683919698285596662518ea13e5eedcf8bdd43b0d0453b"
|
||||
dependencies = [
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.32"
|
||||
@@ -1556,6 +1659,19 @@ version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "globset"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"bstr",
|
||||
"fnv",
|
||||
"log",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.15"
|
||||
@@ -1581,6 +1697,15 @@ version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0"
|
||||
dependencies = [
|
||||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hash32"
|
||||
version = "0.3.1"
|
||||
@@ -1677,6 +1802,15 @@ dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "747309b4b440c06d57b0b25f2aee03ee9b5e5397d288c60e21fc709bb98a7408"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hostname"
|
||||
version = "0.3.1"
|
||||
@@ -2123,6 +2257,27 @@ dependencies = [
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minicbor"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a20020e8e2d1881d8736f64011bb5ff99f1db9947ce3089706945c8915695cb"
|
||||
dependencies = [
|
||||
"half 1.8.2",
|
||||
"minicbor-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minicbor-derive"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8608fb1c805b5b6b3d5ab7bd95c40c396df622b64d77b2d621a5eae1eed050ee"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
@@ -2551,6 +2706,72 @@ version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cbd939b234e95d72bc393d51788aec68aeeb5d51e748ca08ff3aad58cb722f7"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_consume"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79447402d15d18e7142e14c72f2e63fa3d155be1bc5b70b3ccbb610ac55f536b"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_consume_macros",
|
||||
"pest_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_consume_macros"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d8630a7a899cb344ec1c16ba0a6b24240029af34bdc0a21f84e411d7f793f29"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_derive"
|
||||
version = "2.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a81186863f3d0a27340815be8f2078dd8050b14cd71913db9fbda795e5f707d7"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_generator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_generator"
|
||||
version = "2.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75a1ef20bf3193c15ac345acb32e26b3dc3223aff4d77ae4fc5359567683796b"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_meta"
|
||||
version = "2.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e3b284b1f13a20dc5ebc90aff59a51b8d7137c221131b52a7260c08cbc1cc80"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"pest",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.6.2"
|
||||
@@ -2761,6 +2982,18 @@ dependencies = [
|
||||
"workspace_hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pretty"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83f3aa1e3ca87d3b124db7461265ac176b40c277f37e503eaa29c9c75c037846"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"log",
|
||||
"typed-arena",
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.1.23"
|
||||
@@ -2909,6 +3142,7 @@ dependencies = [
|
||||
"consumption_metrics",
|
||||
"futures",
|
||||
"git-version",
|
||||
"globset",
|
||||
"hashbrown 0.13.2",
|
||||
"hashlink",
|
||||
"hex",
|
||||
@@ -2939,6 +3173,7 @@ dependencies = [
|
||||
"rustls-pemfile",
|
||||
"scopeguard",
|
||||
"serde",
|
||||
"serde_dhall",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"socket2",
|
||||
@@ -3546,6 +3781,19 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_dhall"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "655a5c686ad80aef90d2e6bfea3715778623c9a659017c8346bc97eb58f9b27d"
|
||||
dependencies = [
|
||||
"dhall",
|
||||
"dhall_proc_macros",
|
||||
"doc-comment",
|
||||
"serde",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.91"
|
||||
@@ -4433,12 +4681,24 @@ dependencies = [
|
||||
"utf-8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typed-arena"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81"
|
||||
|
||||
[[package]]
|
||||
name = "uname"
|
||||
version = "0.1.1"
|
||||
@@ -4478,6 +4738,12 @@ dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.10"
|
||||
|
||||
@@ -47,6 +47,7 @@ futures = "0.3"
|
||||
futures-core = "0.3"
|
||||
futures-util = "0.3"
|
||||
git-version = "0.3"
|
||||
globset = "0.4.10"
|
||||
hashbrown = "0.13"
|
||||
hashlink = "0.8.1"
|
||||
hex = "0.4"
|
||||
@@ -87,6 +88,7 @@ rustls-split = "0.3"
|
||||
scopeguard = "1.1"
|
||||
sentry = { version = "0.29", default-features = false, features = ["backtrace", "contexts", "panic", "rustls", "reqwest" ] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_dhall = { version = "0.12.1", default_features = false }
|
||||
serde_json = "1"
|
||||
serde_with = "2.0"
|
||||
sha2 = "0.10.2"
|
||||
|
||||
@@ -16,6 +16,7 @@ clap.workspace = true
|
||||
consumption_metrics.workspace = true
|
||||
futures.workspace = true
|
||||
git-version.workspace = true
|
||||
globset.workspace = true
|
||||
hashbrown.workspace = true
|
||||
hashlink.workspace = true
|
||||
hex.workspace = true
|
||||
@@ -44,6 +45,7 @@ rustls-pemfile.workspace = true
|
||||
rustls.workspace = true
|
||||
scopeguard.workspace = true
|
||||
serde.workspace = true
|
||||
serde_dhall.workspace = true
|
||||
serde_json.workspace = true
|
||||
sha2.workspace = true
|
||||
socket2.workspace = true
|
||||
|
||||
0
proxy/config/README.md
Normal file
0
proxy/config/README.md
Normal file
77
proxy/config/foo.bar.localhost/server.crt
Normal file
77
proxy/config/foo.bar.localhost/server.crt
Normal file
@@ -0,0 +1,77 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number:
|
||||
67:2b:fc:80:27:9f:65:dd:42:d7:ef:a8:0a:fe:bd:d1:a8:2d:c8:da
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: CN = *.foo.bar.localhost
|
||||
Validity
|
||||
Not Before: Mar 30 12:39:55 2023 GMT
|
||||
Not After : Sep 3 12:39:55 2202 GMT
|
||||
Subject: CN = *.foo.bar.localhost
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:a3:67:45:c1:97:47:83:a1:1b:34:6a:a5:fa:1a:
|
||||
0c:d7:b9:4e:ef:bd:03:8f:64:bf:e3:ca:51:d8:22:
|
||||
1e:8b:52:71:09:4e:e3:43:2f:92:45:ea:61:86:06:
|
||||
fe:49:23:c4:18:a7:ef:4c:81:77:8d:ce:a5:1b:80:
|
||||
ad:b0:d1:19:71:68:9e:b7:53:6e:d4:9f:d7:ff:d9:
|
||||
c0:7a:92:8e:04:e9:2b:a4:df:b2:e4:a8:ae:28:da:
|
||||
c8:5a:f2:d0:b6:98:e3:c4:2d:3a:c7:c3:07:b6:32:
|
||||
15:0d:f9:e2:05:77:32:b6:d7:e3:64:b5:8c:c0:83:
|
||||
32:25:7d:7f:ad:88:39:25:68:3f:0f:48:4d:60:67:
|
||||
b9:47:ad:bd:6d:93:73:5c:78:41:d7:db:fa:e9:bf:
|
||||
6b:9a:6b:e0:66:c6:90:3c:da:fb:85:2c:45:32:6c:
|
||||
0f:18:66:6e:42:f7:0f:93:35:4f:3e:d1:1f:a8:fb:
|
||||
18:75:87:19:9a:3a:af:28:28:73:45:9a:87:89:b2:
|
||||
a6:33:1b:25:83:69:9e:75:8c:06:d6:f3:2a:b2:bc:
|
||||
52:64:27:8d:ee:ec:50:88:28:5c:86:6d:8a:92:50:
|
||||
00:10:dd:08:42:7c:0d:5a:f8:2b:a2:d6:df:23:0d:
|
||||
5f:a8:da:c6:ce:d5:c9:f6:10:a4:de:62:0c:9b:29:
|
||||
ca:af
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Key Identifier:
|
||||
FE:74:48:82:19:2C:85:19:EB:55:37:8A:70:DF:94:2C:FA:6B:A9:6B
|
||||
X509v3 Authority Key Identifier:
|
||||
FE:74:48:82:19:2C:85:19:EB:55:37:8A:70:DF:94:2C:FA:6B:A9:6B
|
||||
X509v3 Basic Constraints: critical
|
||||
CA:TRUE
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Signature Value:
|
||||
08:2b:2a:bc:b7:0f:3e:ec:96:b0:78:87:12:a5:f1:d7:0e:96:
|
||||
08:65:34:7d:0a:9b:3d:bd:df:dc:de:3f:5e:0f:57:75:75:a3:
|
||||
fd:a2:68:29:80:5b:ce:1a:ea:0f:7b:96:ab:ea:92:d0:da:07:
|
||||
61:28:32:71:37:d1:3c:6a:ca:e8:f9:9b:80:49:c5:16:40:cc:
|
||||
8d:50:8c:4f:4e:6d:73:7b:3a:55:6b:11:76:e3:68:fd:6f:a0:
|
||||
c8:06:f9:a1:af:28:4d:b9:c5:0d:fd:2c:98:61:7d:22:b6:87:
|
||||
43:2b:62:fc:25:9e:fb:f4:09:24:c1:3c:7f:c7:e8:04:b4:c5:
|
||||
5a:4b:4e:17:5d:7f:38:f1:d4:35:0c:82:bf:20:46:c7:f4:96:
|
||||
8f:12:94:c4:ee:92:e0:5d:09:45:de:a1:40:e5:b4:34:2f:11:
|
||||
fe:72:5f:81:a5:11:24:a5:04:98:e5:07:59:dc:d8:dc:7b:f6:
|
||||
12:ba:8b:d3:cf:dd:de:06:84:23:e7:b3:29:b2:8f:b1:6b:c3:
|
||||
71:ee:da:bc:9e:b5:62:a6:68:cb:ea:49:19:34:6c:29:be:ce:
|
||||
6d:3b:7a:59:28:59:67:83:e9:6d:37:06:fd:29:f7:ce:fc:fc:
|
||||
72:de:23:f5:2b:f6:dc:d2:82:3e:45:bb:e1:ce:14:d7:85:d5:
|
||||
ec:3b:1c:3c
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDHzCCAgegAwIBAgIUZyv8gCefZd1C1++oCv690agtyNowDQYJKoZIhvcNAQEL
|
||||
BQAwHjEcMBoGA1UEAwwTKi5mb28uYmFyLmxvY2FsaG9zdDAgFw0yMzAzMzAxMjM5
|
||||
NTVaGA8yMjAyMDkwMzEyMzk1NVowHjEcMBoGA1UEAwwTKi5mb28uYmFyLmxvY2Fs
|
||||
aG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNnRcGXR4OhGzRq
|
||||
pfoaDNe5Tu+9A49kv+PKUdgiHotScQlO40MvkkXqYYYG/kkjxBin70yBd43OpRuA
|
||||
rbDRGXFonrdTbtSf1//ZwHqSjgTpK6TfsuSorijayFry0LaY48QtOsfDB7YyFQ35
|
||||
4gV3MrbX42S1jMCDMiV9f62IOSVoPw9ITWBnuUetvW2Tc1x4Qdfb+um/a5pr4GbG
|
||||
kDza+4UsRTJsDxhmbkL3D5M1Tz7RH6j7GHWHGZo6rygoc0Wah4mypjMbJYNpnnWM
|
||||
BtbzKrK8UmQnje7sUIgoXIZtipJQABDdCEJ8DVr4K6LW3yMNX6jaxs7VyfYQpN5i
|
||||
DJspyq8CAwEAAaNTMFEwHQYDVR0OBBYEFP50SIIZLIUZ61U3inDflCz6a6lrMB8G
|
||||
A1UdIwQYMBaAFP50SIIZLIUZ61U3inDflCz6a6lrMA8GA1UdEwEB/wQFMAMBAf8w
|
||||
DQYJKoZIhvcNAQELBQADggEBAAgrKry3Dz7slrB4hxKl8dcOlghlNH0Kmz2939ze
|
||||
P14PV3V1o/2iaCmAW84a6g97lqvqktDaB2EoMnE30Txqyuj5m4BJxRZAzI1QjE9O
|
||||
bXN7OlVrEXbjaP1voMgG+aGvKE25xQ39LJhhfSK2h0MrYvwlnvv0CSTBPH/H6AS0
|
||||
xVpLThddfzjx1DUMgr8gRsf0lo8SlMTukuBdCUXeoUDltDQvEf5yX4GlESSlBJjl
|
||||
B1nc2Nx79hK6i9PP3d4GhCPnsymyj7Frw3Hu2ryetWKmaMvqSRk0bCm+zm07elko
|
||||
WWeD6W03Bv0p9878/HLeI/Ur9tzSgj5Fu+HOFNeF1ew7HDw=
|
||||
-----END CERTIFICATE-----
|
||||
5
proxy/config/foo.bar.localhost/server.dhall
Normal file
5
proxy/config/foo.bar.localhost/server.dhall
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
server_name = "*.foo.bar.localhost",
|
||||
certificate = ./server.crt as Text,
|
||||
private_key = ./server.key as Text,
|
||||
}
|
||||
28
proxy/config/foo.bar.localhost/server.key
Normal file
28
proxy/config/foo.bar.localhost/server.key
Normal file
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCjZ0XBl0eDoRs0
|
||||
aqX6GgzXuU7vvQOPZL/jylHYIh6LUnEJTuNDL5JF6mGGBv5JI8QYp+9MgXeNzqUb
|
||||
gK2w0RlxaJ63U27Un9f/2cB6ko4E6Suk37LkqK4o2sha8tC2mOPELTrHwwe2MhUN
|
||||
+eIFdzK21+NktYzAgzIlfX+tiDklaD8PSE1gZ7lHrb1tk3NceEHX2/rpv2uaa+Bm
|
||||
xpA82vuFLEUybA8YZm5C9w+TNU8+0R+o+xh1hxmaOq8oKHNFmoeJsqYzGyWDaZ51
|
||||
jAbW8yqyvFJkJ43u7FCIKFyGbYqSUAAQ3QhCfA1a+Cui1t8jDV+o2sbO1cn2EKTe
|
||||
YgybKcqvAgMBAAECggEACcd9ZwqPzcKxyXiCgSmOYn53kkmjaIzCjKQaV/z+wkNi
|
||||
6FFY1UoH6oqOX3lLPjoOP92COy6RQjUtMAfT1Cu1L8BLE2uLgt0jjgGVs+lkMKYM
|
||||
pfwNDXD6pjQBOhjHrxcO7XDL0JJWcVCBAMp76qMb1D+u+poSqg1rcqrNeZVO3s6n
|
||||
ot4aejb+hDEB8t4ytpDnqULaPvnDmlc5WvVpS8qbGTRiq8DSe5RzEQZp7WHR9Una
|
||||
0o/rQPu+RiH2+7CesQugg9bc3iaW83DbJjLuODU/4Au/aU/7I0giV8T89UIvtXDl
|
||||
JzyVDRJNr1qPabZ/H2CFRkfHKovNRpJDEX48VuSR3QKBgQDmr61HA6rRh6zmmehd
|
||||
V1mroKb9UCR/edBklBSsO2kvWMHPtFEwlszebydcrJa2GwbE37NjKZwkEp1Q/mIk
|
||||
yX2mjd629j62vzjOejFrW22YOX2LN2cK2Ns9c5T0qnX7ttxy8lw3dE7uU9Y42X8E
|
||||
Wxm5yIiXImgxIaxCpceR4lzdqwKBgQC1VYUSZcxXIRNjyd98vcD7Ai3zTai4wO3k
|
||||
WC+Myu2DZr1ZhmY2N0M5b5UUsTL6yOt9fKgqMz3Ww21/zweXx91ts6XmygXIj5ZA
|
||||
7TyQxPE/PGzG6Olg5o00L//68P9jSBz9HgRWdRtxyJ8NWOUTTGpqA5dKjEj7tia/
|
||||
E/QcErSbDQKBgAgNug7wodYO1op2dRZNJmRHh4zwb1XD+vKH+PDKYjG09484zFzV
|
||||
5vEdEFK788cHyoS1Cp47pafcvoFFYEfIgQp/iXb5wda/dkw/F9qXpovZ9fgWRxKp
|
||||
332Vu22PRe8zwx6AN5f4B4lqg+AYN8b/JzbFOX+NQ/XzJwBsqTr+nB9hAoGBAIch
|
||||
McdiAQK07UQhvd+xcEwddayoJKF5dE4DwXuEBbc0Ksq6MxUX3YrBsjD3U+w7KfIb
|
||||
oR3BjcWrYMArwZbEJCiKBYmU5vZsuiWsJMQlXzomh1E7ZB8H8BYB5xpT2Z1cse2W
|
||||
Htlm74q9XHmP0zWsbmiOQIIXRJP/S6R89B6vedNJAoGBAJOjRfwepnFpIVXG0waS
|
||||
S1zavMQZvDsJcvNhedyi34ui5XXi79w+uc13xoFTilhG8DS+tOnw/LsDTP8NeLKv
|
||||
yENcF/zSHuC4GJJjxoJ+SPlaW+mlofsoCT7zRGRVG27xS6jOwo5/7fYg0aELsq2o
|
||||
oS/TVaWFJKVtJW64vHdGzMnx
|
||||
-----END PRIVATE KEY-----
|
||||
77
proxy/config/neon.localhost/server.crt
Normal file
77
proxy/config/neon.localhost/server.crt
Normal file
@@ -0,0 +1,77 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number:
|
||||
1b:91:d6:a3:a3:1b:c1:47:b3:76:16:a2:43:64:3b:63:61:0d:0c:c8
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: CN = *.neon.localhost
|
||||
Validity
|
||||
Not Before: Mar 30 13:19:00 2023 GMT
|
||||
Not After : Sep 3 13:19:00 2202 GMT
|
||||
Subject: CN = *.neon.localhost
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:ab:27:17:8b:71:a5:08:65:ec:46:58:69:3d:7d:
|
||||
b7:91:34:33:3a:50:5c:27:91:34:70:fe:2c:81:fc:
|
||||
aa:f2:32:60:b3:49:ca:c1:c8:fb:76:73:97:ac:e9:
|
||||
ff:20:4a:73:48:62:fa:65:d3:81:65:1b:cc:78:00:
|
||||
6d:a8:32:8b:ff:61:3c:8b:a2:23:61:de:e3:b4:5f:
|
||||
cd:ce:7e:ce:05:49:5b:64:81:42:74:81:49:4a:5c:
|
||||
3a:f0:d9:40:2d:42:7d:ef:db:b9:d3:54:a5:11:52:
|
||||
0b:23:65:fd:c1:5e:58:f7:98:9c:ba:3d:9a:f9:a2:
|
||||
50:0c:c4:c8:bf:63:66:aa:e3:29:fe:40:ae:13:8c:
|
||||
18:af:20:24:41:63:3e:1d:af:cd:91:32:fa:b9:26:
|
||||
96:fb:35:12:1c:62:58:93:33:d2:2c:76:08:f9:c4:
|
||||
07:ef:fc:6f:eb:ea:c8:81:5d:d8:73:0a:05:47:79:
|
||||
52:b3:24:34:08:c3:b6:a0:aa:af:de:8b:62:f9:6f:
|
||||
3a:8f:eb:07:85:ef:2b:de:f7:21:69:7a:63:17:27:
|
||||
4a:88:b5:4c:e7:52:73:09:10:c6:ca:eb:f0:c8:31:
|
||||
cc:d4:59:d6:64:82:ac:ae:96:69:18:5e:19:17:5d:
|
||||
9b:86:39:36:a1:9f:90:34:45:73:9b:43:a2:b0:d3:
|
||||
8b:e1
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Key Identifier:
|
||||
E3:8E:E8:BF:5E:72:36:0A:6D:7F:BE:AF:68:38:A7:CE:71:15:CE:14
|
||||
X509v3 Authority Key Identifier:
|
||||
E3:8E:E8:BF:5E:72:36:0A:6D:7F:BE:AF:68:38:A7:CE:71:15:CE:14
|
||||
X509v3 Basic Constraints: critical
|
||||
CA:TRUE
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Signature Value:
|
||||
69:23:54:9d:eb:4c:57:f5:cf:8d:5c:d3:f8:2e:65:0b:f1:b8:
|
||||
8e:a8:ef:67:dd:89:96:8d:df:f1:9b:36:3a:49:0d:55:dc:07:
|
||||
eb:c5:e7:c8:73:12:02:6a:02:d3:ca:92:63:f0:61:4b:8a:2a:
|
||||
32:c2:23:c2:53:ee:33:6b:eb:9f:e5:f4:df:78:55:bf:d5:86:
|
||||
1e:e5:a8:90:e2:df:d7:c2:b8:63:27:a7:2d:ba:43:34:d3:45:
|
||||
e0:94:53:0a:26:fb:66:ac:c3:96:76:c3:45:a1:ae:d6:30:e0:
|
||||
b6:c0:a6:d1:8e:51:c7:56:fb:ed:5c:04:a2:66:b9:74:c6:6d:
|
||||
ef:1e:9e:9a:58:7b:fc:e0:1c:94:fc:17:df:5b:70:e7:cd:f9:
|
||||
22:49:3d:59:83:8e:c3:bf:bc:3b:39:68:9e:5a:34:88:1a:61:
|
||||
f7:53:ac:86:de:76:85:75:f6:b7:86:3f:20:4b:98:63:97:03:
|
||||
8b:29:37:32:2c:c1:9a:65:a2:58:17:f2:7b:79:e7:ee:6a:33:
|
||||
5b:d0:bd:af:04:dd:02:43:98:a7:e9:0f:35:cb:c0:9d:a6:95:
|
||||
bf:98:57:4d:cf:b8:a9:bb:de:0c:4d:51:93:df:62:f6:20:bf:
|
||||
61:27:7d:2c:be:14:48:5d:d1:75:f9:cb:d9:b3:0a:2b:de:ea:
|
||||
2a:4b:9e:c0
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDGTCCAgGgAwIBAgIUG5HWo6MbwUezdhaiQ2Q7Y2ENDMgwDQYJKoZIhvcNAQEL
|
||||
BQAwGzEZMBcGA1UEAwwQKi5uZW9uLmxvY2FsaG9zdDAgFw0yMzAzMzAxMzE5MDBa
|
||||
GA8yMjAyMDkwMzEzMTkwMFowGzEZMBcGA1UEAwwQKi5uZW9uLmxvY2FsaG9zdDCC
|
||||
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKsnF4txpQhl7EZYaT19t5E0
|
||||
MzpQXCeRNHD+LIH8qvIyYLNJysHI+3Zzl6zp/yBKc0hi+mXTgWUbzHgAbagyi/9h
|
||||
PIuiI2He47Rfzc5+zgVJW2SBQnSBSUpcOvDZQC1Cfe/budNUpRFSCyNl/cFeWPeY
|
||||
nLo9mvmiUAzEyL9jZqrjKf5ArhOMGK8gJEFjPh2vzZEy+rkmlvs1EhxiWJMz0ix2
|
||||
CPnEB+/8b+vqyIFd2HMKBUd5UrMkNAjDtqCqr96LYvlvOo/rB4XvK973IWl6Yxcn
|
||||
Soi1TOdScwkQxsrr8MgxzNRZ1mSCrK6WaRheGRddm4Y5NqGfkDRFc5tDorDTi+EC
|
||||
AwEAAaNTMFEwHQYDVR0OBBYEFOOO6L9ecjYKbX++r2g4p85xFc4UMB8GA1UdIwQY
|
||||
MBaAFOOO6L9ecjYKbX++r2g4p85xFc4UMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
|
||||
hvcNAQELBQADggEBAGkjVJ3rTFf1z41c0/guZQvxuI6o72fdiZaN3/GbNjpJDVXc
|
||||
B+vF58hzEgJqAtPKkmPwYUuKKjLCI8JT7jNr65/l9N94Vb/Vhh7lqJDi39fCuGMn
|
||||
py26QzTTReCUUwom+2asw5Z2w0WhrtYw4LbAptGOUcdW++1cBKJmuXTGbe8enppY
|
||||
e/zgHJT8F99bcOfN+SJJPVmDjsO/vDs5aJ5aNIgaYfdTrIbedoV19reGPyBLmGOX
|
||||
A4spNzIswZplolgX8nt55+5qM1vQva8E3QJDmKfpDzXLwJ2mlb+YV03PuKm73gxN
|
||||
UZPfYvYgv2EnfSy+FEhd0XX5y9mzCive6ipLnsA=
|
||||
-----END CERTIFICATE-----
|
||||
5
proxy/config/neon.localhost/server.dhall
Normal file
5
proxy/config/neon.localhost/server.dhall
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
server_name = "*.neon.localhost",
|
||||
certificate = ./server.crt as Text,
|
||||
private_key = ./server.key as Text,
|
||||
}
|
||||
28
proxy/config/neon.localhost/server.key
Normal file
28
proxy/config/neon.localhost/server.key
Normal file
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCrJxeLcaUIZexG
|
||||
WGk9fbeRNDM6UFwnkTRw/iyB/KryMmCzScrByPt2c5es6f8gSnNIYvpl04FlG8x4
|
||||
AG2oMov/YTyLoiNh3uO0X83Ofs4FSVtkgUJ0gUlKXDrw2UAtQn3v27nTVKURUgsj
|
||||
Zf3BXlj3mJy6PZr5olAMxMi/Y2aq4yn+QK4TjBivICRBYz4dr82RMvq5Jpb7NRIc
|
||||
YliTM9Isdgj5xAfv/G/r6siBXdhzCgVHeVKzJDQIw7agqq/ei2L5bzqP6weF7yve
|
||||
9yFpemMXJ0qItUznUnMJEMbK6/DIMczUWdZkgqyulmkYXhkXXZuGOTahn5A0RXOb
|
||||
Q6Kw04vhAgMBAAECggEADrLZw8urwlqL0x1uqa2X9pbGu4BWmb36Wfs03qj7aWId
|
||||
ieg8IIOz4jVagQAg5/4Hg9+e5OB9jAMPfqgoGA+B6cRzta45XwNhsjD0H4LRC1qE
|
||||
cyTityy58EfsIUPBzjaX/Yx08LWj7iaJ9wKgVgYAmqr28suto+NmVTe6jIKV46EL
|
||||
bWmnU0dySOa43ukdhkvQN+FG3hL4iIl+mZ5aTVY8dz885sxYdrKOyrzMREAvHFW6
|
||||
m01fWwgbdiMfR2Gu2ZWmvom4+PiE8EES8/Cpct4/E27SFLr3pdB+voIBSh6kotF9
|
||||
w0dNqnK1dyIC89gxhcH/PO4rC6uKPM68ZezBsqHZ3QKBgQDMB54bMbcVNK/92nRV
|
||||
xtM8sk567oAeDwL7VcMq35vmwZU1OcjPg/QswIIZNIx46SXO8a668Wn6OLZYq4dR
|
||||
FGBWpsMHbQSEdyurYY2bqi5tK5dnKiuCqNmTTtxPA2QgC+PdDcTlJ2FI/RmCeODM
|
||||
GUcKJd0FyR5BNy8TPM31kFs7zwKBgQDWv6A4cpKzzfY7hf/iOcgmgyipPfXBAdCE
|
||||
6w6HAEU5JKJDtxIC3roosxOVbrqCMGqPWKCkQvzOr7d9Ok5fYk4WF+qM67xxdzHa
|
||||
KzmE2+PKDsWBejxjnIMBtDKBkWhOU5/bg/HLDv4RPNwn7f0MjxFpxzYuq3q/dIPN
|
||||
TcZthbU5TwKBgQCJj1FAEILZ304RH2p0MrtVHvre01K58XEXN7mAfIbGTBpnanBD
|
||||
yTmlup18lPtowfjlz/j4va+wLvByVCPFvLE/euvfY9c54Icm43zwSQtIO622tq3j
|
||||
SCh5sx/CfgzRtnKJJbFstuJWrZ63YvxdX2WQJ/se3Xxyh9xLYiGSwSNh7QKBgDFO
|
||||
/rL3W8f9WrSAKCkBq3tsUkHKAEu45vAeKM/GuB5O0xNJTdFq4sPFmpGNQzXxeAZC
|
||||
C2CsIPA0WKVgZe5w3A0moKyK1FIZVFEL68Ed3Efg7Gi2cHdO0KXrgk1N3e1eNi5p
|
||||
NXOylZPPrZ1df+UKVK09GKvOo/iiAEF7wjwTn3DxAoGBAK1iTDV+HrGyxCi2PcoK
|
||||
yyFCB2QEFw5vvMMMu5lvRjaI9r+igEg1Y8DWhXpUb0hsXnTV192dwhqmB+NYn7Yz
|
||||
xwlFeKolv+j+5H+IQ4vmEleOlaBLGBH/lAdCcJ0bGcKHHRP+chF6En2tOTk45Gai
|
||||
4gsDafbyi89fJ/5EoLGRYMe/
|
||||
-----END PRIVATE KEY-----
|
||||
7
proxy/config/servers.dhall
Normal file
7
proxy/config/servers.dhall
Normal file
@@ -0,0 +1,7 @@
|
||||
let Server = { server_name : Text, certificate : Text, private_key : Text }
|
||||
|
||||
let servers
|
||||
: List Server
|
||||
= [ ./foo.bar.localhost/server.dhall, ./neon.localhost/server.dhall ]
|
||||
|
||||
in servers
|
||||
@@ -18,13 +18,6 @@ pub enum ClientCredsParseError {
|
||||
)]
|
||||
InconsistentProjectNames { domain: String, option: String },
|
||||
|
||||
#[error(
|
||||
"SNI ('{}') inconsistently formatted with respect to common name ('{}'). \
|
||||
SNI should be formatted as '<project-name>.{}'.",
|
||||
.sni, .cn, .cn,
|
||||
)]
|
||||
InconsistentSni { sni: String, cn: String },
|
||||
|
||||
#[error("Project name ('{0}') must contain only alphanumeric characters and hyphen.")]
|
||||
MalformedProjectName(String),
|
||||
}
|
||||
@@ -51,7 +44,6 @@ impl<'a> ClientCredentials<'a> {
|
||||
pub fn parse(
|
||||
params: &'a StartupMessageParams,
|
||||
sni: Option<&str>,
|
||||
common_name: Option<&str>,
|
||||
) -> Result<Self, ClientCredsParseError> {
|
||||
use ClientCredsParseError::*;
|
||||
|
||||
@@ -67,18 +59,10 @@ impl<'a> ClientCredentials<'a> {
|
||||
});
|
||||
|
||||
// Alternative project name is in fact a subdomain from SNI.
|
||||
// NOTE: we do not consider SNI if `common_name` is missing.
|
||||
let project_domain = sni
|
||||
.zip(common_name)
|
||||
.map(|(sni, cn)| {
|
||||
subdomain_from_sni(sni, cn)
|
||||
.ok_or_else(|| InconsistentSni {
|
||||
sni: sni.into(),
|
||||
cn: cn.into(),
|
||||
})
|
||||
.map(Cow::<'static, str>::Owned)
|
||||
})
|
||||
.transpose()?;
|
||||
let project_domain = sni.and_then(|sni| {
|
||||
let (domain, _) = sni.split_once('.')?;
|
||||
Some(Cow::from(domain.to_owned()))
|
||||
});
|
||||
|
||||
let project = match (project_option, project_domain) {
|
||||
// Invariant: if we have both project name variants, they should match.
|
||||
@@ -106,12 +90,6 @@ fn project_name_valid(name: &str) -> bool {
|
||||
name.chars().all(|c| c.is_alphanumeric() || c == '-')
|
||||
}
|
||||
|
||||
fn subdomain_from_sni(sni: &str, common_name: &str) -> Option<String> {
|
||||
sni.strip_suffix(common_name)?
|
||||
.strip_suffix('.')
|
||||
.map(str::to_owned)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -122,7 +100,7 @@ mod tests {
|
||||
// According to postgresql, only `user` should be required.
|
||||
let options = StartupMessageParams::new([("user", "john_doe")]);
|
||||
|
||||
let creds = ClientCredentials::parse(&options, None, None)?;
|
||||
let creds = ClientCredentials::parse(&options, None)?;
|
||||
assert_eq!(creds.user, "john_doe");
|
||||
assert_eq!(creds.project, None);
|
||||
|
||||
@@ -137,7 +115,7 @@ mod tests {
|
||||
("foo", "bar"), // should be ignored
|
||||
]);
|
||||
|
||||
let creds = ClientCredentials::parse(&options, None, None)?;
|
||||
let creds = ClientCredentials::parse(&options, None)?;
|
||||
assert_eq!(creds.user, "john_doe");
|
||||
assert_eq!(creds.project, None);
|
||||
|
||||
@@ -149,9 +127,8 @@ mod tests {
|
||||
let options = StartupMessageParams::new([("user", "john_doe")]);
|
||||
|
||||
let sni = Some("foo.localhost");
|
||||
let common_name = Some("localhost");
|
||||
|
||||
let creds = ClientCredentials::parse(&options, sni, common_name)?;
|
||||
let creds = ClientCredentials::parse(&options, sni)?;
|
||||
assert_eq!(creds.user, "john_doe");
|
||||
assert_eq!(creds.project.as_deref(), Some("foo"));
|
||||
|
||||
@@ -165,7 +142,7 @@ mod tests {
|
||||
("options", "-ckey=1 project=bar -c geqo=off"),
|
||||
]);
|
||||
|
||||
let creds = ClientCredentials::parse(&options, None, None)?;
|
||||
let creds = ClientCredentials::parse(&options, None)?;
|
||||
assert_eq!(creds.user, "john_doe");
|
||||
assert_eq!(creds.project.as_deref(), Some("bar"));
|
||||
|
||||
@@ -177,9 +154,8 @@ mod tests {
|
||||
let options = StartupMessageParams::new([("user", "john_doe"), ("options", "project=baz")]);
|
||||
|
||||
let sni = Some("baz.localhost");
|
||||
let common_name = Some("localhost");
|
||||
|
||||
let creds = ClientCredentials::parse(&options, sni, common_name)?;
|
||||
let creds = ClientCredentials::parse(&options, sni)?;
|
||||
assert_eq!(creds.user, "john_doe");
|
||||
assert_eq!(creds.project.as_deref(), Some("baz"));
|
||||
|
||||
@@ -192,9 +168,8 @@ mod tests {
|
||||
StartupMessageParams::new([("user", "john_doe"), ("options", "project=first")]);
|
||||
|
||||
let sni = Some("second.localhost");
|
||||
let common_name = Some("localhost");
|
||||
|
||||
let err = ClientCredentials::parse(&options, sni, common_name).expect_err("should fail");
|
||||
let err = ClientCredentials::parse(&options, sni).expect_err("should fail");
|
||||
match err {
|
||||
InconsistentProjectNames { domain, option } => {
|
||||
assert_eq!(option, "first");
|
||||
@@ -203,21 +178,4 @@ mod tests {
|
||||
_ => panic!("bad error: {err:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_inconsistent_sni() {
|
||||
let options = StartupMessageParams::new([("user", "john_doe")]);
|
||||
|
||||
let sni = Some("project.localhost");
|
||||
let common_name = Some("example.com");
|
||||
|
||||
let err = ClientCredentials::parse(&options, sni, common_name).expect_err("should fail");
|
||||
match err {
|
||||
InconsistentSni { sni, cn } => {
|
||||
assert_eq!(sni, "project.localhost");
|
||||
assert_eq!(cn, "example.com");
|
||||
}
|
||||
_ => panic!("bad error: {err:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
312
proxy/src/certs.rs
Normal file
312
proxy/src/certs.rs
Normal file
@@ -0,0 +1,312 @@
|
||||
use rustls::{
|
||||
server::{ClientHello, ResolvesServerCert},
|
||||
sign::CertifiedKey,
|
||||
};
|
||||
use std::{collections::BTreeMap, io, ops::Bound, sync::Arc};
|
||||
use tracing::{info, warn};
|
||||
|
||||
/// App-level configuration structs for TLS certificates.
|
||||
pub mod config {
|
||||
use super::*;
|
||||
use serde::{de, Deserialize};
|
||||
use std::path::Path;
|
||||
|
||||
/// Collection of TLS-related configurations of virtual proxy servers.
|
||||
#[derive(Debug, Default, Clone, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct TlsServers(pub Vec<TlsServer>);
|
||||
|
||||
impl TlsServers {
|
||||
/// Load [`Self`] config from a file.
|
||||
pub fn from_config_file(path: impl AsRef<Path>) -> anyhow::Result<Self> {
|
||||
info!(path = %path.as_ref().display(), "loading TLS servers config file");
|
||||
let config = serde_dhall::from_file(path).parse()?;
|
||||
Ok(config)
|
||||
}
|
||||
}
|
||||
|
||||
/// This lets us merge multiple configs into one (semigroup).
|
||||
impl FromIterator<Self> for TlsServers {
|
||||
fn from_iter<T: IntoIterator<Item = Self>>(iter: T) -> Self {
|
||||
Self(iter.into_iter().flat_map(|xs| xs.0).collect())
|
||||
}
|
||||
}
|
||||
|
||||
/// Helps deserialize certificate chain from a string.
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct TlsCert(
|
||||
/// The wrapped rustls certificate.
|
||||
#[serde(deserialize_with = "deserialize_certs")]
|
||||
pub Vec<rustls::Certificate>,
|
||||
);
|
||||
|
||||
fn deserialize_certs<'de, D>(des: D) -> Result<Vec<rustls::Certificate>, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let text = String::deserialize(des)?;
|
||||
parse_certs(&mut text.as_bytes()).map_err(de::Error::custom)
|
||||
}
|
||||
|
||||
/// Helps deserialize private key from a string.
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct TlsKey(
|
||||
/// The wrapped rustls private key.
|
||||
#[serde(deserialize_with = "deserialize_key")]
|
||||
pub rustls::PrivateKey,
|
||||
);
|
||||
|
||||
fn deserialize_key<'de, D>(des: D) -> Result<rustls::PrivateKey, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let text = String::deserialize(des)?;
|
||||
parse_key(&mut text.as_bytes()).map_err(de::Error::custom)
|
||||
}
|
||||
|
||||
/// Represents TLS config of a single virtual proxy server.
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct TlsServer {
|
||||
/// Proxy server's certificate chain.
|
||||
pub certificate: TlsCert,
|
||||
/// Proxy server's private key.
|
||||
pub private_key: TlsKey,
|
||||
}
|
||||
|
||||
impl TlsServer {
|
||||
pub fn into_certified_key(
|
||||
self,
|
||||
) -> Result<rustls::sign::CertifiedKey, rustls::sign::SignError> {
|
||||
Ok(rustls::sign::CertifiedKey::new(
|
||||
self.certificate.0,
|
||||
rustls::sign::any_supported_type(&self.private_key.0)?,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse TLS certificate chain from a byte buffer.
|
||||
fn parse_certs(buf: &mut impl io::BufRead) -> io::Result<Vec<rustls::Certificate>> {
|
||||
let chain = rustls_pemfile::certs(buf)?
|
||||
.into_iter()
|
||||
.map(rustls::Certificate)
|
||||
.collect();
|
||||
|
||||
Ok(chain)
|
||||
}
|
||||
|
||||
/// Parse exactly one TLS private key from a byte buffer.
|
||||
fn parse_key(buf: &mut impl io::BufRead) -> io::Result<rustls::PrivateKey> {
|
||||
let mut keys = rustls_pemfile::pkcs8_private_keys(buf)?;
|
||||
|
||||
// We expect to see only 1 key.
|
||||
if keys.len() != 1 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"there should be exactly one TLS key in buffer",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(rustls::PrivateKey(keys.pop().unwrap()))
|
||||
}
|
||||
|
||||
/// Extract domain names from a certificate: first CN, then SANs.
|
||||
/// Further reading: <https://www.rfc-editor.org/rfc/rfc4985>.
|
||||
fn certificate_names(cert: &rustls::Certificate) -> anyhow::Result<Vec<String>> {
|
||||
use x509_parser::{extensions::GeneralName, x509::AttributeTypeAndValue};
|
||||
|
||||
let get_dns_name = |gn: &GeneralName| match gn {
|
||||
GeneralName::DNSName(name) => Some(name.to_string()),
|
||||
_other => None,
|
||||
};
|
||||
|
||||
let get_common_name = |attr: &AttributeTypeAndValue| {
|
||||
// There really shouldn't be anything but string here.
|
||||
attr.attr_value().as_string().expect("bad CN attribute")
|
||||
};
|
||||
|
||||
let (rest, cert) = x509_parser::parse_x509_certificate(cert.0.as_ref())?;
|
||||
anyhow::ensure!(rest.is_empty(), "excessive bytes in DER certificate");
|
||||
|
||||
// Extract CN, Common Name.
|
||||
let mut names: Vec<String> = cert
|
||||
.subject()
|
||||
.iter_common_name()
|
||||
.map(get_common_name)
|
||||
.collect();
|
||||
|
||||
// Now append SANs, Subject Alternative Names, if any.
|
||||
if let Some(extension) = cert.subject_alternative_name()? {
|
||||
let alt_names = &extension.value.general_names;
|
||||
names.extend(alt_names.iter().filter_map(get_dns_name));
|
||||
}
|
||||
|
||||
Ok(names)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct GlobMapBuilder<V> {
|
||||
builder: globset::GlobSetBuilder,
|
||||
values: BTreeMap<usize, V>,
|
||||
}
|
||||
|
||||
impl<V> GlobMapBuilder<V> {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
builder: globset::GlobSetBuilder::new(),
|
||||
values: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn add(&mut self, globs: impl IntoIterator<Item = globset::Glob>, value: V) -> &mut Self {
|
||||
let mut cnt = 0;
|
||||
for glob in globs {
|
||||
self.builder.add(glob);
|
||||
cnt += 1;
|
||||
}
|
||||
|
||||
if cnt > 0 {
|
||||
let offset = self.values.last_key_value().map(|(k, _)| *k).unwrap_or(0);
|
||||
self.values.insert(offset + cnt, value);
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn build(self) -> Result<GlobMap<V>, globset::Error> {
|
||||
Ok(GlobMap {
|
||||
set: self.builder.build()?,
|
||||
values: self.values,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Maps a set of matching globs to an arbitrary value.
|
||||
/// See the tests below in case this description doesn't help.
|
||||
#[derive(Debug)]
|
||||
struct GlobMap<V> {
|
||||
/// An ordered set of all loaded globs.
|
||||
set: globset::GlobSet,
|
||||
/// Store single value per range of globs.
|
||||
values: BTreeMap<usize, V>,
|
||||
}
|
||||
|
||||
impl<V> GlobMap<V> {
|
||||
fn query(&self, text: &str) -> Vec<&V> {
|
||||
let indices = self.set.matches(text);
|
||||
let mut res = Vec::with_capacity(indices.len());
|
||||
|
||||
for i in indices {
|
||||
let mut range = self.values.range((Bound::Excluded(i), Bound::Unbounded));
|
||||
let (_, value) = range.next().expect("invariant: entry must exist");
|
||||
res.push(value);
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CertResolverEntry {
|
||||
pub raw: Arc<rustls::sign::CertifiedKey>,
|
||||
pub names: Vec<String>,
|
||||
}
|
||||
|
||||
pub struct CertResolver {
|
||||
storage: GlobMap<CertResolverEntry>,
|
||||
}
|
||||
|
||||
impl CertResolver {
|
||||
pub fn new(config: config::TlsServers) -> anyhow::Result<Self> {
|
||||
let mut builder = GlobMapBuilder::new();
|
||||
for server in config.0 {
|
||||
let Some(cert) = server.certificate.0.first() else {
|
||||
warn!("found empty certificate, skipping");
|
||||
continue;
|
||||
};
|
||||
|
||||
let names = certificate_names(cert)?;
|
||||
let globs = names
|
||||
.iter()
|
||||
.map(|s| globset::Glob::new(s))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
info!(?names, "loading TLS certificate");
|
||||
let entry = CertResolverEntry {
|
||||
raw: Arc::new(server.into_certified_key()?),
|
||||
names,
|
||||
};
|
||||
|
||||
builder.add(globs, entry);
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
storage: builder.build()?,
|
||||
})
|
||||
}
|
||||
|
||||
#[tracing::instrument(name = "resolve_tls_cert", fields(%server_name), skip_all)]
|
||||
pub fn resolve_raw(&self, server_name: &str) -> Option<&CertResolverEntry> {
|
||||
info!("trying to resolve TLS certificate");
|
||||
let entries = self.storage.query(server_name);
|
||||
info!("found {} matching entries", entries.len());
|
||||
entries.first().copied()
|
||||
}
|
||||
}
|
||||
|
||||
impl ResolvesServerCert for CertResolver {
|
||||
fn resolve(&self, message: ClientHello) -> Option<Arc<CertifiedKey>> {
|
||||
let name = message.server_name()?;
|
||||
self.resolve_raw(name).map(|entry| entry.raw.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use globset::Glob;
|
||||
|
||||
#[test]
|
||||
fn check_glob_map_basic() -> anyhow::Result<()> {
|
||||
let mut builder = GlobMapBuilder::new();
|
||||
builder
|
||||
.add([Glob::new("*.localhost")?], 0)
|
||||
.add([Glob::new("bar.localhost")?], 1)
|
||||
.add([Glob::new("*.foo.localhost")?], 2);
|
||||
|
||||
let map = builder.build()?;
|
||||
|
||||
assert!(map.query("random").is_empty());
|
||||
assert!(map.query("localhost").is_empty());
|
||||
assert_eq!(map.query("foo.localhost"), [&0]);
|
||||
assert_eq!(map.query("bar.localhost"), [&0, &1]);
|
||||
assert_eq!(map.query("project.foo.localhost"), [&0, &2]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_glob_map() -> anyhow::Result<()> {
|
||||
let mut builder = GlobMapBuilder::new();
|
||||
builder
|
||||
.add(
|
||||
[
|
||||
Glob::new("*.neon.tech")?,
|
||||
Glob::new("*.neon.internal.tech")?,
|
||||
],
|
||||
"neon",
|
||||
)
|
||||
.add([Glob::new("*.localhost")?], "mock");
|
||||
|
||||
let map = builder.build()?;
|
||||
|
||||
assert!(map.query("random").is_empty());
|
||||
assert!(map.query("localhost").is_empty());
|
||||
assert_eq!(map.query("ep-1.neon.tech"), [&"neon"]);
|
||||
assert_eq!(map.query("ep-1.neon.internal.tech"), [&"neon"]);
|
||||
assert_eq!(map.query("ep-1.foo.localhost"), [&"mock"]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::auth;
|
||||
use anyhow::{bail, ensure, Context};
|
||||
use crate::{auth, certs};
|
||||
use anyhow::{bail, Context};
|
||||
use std::{str::FromStr, sync::Arc, time::Duration};
|
||||
|
||||
pub struct ProxyConfig {
|
||||
@@ -16,7 +16,6 @@ pub struct MetricCollectionConfig {
|
||||
|
||||
pub struct TlsConfig {
|
||||
pub config: Arc<rustls::ServerConfig>,
|
||||
pub common_name: Option<String>,
|
||||
}
|
||||
|
||||
impl TlsConfig {
|
||||
@@ -25,55 +24,22 @@ impl TlsConfig {
|
||||
}
|
||||
}
|
||||
|
||||
/// Configure TLS for the main endpoint.
|
||||
pub fn configure_tls(key_path: &str, cert_path: &str) -> anyhow::Result<TlsConfig> {
|
||||
let key = {
|
||||
let key_bytes = std::fs::read(key_path).context("TLS key file")?;
|
||||
let mut keys = rustls_pemfile::pkcs8_private_keys(&mut &key_bytes[..])
|
||||
.context(format!("Failed to read TLS keys at '{key_path}'"))?;
|
||||
impl TlsConfig {
|
||||
pub fn new(resolver: certs::CertResolver) -> anyhow::Result<Self> {
|
||||
let rustls_config = rustls::ServerConfig::builder()
|
||||
.with_safe_default_cipher_suites()
|
||||
.with_safe_default_kx_groups()
|
||||
// allow TLS 1.2 to be compatible with older client libraries
|
||||
.with_protocol_versions(&[&rustls::version::TLS13, &rustls::version::TLS12])?
|
||||
.with_no_client_auth()
|
||||
.with_cert_resolver(Arc::new(resolver));
|
||||
|
||||
ensure!(keys.len() == 1, "keys.len() = {} (should be 1)", keys.len());
|
||||
keys.pop().map(rustls::PrivateKey).unwrap()
|
||||
};
|
||||
let config = TlsConfig {
|
||||
config: Arc::new(rustls_config),
|
||||
};
|
||||
|
||||
let cert_chain_bytes = std::fs::read(cert_path)
|
||||
.context(format!("Failed to read TLS cert file at '{cert_path}.'"))?;
|
||||
|
||||
let cert_chain = {
|
||||
rustls_pemfile::certs(&mut &cert_chain_bytes[..])
|
||||
.context(format!(
|
||||
"Failed to read TLS certificate chain from bytes from file at '{cert_path}'."
|
||||
))?
|
||||
.into_iter()
|
||||
.map(rustls::Certificate)
|
||||
.collect()
|
||||
};
|
||||
|
||||
let config = rustls::ServerConfig::builder()
|
||||
.with_safe_default_cipher_suites()
|
||||
.with_safe_default_kx_groups()
|
||||
// allow TLS 1.2 to be compatible with older client libraries
|
||||
.with_protocol_versions(&[&rustls::version::TLS13, &rustls::version::TLS12])?
|
||||
.with_no_client_auth()
|
||||
.with_single_cert(cert_chain, key)?
|
||||
.into();
|
||||
|
||||
// determine common name from tls-cert (-c server.crt param).
|
||||
// used in asserting project name formatting invariant.
|
||||
let common_name = {
|
||||
let pem = x509_parser::pem::parse_x509_pem(&cert_chain_bytes)
|
||||
.context(format!(
|
||||
"Failed to parse PEM object from bytes from file at '{cert_path}'."
|
||||
))?
|
||||
.1;
|
||||
let common_name = pem.parse_x509()?.subject().to_string();
|
||||
common_name.strip_prefix("CN=*.").map(|s| s.to_string())
|
||||
};
|
||||
|
||||
Ok(TlsConfig {
|
||||
config,
|
||||
common_name,
|
||||
})
|
||||
Ok(config)
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper for cmdline cache options parsing.
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
mod auth;
|
||||
mod cache;
|
||||
mod cancellation;
|
||||
mod certs;
|
||||
mod compute;
|
||||
mod config;
|
||||
mod console;
|
||||
@@ -23,10 +24,12 @@ mod url;
|
||||
mod waiters;
|
||||
|
||||
use anyhow::{bail, Context};
|
||||
use auth::BackendType;
|
||||
use certs::config::TlsServers;
|
||||
use clap::{self, Arg};
|
||||
use config::ProxyConfig;
|
||||
use config::{MetricCollectionConfig, ProxyConfig, TlsConfig};
|
||||
use futures::FutureExt;
|
||||
use std::{borrow::Cow, future::Future, net::SocketAddr};
|
||||
use std::{borrow::Cow, future::Future, net::SocketAddr, path::PathBuf};
|
||||
use tokio::{net::TcpListener, task::JoinError};
|
||||
use tracing::{info, warn};
|
||||
use utils::{project_git_version, sentry_init::init_sentry};
|
||||
@@ -126,23 +129,34 @@ async fn handle_signals() -> anyhow::Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
/// ProxyConfig is created at proxy startup, and lives forever.
|
||||
fn build_config(args: &clap::ArgMatches) -> anyhow::Result<&'static ProxyConfig> {
|
||||
let tls_config = match (
|
||||
args.get_one::<String>("tls-key"),
|
||||
args.get_one::<String>("tls-cert"),
|
||||
) {
|
||||
(Some(key_path), Some(cert_path)) => Some(config::configure_tls(key_path, cert_path)?),
|
||||
(None, None) => None,
|
||||
fn build_tls_config(args: &clap::ArgMatches) -> anyhow::Result<Option<TlsConfig>> {
|
||||
let tls_config = args.get_one::<PathBuf>("tls-config");
|
||||
let main = tls_config.map(TlsServers::from_config_file).transpose()?;
|
||||
|
||||
let tls_cert = args.get_one::<PathBuf>("tls-cert");
|
||||
let tls_key = args.get_one::<PathBuf>("tls-key");
|
||||
|
||||
let _aux = match (tls_cert, tls_key) {
|
||||
(Some(_key), Some(_cert)) => todo!("implement legacy TLS setup"),
|
||||
(None, None) => None::<()>,
|
||||
_ => bail!("either both or neither tls-key and tls-cert must be specified"),
|
||||
};
|
||||
|
||||
let metric_collection = match (
|
||||
args.get_one::<String>("metric-collection-endpoint"),
|
||||
args.get_one::<String>("metric-collection-interval"),
|
||||
) {
|
||||
// TODO: first merge `main` and `_aux` into one.
|
||||
main.map(|servers| {
|
||||
let resolver = certs::CertResolver::new(servers)?;
|
||||
TlsConfig::new(resolver)
|
||||
})
|
||||
.transpose()
|
||||
}
|
||||
|
||||
fn build_metrics_config(args: &clap::ArgMatches) -> anyhow::Result<Option<MetricCollectionConfig>> {
|
||||
let endpoint = args.get_one::<String>("metric-collection-endpoint");
|
||||
let interval = args.get_one::<String>("metric-collection-interval");
|
||||
|
||||
let config = match (endpoint, interval) {
|
||||
(Some(endpoint), Some(interval)) => Some(config::MetricCollectionConfig {
|
||||
endpoint: endpoint.parse()?,
|
||||
endpoint: endpoint.parse().context("bad metrics endpoint")?,
|
||||
interval: humantime::parse_duration(interval)?,
|
||||
}),
|
||||
(None, None) => None,
|
||||
@@ -152,7 +166,11 @@ fn build_config(args: &clap::ArgMatches) -> anyhow::Result<&'static ProxyConfig>
|
||||
),
|
||||
};
|
||||
|
||||
let auth_backend = match args.get_one::<String>("auth-backend").unwrap().as_str() {
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
fn build_auth_config(args: &clap::ArgMatches) -> anyhow::Result<BackendType<'static, ()>> {
|
||||
let config = match args.get_one::<String>("auth-backend").unwrap().as_str() {
|
||||
"console" => {
|
||||
let config::CacheOptions { size, ttl } = args
|
||||
.get_one::<String>("wake-compute-cache")
|
||||
@@ -182,10 +200,15 @@ fn build_config(args: &clap::ArgMatches) -> anyhow::Result<&'static ProxyConfig>
|
||||
other => bail!("unsupported auth backend: {other}"),
|
||||
};
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
/// ProxyConfig is created at proxy startup, and lives forever.
|
||||
fn build_config(args: &clap::ArgMatches) -> anyhow::Result<&'static ProxyConfig> {
|
||||
let config = Box::leak(Box::new(ProxyConfig {
|
||||
tls_config,
|
||||
auth_backend,
|
||||
metric_collection,
|
||||
tls_config: build_tls_config(args)?,
|
||||
auth_backend: build_auth_config(args)?,
|
||||
metric_collection: build_metrics_config(args)?,
|
||||
}));
|
||||
|
||||
Ok(config)
|
||||
@@ -245,14 +268,22 @@ fn cli() -> clap::Command {
|
||||
.short('k')
|
||||
.long("tls-key")
|
||||
.alias("ssl-key") // backwards compatibility
|
||||
.help("path to TLS key for client postgres connections"),
|
||||
.help("path to TLS key for client postgres connections")
|
||||
.value_parser(clap::builder::PathBufValueParser::new()),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("tls-cert")
|
||||
.short('c')
|
||||
.long("tls-cert")
|
||||
.alias("ssl-cert") // backwards compatibility
|
||||
.help("path to TLS cert for client postgres connections"),
|
||||
.help("path to TLS cert for client postgres connections")
|
||||
.value_parser(clap::builder::PathBufValueParser::new()),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("tls-config")
|
||||
.long("tls-config")
|
||||
.help("path to the TLS config file (example: config/servers.dhall)")
|
||||
.value_parser(clap::builder::PathBufValueParser::new()),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("metric-collection-endpoint")
|
||||
|
||||
@@ -112,7 +112,6 @@ pub async fn handle_ws_client(
|
||||
NUM_CONNECTIONS_CLOSED_COUNTER.inc();
|
||||
}
|
||||
|
||||
let tls = config.tls_config.as_ref();
|
||||
let hostname = hostname.as_deref();
|
||||
|
||||
// TLS is None here, because the connection is already encrypted.
|
||||
@@ -124,11 +123,10 @@ pub async fn handle_ws_client(
|
||||
|
||||
// Extract credentials which we're going to use for auth.
|
||||
let creds = {
|
||||
let common_name = tls.and_then(|tls| tls.common_name.as_deref());
|
||||
let result = config
|
||||
.auth_backend
|
||||
.as_ref()
|
||||
.map(|_| auth::ClientCredentials::parse(¶ms, hostname, common_name))
|
||||
.map(|_| auth::ClientCredentials::parse(¶ms, hostname))
|
||||
.transpose();
|
||||
|
||||
async { result }.or_else(|e| stream.throw_error(e)).await?
|
||||
@@ -163,11 +161,10 @@ async fn handle_client(
|
||||
// Extract credentials which we're going to use for auth.
|
||||
let creds = {
|
||||
let sni = stream.get_ref().sni_hostname();
|
||||
let common_name = tls.and_then(|tls| tls.common_name.as_deref());
|
||||
let result = config
|
||||
.auth_backend
|
||||
.as_ref()
|
||||
.map(|_| auth::ClientCredentials::parse(¶ms, sni, common_name))
|
||||
.map(|_| auth::ClientCredentials::parse(¶ms, sni))
|
||||
.transpose();
|
||||
|
||||
async { result }.or_else(|e| stream.throw_error(e)).await?
|
||||
|
||||
@@ -41,10 +41,7 @@ impl ClientConfig<'_> {
|
||||
}
|
||||
|
||||
/// Generate TLS certificates and build rustls configs for client and server.
|
||||
fn generate_tls_config<'a>(
|
||||
hostname: &'a str,
|
||||
common_name: &'a str,
|
||||
) -> anyhow::Result<(ClientConfig<'a>, TlsConfig)> {
|
||||
fn generate_tls_config(hostname: &str) -> anyhow::Result<(ClientConfig<'_>, TlsConfig)> {
|
||||
let (ca, cert, key) = generate_certs(hostname)?;
|
||||
|
||||
let tls_config = {
|
||||
@@ -54,10 +51,7 @@ fn generate_tls_config<'a>(
|
||||
.with_single_cert(vec![cert], key)?
|
||||
.into();
|
||||
|
||||
TlsConfig {
|
||||
config,
|
||||
common_name: Some(common_name.to_string()),
|
||||
}
|
||||
TlsConfig { config }
|
||||
};
|
||||
|
||||
let client_config = {
|
||||
@@ -150,7 +144,7 @@ async fn dummy_proxy(
|
||||
async fn handshake_tls_is_enforced_by_proxy() -> anyhow::Result<()> {
|
||||
let (client, server) = tokio::io::duplex(1024);
|
||||
|
||||
let (_, server_config) = generate_tls_config("generic-project-name.localhost", "localhost")?;
|
||||
let (_, server_config) = generate_tls_config("generic-project-name.localhost")?;
|
||||
let proxy = tokio::spawn(dummy_proxy(client, Some(server_config), NoAuth));
|
||||
|
||||
let client_err = tokio_postgres::Config::new()
|
||||
@@ -178,8 +172,7 @@ async fn handshake_tls_is_enforced_by_proxy() -> anyhow::Result<()> {
|
||||
async fn handshake_tls() -> anyhow::Result<()> {
|
||||
let (client, server) = tokio::io::duplex(1024);
|
||||
|
||||
let (client_config, server_config) =
|
||||
generate_tls_config("generic-project-name.localhost", "localhost")?;
|
||||
let (client_config, server_config) = generate_tls_config("generic-project-name.localhost")?;
|
||||
let proxy = tokio::spawn(dummy_proxy(client, Some(server_config), NoAuth));
|
||||
|
||||
let (_client, _conn) = tokio_postgres::Config::new()
|
||||
@@ -237,8 +230,7 @@ async fn keepalive_is_inherited() -> anyhow::Result<()> {
|
||||
async fn scram_auth_good(#[case] password: &str) -> anyhow::Result<()> {
|
||||
let (client, server) = tokio::io::duplex(1024);
|
||||
|
||||
let (client_config, server_config) =
|
||||
generate_tls_config("generic-project-name.localhost", "localhost")?;
|
||||
let (client_config, server_config) = generate_tls_config("generic-project-name.localhost")?;
|
||||
let proxy = tokio::spawn(dummy_proxy(
|
||||
client,
|
||||
Some(server_config),
|
||||
@@ -260,8 +252,7 @@ async fn scram_auth_good(#[case] password: &str) -> anyhow::Result<()> {
|
||||
async fn scram_auth_mock() -> anyhow::Result<()> {
|
||||
let (client, server) = tokio::io::duplex(1024);
|
||||
|
||||
let (client_config, server_config) =
|
||||
generate_tls_config("generic-project-name.localhost", "localhost")?;
|
||||
let (client_config, server_config) = generate_tls_config("generic-project-name.localhost")?;
|
||||
let proxy = tokio::spawn(dummy_proxy(
|
||||
client,
|
||||
Some(server_config),
|
||||
|
||||
Reference in New Issue
Block a user