diff options
Diffstat (limited to 'src/backend/libpq/auth.c')
-rw-r--r-- | src/backend/libpq/auth.c | 62 |
1 files changed, 21 insertions, 41 deletions
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 63f37902e64..cecd104b4a5 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -862,8 +862,7 @@ CheckMD5Auth(Port *port, char *shadow_pass, char **logdetail) static int CheckSCRAMAuth(Port *port, char *shadow_pass, char **logdetail) { - char *sasl_mechs; - char *p; + StringInfoData sasl_mechs; int mtype; StringInfoData buf; void *scram_opaq; @@ -889,42 +888,16 @@ CheckSCRAMAuth(Port *port, char *shadow_pass, char **logdetail) /* * Send the SASL authentication request to user. It includes the list of - * authentication mechanisms that are supported. The order of mechanisms - * is advertised in decreasing order of importance. So the - * channel-binding variants go first, if they are supported. Channel - * binding is only supported in SSL builds. + * authentication mechanisms that are supported. */ - sasl_mechs = palloc(strlen(SCRAM_SHA_256_PLUS_NAME) + - strlen(SCRAM_SHA_256_NAME) + 3); - p = sasl_mechs; - - if (port->ssl_in_use) - { - strcpy(p, SCRAM_SHA_256_PLUS_NAME); - p += strlen(SCRAM_SHA_256_PLUS_NAME) + 1; - } - - strcpy(p, SCRAM_SHA_256_NAME); - p += strlen(SCRAM_SHA_256_NAME) + 1; + initStringInfo(&sasl_mechs); + pg_be_scram_get_mechanisms(port, &sasl_mechs); /* Put another '\0' to mark that list is finished. */ - p[0] = '\0'; - - sendAuthRequest(port, AUTH_REQ_SASL, sasl_mechs, p - sasl_mechs + 1); - pfree(sasl_mechs); + appendStringInfoChar(&sasl_mechs, '\0'); - /* - * Initialize the status tracker for message exchanges. - * - * If the user doesn't exist, or doesn't have a valid password, or it's - * expired, we still go through the motions of SASL authentication, but - * tell the authentication method that the authentication is "doomed". - * That is, it's going to fail, no matter what. - * - * This is because we don't want to reveal to an attacker what usernames - * are valid, nor which users have a valid password. - */ - scram_opaq = pg_be_scram_init(port, shadow_pass); + sendAuthRequest(port, AUTH_REQ_SASL, sasl_mechs.data, sasl_mechs.len); + pfree(sasl_mechs.data); /* * Loop through SASL message exchange. This exchange can consist of @@ -973,13 +946,20 @@ CheckSCRAMAuth(Port *port, char *shadow_pass, char **logdetail) const char *selected_mech; selected_mech = pq_getmsgrawstring(&buf); - if (strcmp(selected_mech, SCRAM_SHA_256_NAME) != 0 && - strcmp(selected_mech, SCRAM_SHA_256_PLUS_NAME) != 0) - { - ereport(ERROR, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("client selected an invalid SASL authentication mechanism"))); - } + + /* + * Initialize the status tracker for message exchanges. + * + * If the user doesn't exist, or doesn't have a valid password, or + * it's expired, we still go through the motions of SASL + * authentication, but tell the authentication method that the + * authentication is "doomed". That is, it's going to fail, no + * matter what. + * + * This is because we don't want to reveal to an attacker what + * usernames are valid, nor which users have a valid password. + */ + scram_opaq = pg_be_scram_init(port, selected_mech, shadow_pass); inputlen = pq_getmsgint(&buf, 4); if (inputlen == -1) |