diff --git a/src/backend/libpq/auth-scram.c b/src/backend/libpq/auth-scram.c index bf97eecb42..3cbe902ace 100644 --- a/src/backend/libpq/auth-scram.c +++ b/src/backend/libpq/auth-scram.c @@ -155,8 +155,8 @@ typedef struct char *logdetail; } scram_state; -static void read_client_first_message(scram_state *state, char *input); -static void read_client_final_message(scram_state *state, char *input); +static void read_client_first_message(scram_state *state, const char *input); +static void read_client_final_message(scram_state *state, const char *input); static char *build_server_first_message(scram_state *state); static char *build_server_final_message(scram_state *state); static bool verify_client_proof(scram_state *state); @@ -327,7 +327,7 @@ pg_be_scram_init(Port *port, * the client). */ int -pg_be_scram_exchange(void *opaq, char *input, int inputlen, +pg_be_scram_exchange(void *opaq, const char *input, int inputlen, char **output, int *outputlen, char **logdetail) { scram_state *state = (scram_state *) opaq; @@ -811,11 +811,11 @@ read_any_attr(char **input, char *attr_p) * At this stage, any errors will be reported directly with ereport(ERROR). */ static void -read_client_first_message(scram_state *state, char *input) +read_client_first_message(scram_state *state, const char *input) { + char *p = pstrdup(input); char *channel_binding_type; - input = pstrdup(input); /*------ * The syntax for the client-first-message is: (RFC 5802) @@ -881,8 +881,8 @@ read_client_first_message(scram_state *state, char *input) * Read gs2-cbind-flag. (For details see also RFC 5802 Section 6 "Channel * Binding".) */ - state->cbind_flag = *input; - switch (*input) + state->cbind_flag = *p; + switch (*p) { case 'n': @@ -896,14 +896,14 @@ read_client_first_message(scram_state *state, char *input) errmsg("malformed SCRAM message"), errdetail("The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data."))); - input++; - if (*input != ',') + p++; + if (*p != ',') ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("malformed SCRAM message"), errdetail("Comma expected, but found character \"%s\".", - sanitize_char(*input)))); - input++; + sanitize_char(*p)))); + p++; break; case 'y': @@ -926,14 +926,14 @@ read_client_first_message(scram_state *state, char *input) errdetail("The client supports SCRAM channel binding but thinks the server does not. " "However, this server does support channel binding."))); #endif - input++; - if (*input != ',') + p++; + if (*p != ',') ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("malformed SCRAM message"), errdetail("Comma expected, but found character \"%s\".", - sanitize_char(*input)))); - input++; + sanitize_char(*p)))); + p++; break; case 'p': @@ -947,7 +947,7 @@ read_client_first_message(scram_state *state, char *input) errmsg("malformed SCRAM message"), errdetail("The client selected SCRAM-SHA-256 without channel binding, but the SCRAM message includes channel binding data."))); - channel_binding_type = read_attr_value(&input, 'p'); + channel_binding_type = read_attr_value(&p, 'p'); /* * The only channel binding type we support is @@ -964,25 +964,25 @@ read_client_first_message(scram_state *state, char *input) (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("malformed SCRAM message"), errdetail("Unexpected channel-binding flag \"%s\".", - sanitize_char(*input)))); + sanitize_char(*p)))); } /* * Forbid optional authzid (authorization identity). We don't support it. */ - if (*input == 'a') + if (*p == 'a') ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("client uses authorization identity, but it is not supported"))); - if (*input != ',') + if (*p != ',') ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("malformed SCRAM message"), errdetail("Unexpected attribute \"%s\" in client-first-message.", - sanitize_char(*input)))); - input++; + sanitize_char(*p)))); + p++; - state->client_first_message_bare = pstrdup(input); + state->client_first_message_bare = pstrdup(p); /* * Any mandatory extensions would go here. We don't support any. @@ -991,7 +991,7 @@ read_client_first_message(scram_state *state, char *input) * but it can only be sent in the server-final message. We prefer to fail * immediately (which the RFC also allows). */ - if (*input == 'm') + if (*p == 'm') ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("client requires an unsupported SCRAM extension"))); @@ -1001,10 +1001,10 @@ read_client_first_message(scram_state *state, char *input) * startup message instead, still it is kept around if provided as it * proves to be useful for debugging purposes. */ - state->client_username = read_attr_value(&input, 'n'); + state->client_username = read_attr_value(&p, 'n'); /* read nonce and check that it is made of only printable characters */ - state->client_nonce = read_attr_value(&input, 'r'); + state->client_nonce = read_attr_value(&p, 'r'); if (!is_scram_printable(state->client_nonce)) ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), @@ -1014,8 +1014,8 @@ read_client_first_message(scram_state *state, char *input) * There can be any number of optional extensions after this. We don't * support any extensions, so ignore them. */ - while (*input != '\0') - read_any_attr(&input, NULL); + while (*p != '\0') + read_any_attr(&p, NULL); /* success! */ } @@ -1144,7 +1144,7 @@ build_server_first_message(scram_state *state) * Read and parse the final message received from client. */ static void -read_client_final_message(scram_state *state, char *input) +read_client_final_message(scram_state *state, const char *input) { char attr; char *channel_binding; diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index c42f7b8fe6..d5115aad72 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -985,7 +985,7 @@ CheckSCRAMAuth(Port *port, char *shadow_pass, char **logdetail) * we pass 'logdetail' as NULL when doing a mock authentication, * because we should already have a better error message in that case */ - result = pg_be_scram_exchange(scram_opaq, unconstify(char *, input), inputlen, + result = pg_be_scram_exchange(scram_opaq, input, inputlen, &output, &outputlen, logdetail); diff --git a/src/include/libpq/scram.h b/src/include/libpq/scram.h index 8eeb8807e9..d7f4c094c9 100644 --- a/src/include/libpq/scram.h +++ b/src/include/libpq/scram.h @@ -24,7 +24,7 @@ /* Routines dedicated to authentication */ extern void pg_be_scram_get_mechanisms(Port *port, StringInfo buf); extern void *pg_be_scram_init(Port *port, const char *selected_mech, const char *shadow_pass); -extern int pg_be_scram_exchange(void *opaq, char *input, int inputlen, +extern int pg_be_scram_exchange(void *opaq, const char *input, int inputlen, char **output, int *outputlen, char **logdetail); /* Routines to handle and check SCRAM-SHA-256 verifier */