PostgreSQL Source Code git master
Loading...
Searching...
No Matches
sasl.h File Reference
#include "lib/stringinfo.h"
#include "libpq/libpq-be.h"
Include dependency graph for sasl.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  pg_be_sasl_mech
 

Macros

#define PG_SASL_EXCHANGE_CONTINUE   0
 
#define PG_SASL_EXCHANGE_SUCCESS   1
 
#define PG_SASL_EXCHANGE_FAILURE   2
 
#define PG_SASL_EXCHANGE_ABANDONED   3
 
#define PG_MAX_SASL_MESSAGE_LENGTH   1024
 

Typedefs

typedef struct pg_be_sasl_mech pg_be_sasl_mech
 

Functions

int CheckSASLAuth (const pg_be_sasl_mech *mech, Port *port, char *shadow_pass, const char **logdetail, bool *abandoned)
 

Macro Definition Documentation

◆ PG_MAX_SASL_MESSAGE_LENGTH

#define PG_MAX_SASL_MESSAGE_LENGTH   1024

Definition at line 36 of file sasl.h.

◆ PG_SASL_EXCHANGE_ABANDONED

#define PG_SASL_EXCHANGE_ABANDONED   3

Definition at line 28 of file sasl.h.

◆ PG_SASL_EXCHANGE_CONTINUE

#define PG_SASL_EXCHANGE_CONTINUE   0

Definition at line 25 of file sasl.h.

◆ PG_SASL_EXCHANGE_FAILURE

#define PG_SASL_EXCHANGE_FAILURE   2

Definition at line 27 of file sasl.h.

◆ PG_SASL_EXCHANGE_SUCCESS

#define PG_SASL_EXCHANGE_SUCCESS   1

Definition at line 26 of file sasl.h.

Typedef Documentation

◆ pg_be_sasl_mech

Function Documentation

◆ CheckSASLAuth()

int CheckSASLAuth ( const pg_be_sasl_mech mech,
Port port,
char shadow_pass,
const char **  logdetail,
bool abandoned 
)
extern

Definition at line 50 of file auth-sasl.c.

52{
54 int mtype;
56 void *opaq = NULL;
57 char *output = NULL;
58 int outputlen = 0;
59 const char *input;
60 int inputlen;
61 int result;
62 bool initial;
63
64 /*
65 * Send the SASL authentication request to user. It includes the list of
66 * authentication mechanisms that are supported.
67 */
69
70 mech->get_mechanisms(port, &sasl_mechs);
71 /* Put another '\0' to mark that list is finished. */
73
75 pfree(sasl_mechs.data);
76
77 /*
78 * Loop through SASL message exchange. This exchange can consist of
79 * multiple messages sent in both directions. First message is always
80 * from the client. All messages from client to server are password
81 * packets (type 'p').
82 */
83 initial = true;
84 do
85 {
87 mtype = pq_getbyte();
89 {
90 /* Only log error if client didn't disconnect. */
91 if (mtype != EOF)
92 {
95 errmsg("expected SASL response, got message type %d",
96 mtype)));
97 }
98 else
99 return STATUS_EOF;
100 }
101
102 /* Get the actual SASL message */
104 if (pq_getmessage(&buf, mech->max_message_length))
105 {
106 /* EOF - pq_getmessage already logged error */
107 pfree(buf.data);
108 return STATUS_ERROR;
109 }
110
111 elog(DEBUG4, "processing received SASL response of length %d", buf.len);
112
113 /*
114 * The first SASLInitialResponse message is different from the others.
115 * It indicates which SASL mechanism the client selected, and contains
116 * an optional Initial Client Response payload. The subsequent
117 * SASLResponse messages contain just the SASL payload.
118 */
119 if (initial)
120 {
121 const char *selected_mech;
122
124
125 /*
126 * Initialize the status tracker for message exchanges.
127 *
128 * If the user doesn't exist, or doesn't have a valid password, or
129 * it's expired, we still go through the motions of SASL
130 * authentication, but tell the authentication method that the
131 * authentication is "doomed". That is, it's going to fail, no
132 * matter what.
133 *
134 * This is because we don't want to reveal to an attacker what
135 * usernames are valid, nor which users have a valid password.
136 */
138
140 if (inputlen == -1)
141 input = NULL;
142 else
144
145 initial = false;
146 }
147 else
148 {
149 inputlen = buf.len;
150 input = pq_getmsgbytes(&buf, buf.len);
151 }
153
154 /*
155 * The StringInfo guarantees that there's a \0 byte after the
156 * response.
157 */
158 Assert(input == NULL || input[inputlen] == '\0');
159
160 /*
161 * Hand the incoming message to the mechanism implementation.
162 */
163 result = mech->exchange(opaq, input, inputlen,
164 &output, &outputlen,
165 logdetail);
166
167 /* input buffer no longer used */
168 pfree(buf.data);
169
170 if (output)
171 {
172 /*
173 * PG_SASL_EXCHANGE_FAILURE with some output is forbidden by SASL.
174 * Make sure here that the mechanism used got that right.
175 */
177 elog(ERROR, "output message found after SASL exchange failure");
178
179 /*
180 * Negotiation generated data to be sent to the client.
181 */
182 elog(DEBUG4, "sending SASL challenge of length %d", outputlen);
183
186 else
188
189 pfree(output);
190 }
192
194 {
195 if (!abandoned)
196 {
197 /*
198 * Programmer error: caller needs to track the abandoned state for
199 * this mechanism.
200 */
201 elog(ERROR, "SASL exchange was abandoned, but CheckSASLAuth isn't tracking it");
202 }
203
204 *abandoned = true;
205 }
206
207 /* Oops, Something bad happened */
209 {
210 return STATUS_ERROR;
211 }
212
213 return STATUS_OK;
214}
void sendAuthRequest(Port *port, AuthRequest areq, const void *extradata, int extralen)
Definition auth.c:682
#define STATUS_OK
Definition c.h:1258
#define Assert(condition)
Definition c.h:943
#define STATUS_EOF
Definition c.h:1260
#define STATUS_ERROR
Definition c.h:1259
uint32 result
int errcode(int sqlerrcode)
Definition elog.c:874
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
#define DEBUG4
Definition elog.h:28
#define ERRCODE_PROTOCOL_VIOLATION
Definition fe-connect.c:96
FILE * input
FILE * output
void pfree(void *pointer)
Definition mcxt.c:1616
static char * errmsg
static int port
Definition pg_regress.c:117
static char buf[DEFAULT_XLOG_SEG_SIZE]
int pq_getmessage(StringInfo s, int maxlen)
Definition pqcomm.c:1204
int pq_getbyte(void)
Definition pqcomm.c:964
void pq_startmsgread(void)
Definition pqcomm.c:1142
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition pqformat.c:414
void pq_getmsgend(StringInfo msg)
Definition pqformat.c:634
const char * pq_getmsgrawstring(StringInfo msg)
Definition pqformat.c:607
const char * pq_getmsgbytes(StringInfo msg, int datalen)
Definition pqformat.c:507
static int fb(int x)
#define AUTH_REQ_SASL_CONT
Definition protocol.h:107
#define PqMsg_SASLResponse
Definition protocol.h:33
#define AUTH_REQ_SASL
Definition protocol.h:106
#define AUTH_REQ_SASL_FIN
Definition protocol.h:108
#define PG_SASL_EXCHANGE_FAILURE
Definition sasl.h:27
#define PG_SASL_EXCHANGE_CONTINUE
Definition sasl.h:25
#define PG_SASL_EXCHANGE_ABANDONED
Definition sasl.h:28
#define PG_SASL_EXCHANGE_SUCCESS
Definition sasl.h:26
void appendStringInfoChar(StringInfo str, char ch)
Definition stringinfo.c:242
void initStringInfo(StringInfo str)
Definition stringinfo.c:97

References appendStringInfoChar(), Assert, AUTH_REQ_SASL, AUTH_REQ_SASL_CONT, AUTH_REQ_SASL_FIN, buf, DEBUG4, elog, ereport, errcode(), ERRCODE_PROTOCOL_VIOLATION, errmsg, ERROR, fb(), initStringInfo(), input, output, pfree(), PG_SASL_EXCHANGE_ABANDONED, PG_SASL_EXCHANGE_CONTINUE, PG_SASL_EXCHANGE_FAILURE, PG_SASL_EXCHANGE_SUCCESS, port, pq_getbyte(), pq_getmessage(), pq_getmsgbytes(), pq_getmsgend(), pq_getmsgint(), pq_getmsgrawstring(), pq_startmsgread(), PqMsg_SASLResponse, result, sendAuthRequest(), STATUS_EOF, STATUS_ERROR, and STATUS_OK.

Referenced by CheckPWChallengeAuth(), and ClientAuthentication().