-
Notifications
You must be signed in to change notification settings - Fork 1.1k
PgSQL native backend protocol: replace libpq on the data path (connect/auth/TLS, simple query, COPY, extended query via stmt pipeline, Describe cache) #5882
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v3.0
Are you sure you want to change the base?
Changes from 78 commits
abb93dc
e2448f8
0572b03
eef410e
d539351
e5e99e3
5447992
6874b5a
6ed54c5
ad31ded
4e90372
630c076
b7bedf0
b027c8c
f953a3f
f9ac560
6e344f0
21600ac
741ce1e
02db8fe
e0ce545
b9583d0
5937ba4
f8e0534
89161a0
320ae67
fc42ba1
1f4709d
5328403
3ef8875
d0a53ae
6b4c7c5
e076212
a407f17
392a199
0b7efc3
9f08de8
e9428cb
f9a95c6
c3518cd
d4a11c5
4b77532
86caf12
ed0a1fb
cc2aa79
54b3633
f7f80ff
3dba6ed
051dd25
5cfa4f3
c9c0073
a254976
683d385
6ca9fc5
6645312
dc6309d
f1ba189
295072c
0eb57a8
6f8edef
62f4e3c
c4d6c70
91f82e9
dfb0490
81f2b23
200f75a
1becd76
aeef97b
c274c39
5c306c2
41df3ca
ad4312c
d561b76
7a9671c
b53ae6c
8018060
4e8f025
181e87c
89ed5b6
f603e83
836cc4b
3e43b35
5cece87
ea60cba
bafe054
810eaba
c516670
1534652
c5ce37e
b9feac1
03d1f8a
0280699
9b6a01c
b18da3a
782532a
4a5e67d
f058436
6888955
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,11 +37,20 @@ ifeq ($(UNAME_S),Darwin) | |
| LIB_CRYPTO_PATH := $(shell find $(SSL_LDIR) -maxdepth 1 -name "libcrypto.a" 2>/dev/null | head -n 1) | ||
| endif | ||
| else | ||
| LIB_SSL_PATH := $(shell find $(SSL_LDIR) -maxdepth 1 -name "libssl.so*" 2>/dev/null | head -n 1) | ||
| # Prefer OpenSSL 3.x when multiple versions coexist in SSL_LDIR | ||
| # (a bare libssl.so* first-match can pick a stale 1.1 library); | ||
| # fall back to any shared lib, then static. | ||
| LIB_SSL_PATH := $(shell find $(SSL_LDIR) -maxdepth 1 -name "libssl.so*3*" 2>/dev/null | head -n 1) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: This file is explicitly documented as a local build workaround that must not be committed. Remove the added OpenSSL-selection changes from the PR so shared builds do not inherit this machine-dependent library selection. Prompt for AI agents |
||
| ifeq ($(LIB_SSL_PATH),) | ||
| LIB_SSL_PATH := $(shell find $(SSL_LDIR) -maxdepth 1 -name "libssl.so*" 2>/dev/null | head -n 1) | ||
| endif | ||
| ifeq ($(LIB_SSL_PATH),) | ||
| LIB_SSL_PATH := $(shell find $(SSL_LDIR) -maxdepth 1 -name "libssl.a" 2>/dev/null | head -n 1) | ||
| endif | ||
| LIB_CRYPTO_PATH := $(shell find $(SSL_LDIR) -maxdepth 1 -name "libcrypto.so*" 2>/dev/null | head -n 1) | ||
| LIB_CRYPTO_PATH := $(shell find $(SSL_LDIR) -maxdepth 1 -name "libcrypto.so*3*" 2>/dev/null | head -n 1) | ||
| ifeq ($(LIB_CRYPTO_PATH),) | ||
| LIB_CRYPTO_PATH := $(shell find $(SSL_LDIR) -maxdepth 1 -name "libcrypto.so*" 2>/dev/null | head -n 1) | ||
| endif | ||
| ifeq ($(LIB_CRYPTO_PATH),) | ||
| LIB_CRYPTO_PATH := $(shell find $(SSL_LDIR) -maxdepth 1 -name "libcrypto.a" 2>/dev/null | head -n 1) | ||
| endif | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -215,13 +215,15 @@ ScramState* scram_state_init() { | |
| scram_state->server_nonce = NULL; | ||
| scram_state->server_first_message = NULL; | ||
| scram_state->SaltedPassword = NULL; | ||
| scram_state->cbind_flag = '\0'; | ||
| scram_state->cbind_flag = 'n'; | ||
| scram_state->adhoc = false; | ||
| scram_state->iterations = 0; | ||
| scram_state->salt = NULL; | ||
| memset(scram_state->ClientKey, 0, sizeof(scram_state->ClientKey)); | ||
| memset(scram_state->StoredKey, 0, sizeof(scram_state->StoredKey)); | ||
| memset(scram_state->ServerKey, 0, sizeof(scram_state->ServerKey)); | ||
| scram_state->client_cbind_input = NULL; | ||
| scram_state->client_cbind_input_len = 0; | ||
| } | ||
| return scram_state; | ||
| } | ||
|
|
@@ -237,6 +239,7 @@ void free_scram_state(ScramState *scram_state) | |
| free(scram_state->client_final_message_without_proof); | ||
| free(scram_state->server_nonce); | ||
| free(scram_state->server_first_message); | ||
| free(scram_state->client_cbind_input); | ||
| free(scram_state->SaltedPassword); | ||
| free(scram_state->salt); | ||
| memset(scram_state, 0, sizeof(*scram_state)); | ||
|
|
@@ -503,7 +506,15 @@ char *build_client_first_message(ScramState *scram_state) | |
| result = malloc(len); | ||
| if (result == NULL) | ||
| goto failed; | ||
| snprintf(result, len, "n,,n=,r=%s", scram_state->client_nonce); | ||
| if (scram_state->client_cbind_input != NULL) { | ||
| /* Channel-bound client: gs2 cbind flag 'p' with tls-server-end-point | ||
| * type. The PostgreSQL convention is an empty SCRAM username (the | ||
| * real username travels in the StartupMessage), so the header is | ||
| * "p=tls-server-end-point,,". */ | ||
| snprintf(result, len, "p=tls-server-end-point,,n=,r=%s", scram_state->client_nonce); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: When channel binding is enabled, this call writes into a buffer sized for plain SCRAM and truncates the client-first nonce. Size the result from the complete channel-bound format before calling Prompt for AI agentsThere was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: When channel binding is enabled, this call writes into a buffer sized for plain SCRAM and truncates the client-first nonce. Size the result from the complete channel-bound format before calling Prompt for AI agents |
||
| } else { | ||
| snprintf(result, len, "n,,n=,r=%s", scram_state->client_nonce); | ||
| } | ||
|
|
||
| scram_state->client_first_message_bare = strdup(result + 3); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When channel binding is enabled ( \tscram_state->client_first_message_bare = strdup(result + (scram_state->client_cbind_input != NULL ? 24 : 3)); |
||
| if (scram_state->client_first_message_bare == NULL) | ||
|
|
@@ -532,7 +543,22 @@ char *build_client_final_message(ScramState *scram_state, | |
| uint8_t client_proof[SCRAM_KEY_LEN]; | ||
| int enclen; | ||
|
|
||
| snprintf(buf, sizeof(buf), "c=biws,r=%s", server_nonce); | ||
| if (scram_state->client_cbind_input != NULL) { | ||
| /* Channel-bound client: c=base64(gs2-header || cbind-data). | ||
| * 86 bytes buffer = 22 (header) + 64 (max digest we accept) = 86; | ||
| * base64-encoded = 116 chars max. The full prefix | ||
| * "c=<b64>,r=<server_nonce>" easily fits in 512. */ | ||
| char b64[128]; | ||
| int blen = pg_b64_encode(scram_state->client_cbind_input, | ||
| scram_state->client_cbind_input_len, | ||
| b64, sizeof(b64)); | ||
| if (blen < 0) | ||
| goto failed; | ||
| b64[blen] = '\0'; | ||
| snprintf(buf, sizeof(buf), "c=%s,r=%s", b64, server_nonce); | ||
| } else { | ||
| snprintf(buf, sizeof(buf), "c=biws,r=%s", server_nonce); | ||
| } | ||
|
|
||
| scram_state->client_final_message_without_proof = strdup(buf); | ||
| if (scram_state->client_final_message_without_proof == NULL) | ||
|
|
@@ -1418,3 +1444,29 @@ bool scram_verify_plain_password(const char *username, const char *password, | |
| free(prep_password); | ||
| return false; | ||
| } | ||
|
|
||
| /* | ||
| * Set the channel-binding input that will be used by build_client_first_message | ||
| * (gs2 header selection) and build_client_final_message (c= field composition). | ||
| * cbind_input must be the full "gs2-header || cbind-data" blob, e.g. | ||
| * "p=tls-server-end-point,," || digest. Passing NULL/0 reverts to plain SCRAM | ||
| * (the existing gs2 header "n,," / c="biws" path) and frees any prior input. | ||
| * The state owns a private copy allocated with malloc; the caller may free its | ||
| * own buffer after the call returns. | ||
| */ | ||
| void scram_state_set_cbind_input(ScramState *state, | ||
| const char *cbind_input, int cbind_input_len) | ||
| { | ||
| if (state == NULL) return; | ||
| free(state->client_cbind_input); | ||
| state->client_cbind_input = NULL; | ||
| state->client_cbind_input_len = 0; | ||
| state->cbind_flag = 'n'; | ||
| if (cbind_input == NULL || cbind_input_len <= 0) return; | ||
| state->client_cbind_input = (char *)malloc((size_t)cbind_input_len + 1); | ||
| if (state->client_cbind_input == NULL) return; | ||
| memcpy(state->client_cbind_input, cbind_input, (size_t)cbind_input_len); | ||
| state->client_cbind_input[cbind_input_len] = '\0'; | ||
| state->client_cbind_input_len = cbind_input_len; | ||
| state->cbind_flag = 'p'; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: This file is explicitly documented as a local build workaround that must not be committed. Remove the added OpenSSL-selection changes from the PR so shared builds do not inherit this machine-dependent library selection.
Prompt for AI agents