Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rfSoU-000IWG-Dm for pgsql-hackers@arkaria.postgresql.org; Wed, 28 Feb 2024 22:54:11 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1rfSoT-00FrIZ-1B for pgsql-hackers@arkaria.postgresql.org; Wed, 28 Feb 2024 22:54:09 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rfSoS-00FrIR-Jm for pgsql-hackers@lists.postgresql.org; Wed, 28 Feb 2024 22:54:09 +0000 Received: from smtp.outgoing.loopia.se ([93.188.3.37]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rfSoQ-001tIW-63 for pgsql-hackers@lists.postgresql.org; Wed, 28 Feb 2024 22:54:08 +0000 Received: from s807.loopia.se (localhost [127.0.0.1]) by s807.loopia.se (Postfix) with ESMTP id DB58E2FFBBB0 for ; Wed, 28 Feb 2024 23:54:04 +0100 (CET) Received: from s979.loopia.se (unknown [172.22.191.5]) by s807.loopia.se (Postfix) with ESMTP id C99AE2E2F9C2; Wed, 28 Feb 2024 23:54:04 +0100 (CET) Received: from s473.loopia.se (unknown [172.22.191.5]) by s979.loopia.se (Postfix) with ESMTP id C7E4610BC47A; Wed, 28 Feb 2024 23:54:04 +0100 (CET) X-Virus-Scanned: amavisd-new at amavis.loopia.se X-Spam-Flag: NO X-Spam-Score: -1.21 X-Spam-Level: X-Spam-Status: No, score=-1.21 tagged_above=-999 required=6.2 tests=[ALL_TRUSTED=-1, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, T_SCC_BODY_TEXT_LINE=-0.01] autolearn=disabled Authentication-Results: s473.loopia.se (amavisd-new); dkim=pass (2048-bit key) header.d=yesql.se Received: from s979.loopia.se ([172.22.191.6]) by s473.loopia.se (s473.loopia.se [172.22.190.13]) (amavisd-new, port 10024) with LMTP id CQoRIrEYdmYX; Wed, 28 Feb 2024 23:54:04 +0100 (CET) X-Loopia-Auth: user X-Loopia-User: daniel@yesql.se X-Loopia-Originating-IP: 89.255.232.193 Received: from smtpclient.apple (customer-89-255-232-193.stosn.net [89.255.232.193]) (Authenticated sender: daniel@yesql.se) by s979.loopia.se (Postfix) with ESMTPSA id 304B910BC3E8; Wed, 28 Feb 2024 23:54:04 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yesql.se; s=loopiadkim1707475645; t=1709160844; bh=h3MZNb8QQfzUI2s78vFz6sWy/YWrMMoyWMAwawA+khY=; h=From:Subject:Date:In-Reply-To:Cc:To:References; b=raob+n0EVlhvccaOfSZ24kfS7gUnv/0n3JL5aI3aYanvC6ZSoZo70RlrPfLZMQZnG KiXgKMwvRcwnbuiWTtWD2cGhJMdQnFceIPpd9BpEZznp1HCtBh53n8fyVF7dxaf3oH qdPYgUOje5bNYME9Gk2FCAu0tZjjHNwM6tofpKuWvfnMm9kZbQP4VVJkZz4gcNYJDV ap74LeLeiVCeo277Ax+Y3y/EN3HUIm4mgLZuxeto3/Zwr/82/rXtyXiJsx7DI7oc7M bkmrJS29d2FFfIE0uhfuDvf4XnfFOE9mNV+071VfMeo/T8h8X41MTXvpPcLvfFqVbH qAkSFy9F3k7dQ== From: Daniel Gustafsson Message-Id: <86FCD541-91BD-48E6-9327-FEB162EADB31@yesql.se> Content-Type: multipart/mixed; boundary="Apple-Mail=_DE73332B-9329-4952-97D9-45E4DCEF99E9" Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3696.120.41.1.4\)) Subject: Re: Refactor SASL exchange in preparation for OAuth Bearer Date: Wed, 28 Feb 2024 23:54:03 +0100 In-Reply-To: Cc: PostgreSQL Hackers To: Jacob Champion References: X-Mailer: Apple Mail (2.3696.120.41.1.4) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --Apple-Mail=_DE73332B-9329-4952-97D9-45E4DCEF99E9 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii > On 26 Feb 2024, at 19:56, Jacob Champion = wrote: >> + * SASL_FAILED: The exchance has failed and the connection should be >=20 > s/exchance/exchange/ I rank that as one of my better typos actually. Fixed though. >> - if (final && !done) >> + if (final && !(status =3D=3D SASL_FAILED || status =3D=3D = SASL_COMPLETE)) >=20 > Since there's not yet a SASL_ASYNC, I wonder if this would be more > readable if it were changed to > if (final && status =3D=3D SASL_CONTINUE) > to match the if condition shortly after it. Fair point, that's more readable in this commit. > In 0002, at the beginning of pg_SASL_init, the `password` variable now > has an uninitialized code path. The OAuth patchset initializes it to > NULL: Nice catch, fixed. -- Daniel Gustafsson --Apple-Mail=_DE73332B-9329-4952-97D9-45E4DCEF99E9 Content-Disposition: attachment; filename=v2-0001-Refactor-SASL-exchange-to-return-tri-state-status.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="v2-0001-Refactor-SASL-exchange-to-return-tri-state-status.patch" Content-Transfer-Encoding: quoted-printable =46rom=20ae32698c528fce4829d4deccb922699d0b516f88=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20Daniel=20Gustafsson=20= =0ADate:=20Fri,=2023=20Feb=202024=2011:09:54=20= +0100=0ASubject:=20[PATCH=20v2=201/2]=20Refactor=20SASL=20exchange=20to=20= return=20tri-state=20status=0A=0AThe=20SASL=20exchange=20callback=20= returned=20state=20in=20to=20output=20variables:=0Adone=20and=20success.=20= =20This=20refactors=20that=20logic=20by=20introducing=20a=20new=0Areturn=20= variable=20of=20type=20SASLStatus=20which=20makes=20the=20code=20easier=20= to=0Aread=20and=20understand,=20and=20prepares=20for=20future=20SASL=20= exchanges=20which=0Aoperate=20asynchronously.=0A=0AThis=20was=20= extracted=20from=20a=20larger=20patchset=20to=20introduce=20OAuthBearer=0A= authentication=20and=20authorization.=0A=0AAuthor:=20Jacob=20Champion=20= =0ADiscussion:=20= https://postgr.es/m/d1b467a78e0e36ed85a09adf979d04cf124a9d4b.camel@vmware.= com=0A---=0A=20src/interfaces/libpq/fe-auth-sasl.h=20=20|=2031=20= +++++++----=0A=20src/interfaces/libpq/fe-auth-scram.c=20|=2078=20= +++++++++++++---------------=0A=20src/interfaces/libpq/fe-auth.c=20=20=20= =20=20=20=20|=2028=20+++++-----=0A=20src/tools/pgindent/typedefs.list=20=20= =20=20=20|=20=201=20+=0A=204=20files=20changed,=2071=20insertions(+),=20= 67=20deletions(-)=0A=0Adiff=20--git=20= a/src/interfaces/libpq/fe-auth-sasl.h=20= b/src/interfaces/libpq/fe-auth-sasl.h=0Aindex=20ee5d1525b5..4eecf53a15=20= 100644=0A---=20a/src/interfaces/libpq/fe-auth-sasl.h=0A+++=20= b/src/interfaces/libpq/fe-auth-sasl.h=0A@@=20-21,6=20+21,17=20@@=0A=20=0A= =20#include=20"libpq-fe.h"=0A=20=0A+/*=0A+=20*=20Possible=20states=20for=20= the=20SASL=20exchange,=20see=20the=20comment=20on=20exchange=20for=20an=0A= +=20*=20explanation=20of=20these.=0A+=20*/=0A+typedef=20enum=0A+{=0A+=09= SASL_COMPLETE=20=3D=200,=0A+=09SASL_FAILED,=0A+=09SASL_CONTINUE,=0A+}=20= SASLStatus;=0A+=0A=20/*=0A=20=20*=20Frontend=20SASL=20mechanism=20= callbacks.=0A=20=20*=0A@@=20-59,7=20+70,8=20@@=20typedef=20struct=20= pg_fe_sasl_mech=0A=20=09=20*=20Produces=20a=20client=20response=20to=20a=20= server=20challenge.=20=20As=20a=20special=20case=0A=20=09=20*=20for=20= client-first=20SASL=20mechanisms,=20exchange()=20is=20called=20with=20a=20= NULL=0A=20=09=20*=20server=20response=20once=20at=20the=20start=20of=20= the=20authentication=20exchange=20to=0A-=09=20*=20generate=20an=20= initial=20response.=0A+=09=20*=20generate=20an=20initial=20response.=20= Returns=20a=20SASLStatus=20indicating=20the=0A+=09=20*=20state=20and=20= status=20of=20the=20exchange.=0A=20=09=20*=0A=20=09=20*=20Input=20= parameters:=0A=20=09=20*=0A@@=20-79,22=20+91,23=20@@=20typedef=20struct=20= pg_fe_sasl_mech=0A=20=09=20*=0A=20=09=20*=09output:=09=20=20=20A=20= malloc'd=20buffer=20containing=20the=20client's=20response=20to=0A=20=09=20= *=09=09=09=20=20=20the=20server=20(can=20be=20empty),=20or=20NULL=20if=20= the=20exchange=20should=0A-=09=20*=09=09=09=20=20=20be=20aborted.=20=20= (*success=20should=20be=20set=20to=20false=20in=20the=0A+=09=20*=09=09=09= =20=20=20be=20aborted.=20=20(The=20callback=20should=20return=20= SASL_FAILED=20in=20the=0A=20=09=20*=09=09=09=20=20=20latter=20case.)=0A=20= =09=20*=0A=20=09=20*=09outputlen:=20The=20length=20(0=20or=20higher)=20= of=20the=20client=20response=20buffer,=0A=20=09=20*=09=09=09=20=20=20= ignored=20if=20output=20is=20NULL.=0A=20=09=20*=0A-=09=20*=09done:=20=20=20= =20=20=20Set=20to=20true=20if=20the=20SASL=20exchange=20should=20not=20= continue,=0A-=09=20*=09=09=09=20=20=20because=20the=20exchange=20is=20= either=20complete=20or=20failed=0A+=09=20*=20Return=20value:=0A=20=09=20= *=0A-=09=20*=09success:=20=20=20Set=20to=20true=20if=20the=20SASL=20= exchange=20completed=20successfully.=0A-=09=20*=09=09=09=20=20=20Ignored=20= if=20*done=20is=20false.=0A+=09=20*=09SASL_CONTINUE:=09The=20output=20= buffer=20is=20filled=20with=20a=20client=20response.=0A+=09=20*=09=09=09=09= =09Additional=20server=20challenge=20is=20expected=0A+=09=20*=09= SASL_COMPLETE:=09The=20SASL=20exchange=20has=20completed=20successfully.=0A= +=09=20*=09SASL_FAILED:=09The=20exchange=20has=20failed=20and=20the=20= connection=20should=20be=0A+=09=20*=09=09=09=09=09dropped.=0A=20=09=20= *--------=0A=20=09=20*/=0A-=09void=09=09(*exchange)=20(void=20*state,=20= char=20*input,=20int=20inputlen,=0A-=09=09=09=09=09=09=09=20char=20= **output,=20int=20*outputlen,=0A-=09=09=09=09=09=09=09=20bool=20*done,=20= bool=20*success);=0A+=09SASLStatus=09(*exchange)=20(void=20*state,=20= char=20*input,=20int=20inputlen,=0A+=09=09=09=09=09=09=09=20char=20= **output,=20int=20*outputlen);=0A=20=0A=20=09/*--------=0A=20=09=20*=20= channel_bound()=0Adiff=20--git=20a/src/interfaces/libpq/fe-auth-scram.c=20= b/src/interfaces/libpq/fe-auth-scram.c=0Aindex=2004f0e5713d..0bb820e0d9=20= 100644=0A---=20a/src/interfaces/libpq/fe-auth-scram.c=0A+++=20= b/src/interfaces/libpq/fe-auth-scram.c=0A@@=20-24,9=20+24,8=20@@=0A=20/*=20= The=20exported=20SCRAM=20callback=20mechanism.=20*/=0A=20static=20void=20= *scram_init(PGconn=20*conn,=20const=20char=20*password,=0A=20=09=09=09=09= =09=09const=20char=20*sasl_mechanism);=0A-static=20void=20= scram_exchange(void=20*opaq,=20char=20*input,=20int=20inputlen,=0A-=09=09= =09=09=09=09=20=20=20char=20**output,=20int=20*outputlen,=0A-=09=09=09=09= =09=09=20=20=20bool=20*done,=20bool=20*success);=0A+static=20SASLStatus=20= scram_exchange(void=20*opaq,=20char=20*input,=20int=20inputlen,=0A+=09=09= =09=09=09=09=09=09=20char=20**output,=20int=20*outputlen);=0A=20static=20= bool=20scram_channel_bound(void=20*opaq);=0A=20static=20void=20= scram_free(void=20*opaq);=0A=20=0A@@=20-202,17=20+201,14=20@@=20= scram_free(void=20*opaq)=0A=20/*=0A=20=20*=20Exchange=20a=20SCRAM=20= message=20with=20backend.=0A=20=20*/=0A-static=20void=0A+static=20= SASLStatus=0A=20scram_exchange(void=20*opaq,=20char=20*input,=20int=20= inputlen,=0A-=09=09=09=20=20=20char=20**output,=20int=20*outputlen,=0A-=09= =09=09=20=20=20bool=20*done,=20bool=20*success)=0A+=09=09=09=20=20=20= char=20**output,=20int=20*outputlen)=0A=20{=0A=20=09fe_scram_state=20= *state=20=3D=20(fe_scram_state=20*)=20opaq;=0A=20=09PGconn=09=20=20=20= *conn=20=3D=20state->conn;=0A=20=09const=20char=20*errstr=20=3D=20NULL;=0A= =20=0A-=09*done=20=3D=20false;=0A-=09*success=20=3D=20false;=0A=20=09= *output=20=3D=20NULL;=0A=20=09*outputlen=20=3D=200;=0A=20=0A@@=20-225,12=20= +221,12=20@@=20scram_exchange(void=20*opaq,=20char=20*input,=20int=20= inputlen,=0A=20=09=09if=20(inputlen=20=3D=3D=200)=0A=20=09=09{=0A=20=09=09= =09libpq_append_conn_error(conn,=20"malformed=20SCRAM=20message=20(empty=20= message)");=0A-=09=09=09goto=20error;=0A+=09=09=09return=20SASL_FAILED;=0A= =20=09=09}=0A=20=09=09if=20(inputlen=20!=3D=20strlen(input))=0A=20=09=09= {=0A=20=09=09=09libpq_append_conn_error(conn,=20"malformed=20SCRAM=20= message=20(length=20mismatch)");=0A-=09=09=09goto=20error;=0A+=09=09=09= return=20SASL_FAILED;=0A=20=09=09}=0A=20=09}=0A=20=0A@@=20-240,61=20= +236,59=20@@=20scram_exchange(void=20*opaq,=20char=20*input,=20int=20= inputlen,=0A=20=09=09=09/*=20Begin=20the=20SCRAM=20handshake,=20by=20= sending=20client=20nonce=20*/=0A=20=09=09=09*output=20=3D=20= build_client_first_message(state);=0A=20=09=09=09if=20(*output=20=3D=3D=20= NULL)=0A-=09=09=09=09goto=20error;=0A+=09=09=09=09return=20SASL_FAILED;=0A= =20=0A=20=09=09=09*outputlen=20=3D=20strlen(*output);=0A-=09=09=09*done=20= =3D=20false;=0A=20=09=09=09state->state=20=3D=20FE_SCRAM_NONCE_SENT;=0A-=09= =09=09break;=0A+=09=09=09return=20SASL_CONTINUE;=0A=20=0A=20=09=09case=20= FE_SCRAM_NONCE_SENT:=0A=20=09=09=09/*=20Receive=20salt=20and=20server=20= nonce,=20send=20response.=20*/=0A=20=09=09=09if=20= (!read_server_first_message(state,=20input))=0A-=09=09=09=09goto=20= error;=0A+=09=09=09=09return=20SASL_FAILED;=0A=20=0A=20=09=09=09*output=20= =3D=20build_client_final_message(state);=0A=20=09=09=09if=20(*output=20= =3D=3D=20NULL)=0A-=09=09=09=09goto=20error;=0A+=09=09=09=09return=20= SASL_FAILED;=0A=20=0A=20=09=09=09*outputlen=20=3D=20strlen(*output);=0A-=09= =09=09*done=20=3D=20false;=0A=20=09=09=09state->state=20=3D=20= FE_SCRAM_PROOF_SENT;=0A-=09=09=09break;=0A+=09=09=09return=20= SASL_CONTINUE;=0A=20=0A=20=09=09case=20FE_SCRAM_PROOF_SENT:=0A-=09=09=09= /*=20Receive=20server=20signature=20*/=0A-=09=09=09if=20= (!read_server_final_message(state,=20input))=0A-=09=09=09=09goto=20= error;=0A-=0A-=09=09=09/*=0A-=09=09=09=20*=20Verify=20server=20= signature,=20to=20make=20sure=20we're=20talking=20to=20the=0A-=09=09=09=20= *=20genuine=20server.=0A-=09=09=09=20*/=0A-=09=09=09if=20= (!verify_server_signature(state,=20success,=20&errstr))=0A-=09=09=09{=0A= -=09=09=09=09libpq_append_conn_error(conn,=20"could=20not=20verify=20= server=20signature:=20%s",=20errstr);=0A-=09=09=09=09goto=20error;=0A-=09= =09=09}=0A-=0A-=09=09=09if=20(!*success)=0A=20=09=09=09{=0A-=09=09=09=09= libpq_append_conn_error(conn,=20"incorrect=20server=20signature");=0A+=09= =09=09=09bool=09=09match;=0A+=0A+=09=09=09=09/*=20Receive=20server=20= signature=20*/=0A+=09=09=09=09if=20(!read_server_final_message(state,=20= input))=0A+=09=09=09=09=09return=20SASL_FAILED;=0A+=0A+=09=09=09=09/*=0A= +=09=09=09=09=20*=20Verify=20server=20signature,=20to=20make=20sure=20= we're=20talking=20to=20the=0A+=09=09=09=09=20*=20genuine=20server.=0A+=09= =09=09=09=20*/=0A+=09=09=09=09if=20(!verify_server_signature(state,=20= &match,=20&errstr))=0A+=09=09=09=09{=0A+=09=09=09=09=09= libpq_append_conn_error(conn,=20"could=20not=20verify=20server=20= signature:=20%s",=20errstr);=0A+=09=09=09=09=09return=20SASL_FAILED;=0A+=09= =09=09=09}=0A+=0A+=09=09=09=09if=20(!match)=0A+=09=09=09=09{=0A+=09=09=09= =09=09libpq_append_conn_error(conn,=20"incorrect=20server=20signature");=0A= +=09=09=09=09}=0A+=09=09=09=09state->state=20=3D=20FE_SCRAM_FINISHED;=0A= +=09=09=09=09state->conn->client_finished_auth=20=3D=20true;=0A+=09=09=09= =09return=20match=20?=20SASL_COMPLETE=20:=20SASL_FAILED;=0A=20=09=09=09}=0A= -=09=09=09*done=20=3D=20true;=0A-=09=09=09state->state=20=3D=20= FE_SCRAM_FINISHED;=0A-=09=09=09state->conn->client_finished_auth=20=3D=20= true;=0A-=09=09=09break;=0A=20=0A=20=09=09default:=0A=20=09=09=09/*=20= shouldn't=20happen=20*/=0A=20=09=09=09libpq_append_conn_error(conn,=20= "invalid=20SCRAM=20exchange=20state");=0A-=09=09=09goto=20error;=0A+=09=09= =09break;=0A=20=09}=0A-=09return;=0A=20=0A-error:=0A-=09*done=20=3D=20= true;=0A-=09*success=20=3D=20false;=0A+=09return=20SASL_FAILED;=0A=20}=0A= =20=0A=20/*=0Adiff=20--git=20a/src/interfaces/libpq/fe-auth.c=20= b/src/interfaces/libpq/fe-auth.c=0Aindex=201a8e4f6fbf..cf8af4c62e=20= 100644=0A---=20a/src/interfaces/libpq/fe-auth.c=0A+++=20= b/src/interfaces/libpq/fe-auth.c=0A@@=20-423,11=20+423,10=20@@=20= pg_SASL_init(PGconn=20*conn,=20int=20payloadlen)=0A=20{=0A=20=09char=09=20= =20=20*initialresponse=20=3D=20NULL;=0A=20=09int=09=09=09= initialresponselen;=0A-=09bool=09=09done;=0A-=09bool=09=09success;=0A=20=09= const=20char=20*selected_mechanism;=0A=20=09PQExpBufferData=20= mechanism_buf;=0A=20=09char=09=20=20=20*password;=0A+=09SASLStatus=09= status;=0A=20=0A=20=09initPQExpBuffer(&mechanism_buf);=0A=20=0A@@=20= -575,12=20+574,11=20@@=20pg_SASL_init(PGconn=20*conn,=20int=20= payloadlen)=0A=20=09=09goto=20oom_error;=0A=20=0A=20=09/*=20Get=20the=20= mechanism-specific=20Initial=20Client=20Response,=20if=20any=20*/=0A-=09= conn->sasl->exchange(conn->sasl_state,=0A-=09=09=09=09=09=09=20NULL,=20= -1,=0A-=09=09=09=09=09=09=20&initialresponse,=20&initialresponselen,=0A-=09= =09=09=09=09=09=20&done,=20&success);=0A+=09status=20=3D=20= conn->sasl->exchange(conn->sasl_state,=0A+=09=09=09=09=09=09=09=09=20=20= NULL,=20-1,=0A+=09=09=09=09=09=09=09=09=20=20&initialresponse,=20= &initialresponselen);=0A=20=0A-=09if=20(done=20&&=20!success)=0A+=09if=20= (status=20=3D=3D=20SASL_FAILED)=0A=20=09=09goto=20error;=0A=20=0A=20=09= /*=0A@@=20-629,10=20+627,9=20@@=20pg_SASL_continue(PGconn=20*conn,=20int=20= payloadlen,=20bool=20final)=0A=20{=0A=20=09char=09=20=20=20*output;=0A=20= =09int=09=09=09outputlen;=0A-=09bool=09=09done;=0A-=09bool=09=09success;=0A= =20=09int=09=09=09res;=0A=20=09char=09=20=20=20*challenge;=0A+=09= SASLStatus=09status;=0A=20=0A=20=09/*=20Read=20the=20SASL=20challenge=20= from=20the=20AuthenticationSASLContinue=20message.=20*/=0A=20=09= challenge=20=3D=20malloc(payloadlen=20+=201);=0A@@=20-651,13=20+648,12=20= @@=20pg_SASL_continue(PGconn=20*conn,=20int=20payloadlen,=20bool=20= final)=0A=20=09/*=20For=20safety=20and=20convenience,=20ensure=20the=20= buffer=20is=20NULL-terminated.=20*/=0A=20=09challenge[payloadlen]=20=3D=20= '\0';=0A=20=0A-=09conn->sasl->exchange(conn->sasl_state,=0A-=09=09=09=09=09= =09=20challenge,=20payloadlen,=0A-=09=09=09=09=09=09=20&output,=20= &outputlen,=0A-=09=09=09=09=09=09=20&done,=20&success);=0A+=09status=20=3D= =20conn->sasl->exchange(conn->sasl_state,=0A+=09=09=09=09=09=09=09=09=20=20= challenge,=20payloadlen,=0A+=09=09=09=09=09=09=09=09=20=20&output,=20= &outputlen);=0A=20=09free(challenge);=09=09=09/*=20don't=20need=20the=20= input=20anymore=20*/=0A=20=0A-=09if=20(final=20&&=20!done)=0A+=09if=20= (final=20&&=20status=20=3D=3D=20SASL_CONTINUE)=0A=20=09{=0A=20=09=09if=20= (outputlen=20!=3D=200)=0A=20=09=09=09free(output);=0A@@=20-670,7=20= +666,7=20@@=20pg_SASL_continue(PGconn=20*conn,=20int=20payloadlen,=20= bool=20final)=0A=20=09=20*=20If=20the=20exchange=20is=20not=20completed=20= yet,=20we=20need=20to=20make=20sure=20that=20the=0A=20=09=20*=20SASL=20= mechanism=20has=20generated=20a=20message=20to=20send=20back.=0A=20=09=20= */=0A-=09if=20(output=20=3D=3D=20NULL=20&&=20!done)=0A+=09if=20(output=20= =3D=3D=20NULL=20&&=20status=20=3D=3D=20SASL_CONTINUE)=0A=20=09{=0A=20=09=09= libpq_append_conn_error(conn,=20"no=20client=20response=20found=20after=20= SASL=20exchange=20success");=0A=20=09=09return=20STATUS_ERROR;=0A@@=20= -692,7=20+688,7=20@@=20pg_SASL_continue(PGconn=20*conn,=20int=20= payloadlen,=20bool=20final)=0A=20=09=09=09return=20STATUS_ERROR;=0A=20=09= }=0A=20=0A-=09if=20(done=20&&=20!success)=0A+=09if=20(status=20=3D=3D=20= SASL_FAILED)=0A=20=09=09return=20STATUS_ERROR;=0A=20=0A=20=09return=20= STATUS_OK;=0Adiff=20--git=20a/src/tools/pgindent/typedefs.list=20= b/src/tools/pgindent/typedefs.list=0Aindex=20fc8b15d0cf..2461567026=20= 100644=0A---=20a/src/tools/pgindent/typedefs.list=0A+++=20= b/src/tools/pgindent/typedefs.list=0A@@=20-2423,6=20+2423,7=20@@=20= RuleLock=0A=20RuleStmt=0A=20RunningTransactions=0A=20= RunningTransactionsData=0A+SASLStatus=0A=20SC_HANDLE=0A=20= SECURITY_ATTRIBUTES=0A=20SECURITY_STATUS=0A--=20=0A2.32.1=20(Apple=20= Git-133)=0A=0A= --Apple-Mail=_DE73332B-9329-4952-97D9-45E4DCEF99E9 Content-Disposition: attachment; filename=v2-0002-Explicitly-require-password-for-SCRAM-exchange.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="v2-0002-Explicitly-require-password-for-SCRAM-exchange.patch" Content-Transfer-Encoding: quoted-printable =46rom=20ed4a2e0c169e7b3a762aa93ee349b90d898962b2=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20Daniel=20Gustafsson=20= =0ADate:=20Fri,=2023=20Feb=202024=2011:19:55=20= +0100=0ASubject:=20[PATCH=20v2=202/2]=20Explicitly=20require=20password=20= for=20SCRAM=20exchange=0A=0AThis=20refactors=20the=20SASL=20init=20flow=20= to=20set=20password_needed=20on=20the=20two=0ASCRAM=20exchanges=20= currently=20supported.=20The=20code=20already=20required=20this=0Abut=20= was=20set=20up=20in=20such=20a=20way=20that=20all=20SASL=20exchanges=20= required=20using=0Aa=20password,=20a=20restriction=20which=20may=20not=20= hold=20for=20all=20exchanges=20(the=0Aexample=20at=20hand=20being=20the=20= proposed=20OAuthbearer=20exchange).=0A=0AThis=20was=20extracted=20from=20= a=20larger=20patchset=20to=20introduce=20OAuthBearer=0Aauthentication=20= and=20authorization.=0A=0AAuthor:=20Jacob=20Champion=20= =0ADiscussion:=20= https://postgr.es/m/d1b467a78e0e36ed85a09adf979d04cf124a9d4b.camel@vmware.= com=0A---=0A=20src/interfaces/libpq/fe-auth.c=20|=2028=20= +++++++++++++++-------------=0A=201=20file=20changed,=2015=20= insertions(+),=2013=20deletions(-)=0A=0Adiff=20--git=20= a/src/interfaces/libpq/fe-auth.c=20b/src/interfaces/libpq/fe-auth.c=0A= index=20cf8af4c62e..81ec08485d=20100644=0A---=20= a/src/interfaces/libpq/fe-auth.c=0A+++=20= b/src/interfaces/libpq/fe-auth.c=0A@@=20-425,7=20+425,7=20@@=20= pg_SASL_init(PGconn=20*conn,=20int=20payloadlen)=0A=20=09int=09=09=09= initialresponselen;=0A=20=09const=20char=20*selected_mechanism;=0A=20=09= PQExpBufferData=20mechanism_buf;=0A-=09char=09=20=20=20*password;=0A+=09= char=09=20=20=20*password=20=3D=20NULL;=0A=20=09SASLStatus=09status;=0A=20= =0A=20=09initPQExpBuffer(&mechanism_buf);=0A@@=20-446,8=20+446,7=20@@=20= pg_SASL_init(PGconn=20*conn,=20int=20payloadlen)=0A=20=09/*=0A=20=09=20*=20= Parse=20the=20list=20of=20SASL=20authentication=20mechanisms=20in=20the=0A= =20=09=20*=20AuthenticationSASL=20message,=20and=20select=20the=20best=20= mechanism=20that=20we=0A-=09=20*=20support.=20=20SCRAM-SHA-256-PLUS=20= and=20SCRAM-SHA-256=20are=20the=20only=20ones=0A-=09=20*=20supported=20= at=20the=20moment,=20listed=20by=20order=20of=20decreasing=20importance.=0A= +=09=20*=20support.=20Mechanisms=20are=20listed=20by=20order=20of=20= decreasing=20importance.=0A=20=09=20*/=0A=20=09selected_mechanism=20=3D=20= NULL;=0A=20=09for=20(;;)=0A@@=20-487,6=20+486,7=20@@=20= pg_SASL_init(PGconn=20*conn,=20int=20payloadlen)=0A=20=09=09=09=09{=0A=20= =09=09=09=09=09selected_mechanism=20=3D=20SCRAM_SHA_256_PLUS_NAME;=0A=20=09= =09=09=09=09conn->sasl=20=3D=20&pg_scram_mech;=0A+=09=09=09=09=09= conn->password_needed=20=3D=20true;=0A=20=09=09=09=09}=0A=20#else=0A=20=09= =09=09=09/*=0A@@=20-522,6=20+522,7=20@@=20pg_SASL_init(PGconn=20*conn,=20= int=20payloadlen)=0A=20=09=09{=0A=20=09=09=09selected_mechanism=20=3D=20= SCRAM_SHA_256_NAME;=0A=20=09=09=09conn->sasl=20=3D=20&pg_scram_mech;=0A+=09= =09=09conn->password_needed=20=3D=20true;=0A=20=09=09}=0A=20=09}=0A=20=0A= @@=20-545,18=20+546,19=20@@=20pg_SASL_init(PGconn=20*conn,=20int=20= payloadlen)=0A=20=0A=20=09/*=0A=20=09=20*=20First,=20select=20the=20= password=20to=20use=20for=20the=20exchange,=20complaining=20if=0A-=09=20= *=20there=20isn't=20one.=20=20Currently,=20all=20supported=20SASL=20= mechanisms=20require=20a=0A-=09=20*=20password,=20so=20we=20can=20just=20= go=20ahead=20here=20without=20further=20distinction.=0A+=09=20*=20there=20= isn't=20one=20and=20the=20selected=20SASL=20mechanism=20needs=20it.=0A=20= =09=20*/=0A-=09conn->password_needed=20=3D=20true;=0A-=09password=20=3D=20= conn->connhost[conn->whichhost].password;=0A-=09if=20(password=20=3D=3D=20= NULL)=0A-=09=09password=20=3D=20conn->pgpass;=0A-=09if=20(password=20=3D=3D= =20NULL=20||=20password[0]=20=3D=3D=20'\0')=0A+=09if=20= (conn->password_needed)=0A=20=09{=0A-=09=09= appendPQExpBufferStr(&conn->errorMessage,=0A-=09=09=09=09=09=09=09=20= PQnoPasswordSupplied);=0A-=09=09goto=20error;=0A+=09=09password=20=3D=20= conn->connhost[conn->whichhost].password;=0A+=09=09if=20(password=20=3D=3D= =20NULL)=0A+=09=09=09password=20=3D=20conn->pgpass;=0A+=09=09if=20= (password=20=3D=3D=20NULL=20||=20password[0]=20=3D=3D=20'\0')=0A+=09=09{=0A= +=09=09=09appendPQExpBufferStr(&conn->errorMessage,=0A+=09=09=09=09=09=09= =09=09=20PQnoPasswordSupplied);=0A+=09=09=09goto=20error;=0A+=09=09}=0A=20= =09}=0A=20=0A=20=09Assert(conn->sasl);=0A--=20=0A2.32.1=20(Apple=20= Git-133)=0A=0A= --Apple-Mail=_DE73332B-9329-4952-97D9-45E4DCEF99E9--