Skip to content

Commit 1d642d6

Browse files
chore(proxy): vendor a subset of rust-postgres (#9930)
Our rust-postgres fork is getting messy. Mostly because proxy wants more control over the raw protocol than tokio-postgres provides. As such, it's diverging more and more. Storage and compute also make use of rust-postgres, but in more normal usage, thus they don't need our crazy changes. Idea: * proxy maintains their subset * other teams use a minimal patch set against upstream rust-postgres Reviewing this code will be difficult. To implement it, I 1. Copied tokio-postgres, postgres-protocol and postgres-types from https://github.com/neondatabase/rust-postgres/tree/00940fcdb57a8e99e805297b75839e7c4c7b1796 2. Updated their package names with the `2` suffix to make them compile in the workspace. 3. Updated proxy to use those packages 4. Copied in the code from tokio-postgres-rustls 0.13 (with some patches applied jbg/tokio-postgres-rustls#32 jbg/tokio-postgres-rustls#33) 5. Removed as much dead code as I could find in the vendored libraries 6. Updated the tokio-postgres-rustls code to use our existing channel binding implementation
1 parent 3ffe6de commit 1d642d6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+11199
-26
lines changed

.config/hakari.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ workspace-members = [
4646
"utils",
4747
"wal_craft",
4848
"walproposer",
49+
"postgres-protocol2",
50+
"postgres-types2",
51+
"tokio-postgres2",
4952
]
5053

5154
# Write out exact versions rather than a semver range. (Defaults to false.)

Cargo.lock

Lines changed: 49 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ members = [
3535
"libs/walproposer",
3636
"libs/wal_decoder",
3737
"libs/postgres_initdb",
38+
"libs/proxy/postgres-protocol2",
39+
"libs/proxy/postgres-types2",
40+
"libs/proxy/tokio-postgres2",
3841
]
3942

4043
[workspace.package]

libs/proxy/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
This directory contains libraries that are specific for proxy.
2+
3+
Currently, it contains a signficant fork/refactoring of rust-postgres that no longer reflects the API
4+
of the original library. Since it was so significant, it made sense to upgrade it to it's own set of libraries.
5+
6+
Proxy needs unique access to the protocol, which explains why such heavy modifications were necessary.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
name = "postgres-protocol2"
3+
version = "0.1.0"
4+
edition = "2018"
5+
license = "MIT/Apache-2.0"
6+
7+
[dependencies]
8+
base64 = "0.20"
9+
byteorder.workspace = true
10+
bytes.workspace = true
11+
fallible-iterator.workspace = true
12+
hmac.workspace = true
13+
md-5 = "0.10"
14+
memchr = "2.0"
15+
rand.workspace = true
16+
sha2.workspace = true
17+
stringprep = "0.1"
18+
tokio = { workspace = true, features = ["rt"] }
19+
20+
[dev-dependencies]
21+
tokio = { workspace = true, features = ["full"] }
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//! Authentication protocol support.
2+
use md5::{Digest, Md5};
3+
4+
pub mod sasl;
5+
6+
/// Hashes authentication information in a way suitable for use in response
7+
/// to an `AuthenticationMd5Password` message.
8+
///
9+
/// The resulting string should be sent back to the database in a
10+
/// `PasswordMessage` message.
11+
#[inline]
12+
pub fn md5_hash(username: &[u8], password: &[u8], salt: [u8; 4]) -> String {
13+
let mut md5 = Md5::new();
14+
md5.update(password);
15+
md5.update(username);
16+
let output = md5.finalize_reset();
17+
md5.update(format!("{:x}", output));
18+
md5.update(salt);
19+
format!("md5{:x}", md5.finalize())
20+
}
21+
22+
#[cfg(test)]
23+
mod test {
24+
use super::*;
25+
26+
#[test]
27+
fn md5() {
28+
let username = b"md5_user";
29+
let password = b"password";
30+
let salt = [0x2a, 0x3d, 0x8f, 0xe0];
31+
32+
assert_eq!(
33+
md5_hash(username, password, salt),
34+
"md562af4dd09bbb41884907a838a3233294"
35+
);
36+
}
37+
}

0 commit comments

Comments
 (0)