aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/libpq/fe-auth-scram.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/libpq/fe-auth-scram.c')
-rw-r--r--src/interfaces/libpq/fe-auth-scram.c124
1 files changed, 67 insertions, 57 deletions
diff --git a/src/interfaces/libpq/fe-auth-scram.c b/src/interfaces/libpq/fe-auth-scram.c
index b76f0befd0b..002469540a9 100644
--- a/src/interfaces/libpq/fe-auth-scram.c
+++ b/src/interfaces/libpq/fe-auth-scram.c
@@ -208,14 +208,14 @@ pg_fe_scram_exchange(void *opaq, char *input, int inputlen,
{
if (inputlen == 0)
{
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("malformed SCRAM message (empty message)\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("malformed SCRAM message (empty message)\n"));
goto error;
}
if (inputlen != strlen(input))
{
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("malformed SCRAM message (length mismatch)\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("malformed SCRAM message (length mismatch)\n"));
goto error;
}
}
@@ -258,15 +258,15 @@ pg_fe_scram_exchange(void *opaq, char *input, int inputlen,
*/
if (!verify_server_signature(state, success))
{
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("could not verify server signature\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("could not verify server signature\n"));
goto error;
}
if (!*success)
{
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("incorrect server signature\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("incorrect server signature\n"));
}
*done = true;
state->state = FE_SCRAM_FINISHED;
@@ -274,8 +274,8 @@ pg_fe_scram_exchange(void *opaq, char *input, int inputlen,
default:
/* shouldn't happen */
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("invalid SCRAM exchange state\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("invalid SCRAM exchange state\n"));
goto error;
}
return;
@@ -287,6 +287,11 @@ error:
/*
* Read value for an attribute part of a SCRAM message.
+ *
+ * The buffer at **input is destructively modified, and *input is
+ * advanced over the "attr=value" string and any following comma.
+ *
+ * On failure, append an error message to *errorMessage and return NULL.
*/
static char *
read_attr_value(char **input, char attr, PQExpBuffer errorMessage)
@@ -296,7 +301,7 @@ read_attr_value(char **input, char attr, PQExpBuffer errorMessage)
if (*begin != attr)
{
- printfPQExpBuffer(errorMessage,
+ appendPQExpBuffer(errorMessage,
libpq_gettext("malformed SCRAM message (attribute \"%c\" expected)\n"),
attr);
return NULL;
@@ -305,7 +310,7 @@ read_attr_value(char **input, char attr, PQExpBuffer errorMessage)
if (*begin != '=')
{
- printfPQExpBuffer(errorMessage,
+ appendPQExpBuffer(errorMessage,
libpq_gettext("malformed SCRAM message (expected character \"=\" for attribute \"%c\")\n"),
attr);
return NULL;
@@ -346,8 +351,8 @@ build_client_first_message(fe_scram_state *state)
*/
if (!pg_strong_random(raw_nonce, SCRAM_RAW_NONCE_LEN))
{
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("could not generate nonce\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("could not generate nonce\n"));
return NULL;
}
@@ -356,16 +361,16 @@ build_client_first_message(fe_scram_state *state)
state->client_nonce = malloc(encoded_len + 1);
if (state->client_nonce == NULL)
{
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("out of memory\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("out of memory\n"));
return NULL;
}
encoded_len = pg_b64_encode(raw_nonce, SCRAM_RAW_NONCE_LEN,
state->client_nonce, encoded_len);
if (encoded_len < 0)
{
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("could not encode nonce\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("could not encode nonce\n"));
return NULL;
}
state->client_nonce[encoded_len] = '\0';
@@ -431,8 +436,8 @@ build_client_first_message(fe_scram_state *state)
oom_error:
termPQExpBuffer(&buf);
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("out of memory\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("out of memory\n"));
return NULL;
}
@@ -508,8 +513,8 @@ build_client_final_message(fe_scram_state *state)
free(cbind_data);
free(cbind_input);
termPQExpBuffer(&buf);
- printfPQExpBuffer(&conn->errorMessage,
- "could not encode cbind data for channel binding\n");
+ appendPQExpBufferStr(&conn->errorMessage,
+ "could not encode cbind data for channel binding\n");
return NULL;
}
buf.len += encoded_cbind_len;
@@ -523,8 +528,8 @@ build_client_final_message(fe_scram_state *state)
* Shouldn't happen.
*/
termPQExpBuffer(&buf);
- printfPQExpBuffer(&conn->errorMessage,
- "channel binding not supported by this build\n");
+ appendPQExpBufferStr(&conn->errorMessage,
+ "channel binding not supported by this build\n");
return NULL;
#endif /* HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH */
}
@@ -553,8 +558,8 @@ build_client_final_message(fe_scram_state *state)
client_proof))
{
termPQExpBuffer(&buf);
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("could not calculate client proof\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("could not calculate client proof\n"));
return NULL;
}
@@ -569,8 +574,8 @@ build_client_final_message(fe_scram_state *state)
if (encoded_len < 0)
{
termPQExpBuffer(&buf);
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("could not encode client proof\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("could not encode client proof\n"));
return NULL;
}
buf.len += encoded_len;
@@ -585,8 +590,8 @@ build_client_final_message(fe_scram_state *state)
oom_error:
termPQExpBuffer(&buf);
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("out of memory\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("out of memory\n"));
return NULL;
}
@@ -606,8 +611,8 @@ read_server_first_message(fe_scram_state *state, char *input)
state->server_first_message = strdup(input);
if (state->server_first_message == NULL)
{
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("out of memory\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("out of memory\n"));
return false;
}
@@ -616,7 +621,7 @@ read_server_first_message(fe_scram_state *state, char *input)
&conn->errorMessage);
if (nonce == NULL)
{
- /* read_attr_value() has generated an error string */
+ /* read_attr_value() has appended an error string */
return false;
}
@@ -624,31 +629,31 @@ read_server_first_message(fe_scram_state *state, char *input)
if (strlen(nonce) < strlen(state->client_nonce) ||
memcmp(nonce, state->client_nonce, strlen(state->client_nonce)) != 0)
{
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("invalid SCRAM response (nonce mismatch)\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("invalid SCRAM response (nonce mismatch)\n"));
return false;
}
state->nonce = strdup(nonce);
if (state->nonce == NULL)
{
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("out of memory\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("out of memory\n"));
return false;
}
encoded_salt = read_attr_value(&input, 's', &conn->errorMessage);
if (encoded_salt == NULL)
{
- /* read_attr_value() has generated an error string */
+ /* read_attr_value() has appended an error string */
return false;
}
decoded_salt_len = pg_b64_dec_len(strlen(encoded_salt));
state->salt = malloc(decoded_salt_len);
if (state->salt == NULL)
{
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("out of memory\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("out of memory\n"));
return false;
}
state->saltlen = pg_b64_decode(encoded_salt,
@@ -657,28 +662,28 @@ read_server_first_message(fe_scram_state *state, char *input)
decoded_salt_len);
if (state->saltlen < 0)
{
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("malformed SCRAM message (invalid salt)\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("malformed SCRAM message (invalid salt)\n"));
return false;
}
iterations_str = read_attr_value(&input, 'i', &conn->errorMessage);
if (iterations_str == NULL)
{
- /* read_attr_value() has generated an error string */
+ /* read_attr_value() has appended an error string */
return false;
}
state->iterations = strtol(iterations_str, &endptr, 10);
if (*endptr != '\0' || state->iterations < 1)
{
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("malformed SCRAM message (invalid iteration count)\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("malformed SCRAM message (invalid iteration count)\n"));
return false;
}
if (*input != '\0')
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("malformed SCRAM message (garbage at end of server-first-message)\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("malformed SCRAM message (garbage at end of server-first-message)\n"));
return true;
}
@@ -697,8 +702,8 @@ read_server_final_message(fe_scram_state *state, char *input)
state->server_final_message = strdup(input);
if (!state->server_final_message)
{
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("out of memory\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("out of memory\n"));
return false;
}
@@ -708,7 +713,12 @@ read_server_final_message(fe_scram_state *state, char *input)
char *errmsg = read_attr_value(&input, 'e',
&conn->errorMessage);
- printfPQExpBuffer(&conn->errorMessage,
+ if (errmsg == NULL)
+ {
+ /* read_attr_value() has appended an error message */
+ return false;
+ }
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("error received from server in SCRAM exchange: %s\n"),
errmsg);
return false;
@@ -719,20 +729,20 @@ read_server_final_message(fe_scram_state *state, char *input)
&conn->errorMessage);
if (encoded_server_signature == NULL)
{
- /* read_attr_value() has generated an error message */
+ /* read_attr_value() has appended an error message */
return false;
}
if (*input != '\0')
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("malformed SCRAM message (garbage at end of server-final-message)\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("malformed SCRAM message (garbage at end of server-final-message)\n"));
server_signature_len = pg_b64_dec_len(strlen(encoded_server_signature));
decoded_server_signature = malloc(server_signature_len);
if (!decoded_server_signature)
{
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("out of memory\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("out of memory\n"));
return false;
}
@@ -743,8 +753,8 @@ read_server_final_message(fe_scram_state *state, char *input)
if (server_signature_len != SCRAM_KEY_LEN)
{
free(decoded_server_signature);
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("malformed SCRAM message (invalid server signature)\n"));
+ appendPQExpBufferStr(&conn->errorMessage,
+ libpq_gettext("malformed SCRAM message (invalid server signature)\n"));
return false;
}
memcpy(state->ServerSignature, decoded_server_signature, SCRAM_KEY_LEN);