Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit24178e2

Browse files
Refactor SASL exchange to return tri-state status
The SASL exchange callback returned state in to output variables:done and success. This refactors that logic by introducing a newreturn variable of type SASLStatus which makes the code easier toread and understand, and prepares for future SASL exchanges whichoperate asynchronously.This was extracted from a larger patchset to introduce OAuthBearerauthentication and authorization.Author: Jacob Champion <jacob.champion@enterprisedb.com>Discussion:https://postgr.es/m/d1b467a78e0e36ed85a09adf979d04cf124a9d4b.camel@vmware.com
1 parent1db6897 commit24178e2

File tree

4 files changed

+71
-67
lines changed

4 files changed

+71
-67
lines changed

‎src/interfaces/libpq/fe-auth-sasl.h

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@
2121

2222
#include"libpq-fe.h"
2323

24+
/*
25+
* Possible states for the SASL exchange, see the comment on exchange for an
26+
* explanation of these.
27+
*/
28+
typedefenum
29+
{
30+
SASL_COMPLETE=0,
31+
SASL_FAILED,
32+
SASL_CONTINUE,
33+
}SASLStatus;
34+
2435
/*
2536
* Frontend SASL mechanism callbacks.
2637
*
@@ -59,7 +70,8 @@ typedef struct pg_fe_sasl_mech
5970
* Produces a client response to a server challenge. As a special case
6071
* for client-first SASL mechanisms, exchange() is called with a NULL
6172
* server response once at the start of the authentication exchange to
62-
* generate an initial response.
73+
* generate an initial response. Returns a SASLStatus indicating the
74+
* state and status of the exchange.
6375
*
6476
* Input parameters:
6577
*
@@ -79,22 +91,23 @@ typedef struct pg_fe_sasl_mech
7991
*
8092
*output: A malloc'd buffer containing the client's response to
8193
* the server (can be empty), or NULL if the exchange should
82-
* be aborted. (*successshouldbe set to false in the
94+
* be aborted. (The callbackshouldreturn SASL_FAILED in the
8395
* latter case.)
8496
*
8597
*outputlen: The length (0 or higher) of the client response buffer,
8698
* ignored if output is NULL.
8799
*
88-
*done: Set to true if the SASL exchange should not continue,
89-
* because the exchange is either complete or failed
100+
* Return value:
90101
*
91-
*success: Set to true if the SASL exchange completed successfully.
92-
* Ignored if *done is false.
102+
*SASL_CONTINUE:The output buffer is filled with a client response.
103+
*Additional server challenge is expected
104+
*SASL_COMPLETE:The SASL exchange has completed successfully.
105+
*SASL_FAILED:The exchange has failed and the connection should be
106+
*dropped.
93107
*--------
94108
*/
95-
void(*exchange) (void*state,char*input,intinputlen,
96-
char**output,int*outputlen,
97-
bool*done,bool*success);
109+
SASLStatus(*exchange) (void*state,char*input,intinputlen,
110+
char**output,int*outputlen);
98111

99112
/*--------
100113
* channel_bound()

‎src/interfaces/libpq/fe-auth-scram.c

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@
2424
/* The exported SCRAM callback mechanism. */
2525
staticvoid*scram_init(PGconn*conn,constchar*password,
2626
constchar*sasl_mechanism);
27-
staticvoidscram_exchange(void*opaq,char*input,intinputlen,
28-
char**output,int*outputlen,
29-
bool*done,bool*success);
27+
staticSASLStatusscram_exchange(void*opaq,char*input,intinputlen,
28+
char**output,int*outputlen);
3029
staticboolscram_channel_bound(void*opaq);
3130
staticvoidscram_free(void*opaq);
3231

@@ -202,17 +201,14 @@ scram_free(void *opaq)
202201
/*
203202
* Exchange a SCRAM message with backend.
204203
*/
205-
staticvoid
204+
staticSASLStatus
206205
scram_exchange(void*opaq,char*input,intinputlen,
207-
char**output,int*outputlen,
208-
bool*done,bool*success)
206+
char**output,int*outputlen)
209207
{
210208
fe_scram_state*state= (fe_scram_state*)opaq;
211209
PGconn*conn=state->conn;
212210
constchar*errstr=NULL;
213211

214-
*done= false;
215-
*success= false;
216212
*output=NULL;
217213
*outputlen=0;
218214

@@ -225,12 +221,12 @@ scram_exchange(void *opaq, char *input, int inputlen,
225221
if (inputlen==0)
226222
{
227223
libpq_append_conn_error(conn,"malformed SCRAM message (empty message)");
228-
gotoerror;
224+
returnSASL_FAILED;
229225
}
230226
if (inputlen!=strlen(input))
231227
{
232228
libpq_append_conn_error(conn,"malformed SCRAM message (length mismatch)");
233-
gotoerror;
229+
returnSASL_FAILED;
234230
}
235231
}
236232

@@ -240,61 +236,59 @@ scram_exchange(void *opaq, char *input, int inputlen,
240236
/* Begin the SCRAM handshake, by sending client nonce */
241237
*output=build_client_first_message(state);
242238
if (*output==NULL)
243-
gotoerror;
239+
returnSASL_FAILED;
244240

245241
*outputlen=strlen(*output);
246-
*done= false;
247242
state->state=FE_SCRAM_NONCE_SENT;
248-
break;
243+
returnSASL_CONTINUE;
249244

250245
caseFE_SCRAM_NONCE_SENT:
251246
/* Receive salt and server nonce, send response. */
252247
if (!read_server_first_message(state,input))
253-
gotoerror;
248+
returnSASL_FAILED;
254249

255250
*output=build_client_final_message(state);
256251
if (*output==NULL)
257-
gotoerror;
252+
returnSASL_FAILED;
258253

259254
*outputlen=strlen(*output);
260-
*done= false;
261255
state->state=FE_SCRAM_PROOF_SENT;
262-
break;
256+
returnSASL_CONTINUE;
263257

264258
caseFE_SCRAM_PROOF_SENT:
265-
/* Receive server signature */
266-
if (!read_server_final_message(state,input))
267-
gotoerror;
268-
269-
/*
270-
* Verify server signature, to make sure we're talking to the
271-
* genuine server.
272-
*/
273-
if (!verify_server_signature(state,success,&errstr))
274-
{
275-
libpq_append_conn_error(conn,"could not verify server signature: %s",errstr);
276-
gotoerror;
277-
}
278-
279-
if (!*success)
280259
{
281-
libpq_append_conn_error(conn,"incorrect server signature");
260+
boolmatch;
261+
262+
/* Receive server signature */
263+
if (!read_server_final_message(state,input))
264+
returnSASL_FAILED;
265+
266+
/*
267+
* Verify server signature, to make sure we're talking to the
268+
* genuine server.
269+
*/
270+
if (!verify_server_signature(state,&match,&errstr))
271+
{
272+
libpq_append_conn_error(conn,"could not verify server signature: %s",errstr);
273+
returnSASL_FAILED;
274+
}
275+
276+
if (!match)
277+
{
278+
libpq_append_conn_error(conn,"incorrect server signature");
279+
}
280+
state->state=FE_SCRAM_FINISHED;
281+
state->conn->client_finished_auth= true;
282+
returnmatch ?SASL_COMPLETE :SASL_FAILED;
282283
}
283-
*done= true;
284-
state->state=FE_SCRAM_FINISHED;
285-
state->conn->client_finished_auth= true;
286-
break;
287284

288285
default:
289286
/* shouldn't happen */
290287
libpq_append_conn_error(conn,"invalid SCRAM exchange state");
291-
gotoerror;
288+
break;
292289
}
293-
return;
294290

295-
error:
296-
*done= true;
297-
*success= false;
291+
returnSASL_FAILED;
298292
}
299293

300294
/*

‎src/interfaces/libpq/fe-auth.c

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -423,11 +423,10 @@ pg_SASL_init(PGconn *conn, int payloadlen)
423423
{
424424
char*initialresponse=NULL;
425425
intinitialresponselen;
426-
booldone;
427-
boolsuccess;
428426
constchar*selected_mechanism;
429427
PQExpBufferDatamechanism_buf;
430428
char*password;
429+
SASLStatusstatus;
431430

432431
initPQExpBuffer(&mechanism_buf);
433432

@@ -575,12 +574,11 @@ pg_SASL_init(PGconn *conn, int payloadlen)
575574
gotooom_error;
576575

577576
/* Get the mechanism-specific Initial Client Response, if any */
578-
conn->sasl->exchange(conn->sasl_state,
579-
NULL,-1,
580-
&initialresponse,&initialresponselen,
581-
&done,&success);
577+
status=conn->sasl->exchange(conn->sasl_state,
578+
NULL,-1,
579+
&initialresponse,&initialresponselen);
582580

583-
if (done&& !success)
581+
if (status==SASL_FAILED)
584582
gotoerror;
585583

586584
/*
@@ -629,10 +627,9 @@ pg_SASL_continue(PGconn *conn, int payloadlen, bool final)
629627
{
630628
char*output;
631629
intoutputlen;
632-
booldone;
633-
boolsuccess;
634630
intres;
635631
char*challenge;
632+
SASLStatusstatus;
636633

637634
/* Read the SASL challenge from the AuthenticationSASLContinue message. */
638635
challenge=malloc(payloadlen+1);
@@ -651,13 +648,12 @@ pg_SASL_continue(PGconn *conn, int payloadlen, bool final)
651648
/* For safety and convenience, ensure the buffer is NULL-terminated. */
652649
challenge[payloadlen]='\0';
653650

654-
conn->sasl->exchange(conn->sasl_state,
655-
challenge,payloadlen,
656-
&output,&outputlen,
657-
&done,&success);
651+
status=conn->sasl->exchange(conn->sasl_state,
652+
challenge,payloadlen,
653+
&output,&outputlen);
658654
free(challenge);/* don't need the input anymore */
659655

660-
if (final&&!done)
656+
if (final&&status==SASL_CONTINUE)
661657
{
662658
if (outputlen!=0)
663659
free(output);
@@ -670,7 +666,7 @@ pg_SASL_continue(PGconn *conn, int payloadlen, bool final)
670666
* If the exchange is not completed yet, we need to make sure that the
671667
* SASL mechanism has generated a message to send back.
672668
*/
673-
if (output==NULL&&!done)
669+
if (output==NULL&&status==SASL_CONTINUE)
674670
{
675671
libpq_append_conn_error(conn,"no client response found after SASL exchange success");
676672
returnSTATUS_ERROR;
@@ -692,7 +688,7 @@ pg_SASL_continue(PGconn *conn, int payloadlen, bool final)
692688
returnSTATUS_ERROR;
693689
}
694690

695-
if (done&& !success)
691+
if (status==SASL_FAILED)
696692
returnSTATUS_ERROR;
697693

698694
returnSTATUS_OK;

‎src/tools/pgindent/typedefs.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2442,6 +2442,7 @@ RuleLock
24422442
RuleStmt
24432443
RunningTransactions
24442444
RunningTransactionsData
2445+
SASLStatus
24452446
SC_HANDLE
24462447
SECURITY_ATTRIBUTES
24472448
SECURITY_STATUS

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp