PostgreSQL Source Code git master
be-secure-gssapi.c File Reference
#include "postgres.h"
#include <unistd.h>
#include "libpq/auth.h"
#include "libpq/be-gssapi-common.h"
#include "libpq/libpq.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "port/pg_bswap.h"
#include "utils/injection_point.h"
#include "utils/memutils.h"
Include dependency graph for be-secure-gssapi.c:

Go to the source code of this file.

Macros

#define PQ_GSS_MAX_PACKET_SIZE   16384 /* includes uint32 header word */
 
#define PQ_GSS_AUTH_BUFFER_SIZE   65536 /* includes uint32 header word */
 

Functions

ssize_t be_gssapi_write (Port *port, const void *ptr, size_t len)
 
ssize_t be_gssapi_read (Port *port, void *ptr, size_t len)
 
static ssize_t read_or_wait (Port *port, ssize_t len)
 
ssize_t secure_open_gssapi (Port *port)
 
bool be_gssapi_get_auth (Port *port)
 
bool be_gssapi_get_enc (Port *port)
 
const char * be_gssapi_get_princ (Port *port)
 
bool be_gssapi_get_delegation (Port *port)
 

Variables

static char * PqGSSSendBuffer
 
static int PqGSSSendLength
 
static int PqGSSSendNext
 
static int PqGSSSendConsumed
 
static char * PqGSSRecvBuffer
 
static int PqGSSRecvLength
 
static char * PqGSSResultBuffer
 
static int PqGSSResultLength
 
static int PqGSSResultNext
 
static uint32 PqGSSMaxPktSize
 

Macro Definition Documentation

◆ PQ_GSS_AUTH_BUFFER_SIZE

#define PQ_GSS_AUTH_BUFFER_SIZE   65536 /* includes uint32 header word */

Definition at line 60 of file be-secure-gssapi.c.

◆ PQ_GSS_MAX_PACKET_SIZE

#define PQ_GSS_MAX_PACKET_SIZE   16384 /* includes uint32 header word */

Definition at line 52 of file be-secure-gssapi.c.

Function Documentation

◆ be_gssapi_get_auth()

bool be_gssapi_get_auth ( Port port)

Definition at line 744 of file be-secure-gssapi.c.

745{
746 if (!port || !port->gss)
747 return false;
748
749 return port->gss->auth;
750}
static int port
Definition: pg_regress.c:115

References port.

Referenced by PerformAuthentication(), and pgstat_bestart_security().

◆ be_gssapi_get_delegation()

bool be_gssapi_get_delegation ( Port port)

Definition at line 782 of file be-secure-gssapi.c.

783{
784 if (!port || !port->gss)
785 return false;
786
787 return port->gss->delegated_creds;
788}

References port.

Referenced by check_conn_params(), dblink_connstr_check(), dblink_security_check(), PerformAuthentication(), pgfdw_security_check(), and pgstat_bestart_security().

◆ be_gssapi_get_enc()

bool be_gssapi_get_enc ( Port port)

Definition at line 756 of file be-secure-gssapi.c.

757{
758 if (!port || !port->gss)
759 return false;
760
761 return port->gss->enc;
762}

References port.

Referenced by PerformAuthentication(), and pgstat_bestart_security().

◆ be_gssapi_get_princ()

const char * be_gssapi_get_princ ( Port port)

Definition at line 769 of file be-secure-gssapi.c.

770{
771 if (!port || !port->gss)
772 return NULL;
773
774 return port->gss->princ;
775}

References port.

Referenced by PerformAuthentication(), and pgstat_bestart_security().

◆ be_gssapi_read()

ssize_t be_gssapi_read ( Port port,
void *  ptr,
size_t  len 
)

Definition at line 270 of file be-secure-gssapi.c.

271{
272 OM_uint32 major,
273 minor;
274 gss_buffer_desc input,
275 output;
276 ssize_t ret;
277 size_t bytes_returned = 0;
278 gss_ctx_id_t gctx = port->gss->ctx;
279
280 /*
281 * The plan here is to read one incoming encrypted packet into
282 * PqGSSRecvBuffer, decrypt it into PqGSSResultBuffer, and then dole out
283 * data from there to the caller. When we exhaust the current input
284 * packet, read another.
285 */
286 while (bytes_returned < len)
287 {
288 int conf_state = 0;
289
290 /* Check if we have data in our buffer that we can return immediately */
292 {
293 size_t bytes_in_buffer = PqGSSResultLength - PqGSSResultNext;
294 size_t bytes_to_copy = Min(bytes_in_buffer, len - bytes_returned);
295
296 /*
297 * Copy the data from our result buffer into the caller's buffer,
298 * at the point where we last left off filling their buffer.
299 */
300 memcpy((char *) ptr + bytes_returned, PqGSSResultBuffer + PqGSSResultNext, bytes_to_copy);
301 PqGSSResultNext += bytes_to_copy;
302 bytes_returned += bytes_to_copy;
303
304 /*
305 * At this point, we've either filled the caller's buffer or
306 * emptied our result buffer. Either way, return to caller. In
307 * the second case, we could try to read another encrypted packet,
308 * but the odds are good that there isn't one available. (If this
309 * isn't true, we chose too small a max packet size.) In any
310 * case, there's no harm letting the caller process the data we've
311 * already returned.
312 */
313 break;
314 }
315
316 /* Result buffer is empty, so reset buffer pointers */
318
319 /*
320 * Because we chose above to return immediately as soon as we emit
321 * some data, bytes_returned must be zero at this point. Therefore
322 * the failure exits below can just return -1 without worrying about
323 * whether we already emitted some data.
324 */
325 Assert(bytes_returned == 0);
326
327 /*
328 * At this point, our result buffer is empty with more bytes being
329 * requested to be read. We are now ready to load the next packet and
330 * decrypt it (entirely) into our result buffer.
331 */
332
333 /* Collect the length if we haven't already */
334 if (PqGSSRecvLength < sizeof(uint32))
335 {
337 sizeof(uint32) - PqGSSRecvLength);
338
339 /* If ret <= 0, secure_raw_read already set the correct errno */
340 if (ret <= 0)
341 return ret;
342
343 PqGSSRecvLength += ret;
344
345 /* If we still haven't got the length, return to the caller */
346 if (PqGSSRecvLength < sizeof(uint32))
347 {
348 errno = EWOULDBLOCK;
349 return -1;
350 }
351 }
352
353 /* Decode the packet length and check for overlength packet */
354 input.length = pg_ntoh32(*(uint32 *) PqGSSRecvBuffer);
355
356 if (input.length > PQ_GSS_MAX_PACKET_SIZE - sizeof(uint32))
357 {
359 (errmsg("oversize GSSAPI packet sent by the client (%zu > %zu)",
360 (size_t) input.length,
361 PQ_GSS_MAX_PACKET_SIZE - sizeof(uint32))));
362 errno = ECONNRESET;
363 return -1;
364 }
365
366 /*
367 * Read as much of the packet as we are able to on this call into
368 * wherever we left off from the last time we were called.
369 */
371 input.length - (PqGSSRecvLength - sizeof(uint32)));
372 /* If ret <= 0, secure_raw_read already set the correct errno */
373 if (ret <= 0)
374 return ret;
375
376 PqGSSRecvLength += ret;
377
378 /* If we don't yet have the whole packet, return to the caller */
379 if (PqGSSRecvLength - sizeof(uint32) < input.length)
380 {
381 errno = EWOULDBLOCK;
382 return -1;
383 }
384
385 /*
386 * We now have the full packet and we can perform the decryption and
387 * refill our result buffer, then loop back up to pass data back to
388 * the caller.
389 */
390 output.value = NULL;
391 output.length = 0;
392 input.value = PqGSSRecvBuffer + sizeof(uint32);
393
394 major = gss_unwrap(&minor, gctx, &input, &output, &conf_state, NULL);
395 if (major != GSS_S_COMPLETE)
396 {
397 pg_GSS_error(_("GSSAPI unwrap error"), major, minor);
398 errno = ECONNRESET;
399 return -1;
400 }
401 if (conf_state == 0)
402 {
404 (errmsg("incoming GSSAPI message did not use confidentiality")));
405 errno = ECONNRESET;
406 return -1;
407 }
408
409 memcpy(PqGSSResultBuffer, output.value, output.length);
410 PqGSSResultLength = output.length;
411
412 /* Our receive buffer is now empty, reset it */
413 PqGSSRecvLength = 0;
414
415 /* Release buffer storage allocated by GSSAPI */
416 gss_release_buffer(&minor, &output);
417 }
418
419 return bytes_returned;
420}
void pg_GSS_error(const char *errmsg, OM_uint32 maj_stat, OM_uint32 min_stat)
static int PqGSSRecvLength
static int PqGSSResultLength
static char * PqGSSRecvBuffer
static int PqGSSResultNext
static char * PqGSSResultBuffer
#define PQ_GSS_MAX_PACKET_SIZE
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
Definition: be-secure.c:268
#define Min(x, y)
Definition: c.h:1008
uint32_t uint32
Definition: c.h:543
int errmsg(const char *fmt,...)
Definition: elog.c:1080
#define _(x)
Definition: elog.c:91
#define COMMERROR
Definition: elog.h:33
#define ereport(elevel,...)
Definition: elog.h:150
Assert(PointerIsAligned(start, uint64))
FILE * input
FILE * output
#define pg_ntoh32(x)
Definition: pg_bswap.h:125
const void size_t len
#define EWOULDBLOCK
Definition: win32_port.h:370
#define ECONNRESET
Definition: win32_port.h:374

References _, Assert(), COMMERROR, ECONNRESET, ereport, errmsg(), EWOULDBLOCK, input, len, Min, output, pg_GSS_error(), pg_ntoh32, port, PQ_GSS_MAX_PACKET_SIZE, PqGSSRecvBuffer, PqGSSRecvLength, PqGSSResultBuffer, PqGSSResultLength, PqGSSResultNext, and secure_raw_read().

Referenced by secure_read().

◆ be_gssapi_write()

ssize_t be_gssapi_write ( Port port,
const void *  ptr,
size_t  len 
)

Definition at line 103 of file be-secure-gssapi.c.

104{
105 OM_uint32 major,
106 minor;
107 gss_buffer_desc input,
108 output;
109 size_t bytes_to_encrypt;
110 size_t bytes_encrypted;
111 gss_ctx_id_t gctx = port->gss->ctx;
112
113 /*
114 * When we get a retryable failure, we must not tell the caller we have
115 * successfully transmitted everything, else it won't retry. For
116 * simplicity, we claim we haven't transmitted anything until we have
117 * successfully transmitted all "len" bytes. Between calls, the amount of
118 * the current input data that's already been encrypted and placed into
119 * PqGSSSendBuffer (and perhaps transmitted) is remembered in
120 * PqGSSSendConsumed. On a retry, the caller *must* be sending that data
121 * again, so if it offers a len less than that, something is wrong.
122 *
123 * Note: it may seem attractive to report partial write completion once
124 * we've successfully sent any encrypted packets. However, doing that
125 * expands the state space of this processing and has been responsible for
126 * bugs in the past (cf. commit d053a879b). We won't save much,
127 * typically, by letting callers discard data early, so don't risk it.
128 */
130 {
131 elog(COMMERROR, "GSSAPI caller failed to retransmit all data needing to be retried");
132 errno = ECONNRESET;
133 return -1;
134 }
135
136 /* Discount whatever source data we already encrypted. */
137 bytes_to_encrypt = len - PqGSSSendConsumed;
138 bytes_encrypted = PqGSSSendConsumed;
139
140 /*
141 * Loop through encrypting data and sending it out until it's all done or
142 * secure_raw_write() complains (which would likely mean that the socket
143 * is non-blocking and the requested send() would block, or there was some
144 * kind of actual error).
145 */
146 while (bytes_to_encrypt || PqGSSSendLength)
147 {
148 int conf_state = 0;
149 uint32 netlen;
150
151 /*
152 * Check if we have data in the encrypted output buffer that needs to
153 * be sent (possibly left over from a previous call), and if so, try
154 * to send it. If we aren't able to, return that fact back up to the
155 * caller.
156 */
157 if (PqGSSSendLength)
158 {
159 ssize_t ret;
160 ssize_t amount = PqGSSSendLength - PqGSSSendNext;
161
163 if (ret <= 0)
164 return ret;
165
166 /*
167 * Check if this was a partial write, and if so, move forward that
168 * far in our buffer and try again.
169 */
170 if (ret < amount)
171 {
172 PqGSSSendNext += ret;
173 continue;
174 }
175
176 /* We've successfully sent whatever data was in the buffer. */
178 }
179
180 /*
181 * Check if there are any bytes left to encrypt. If not, we're done.
182 */
183 if (!bytes_to_encrypt)
184 break;
185
186 /*
187 * Check how much we are being asked to send, if it's too much, then
188 * we will have to loop and possibly be called multiple times to get
189 * through all the data.
190 */
191 if (bytes_to_encrypt > PqGSSMaxPktSize)
192 input.length = PqGSSMaxPktSize;
193 else
194 input.length = bytes_to_encrypt;
195
196 input.value = (char *) ptr + bytes_encrypted;
197
198 output.value = NULL;
199 output.length = 0;
200
201 /*
202 * Create the next encrypted packet. Any failure here is considered a
203 * hard failure, so we return -1 even if some data has been sent.
204 */
205 major = gss_wrap(&minor, gctx, 1, GSS_C_QOP_DEFAULT,
206 &input, &conf_state, &output);
207 if (major != GSS_S_COMPLETE)
208 {
209 pg_GSS_error(_("GSSAPI wrap error"), major, minor);
210 errno = ECONNRESET;
211 return -1;
212 }
213 if (conf_state == 0)
214 {
216 (errmsg("outgoing GSSAPI message would not use confidentiality")));
217 errno = ECONNRESET;
218 return -1;
219 }
220 if (output.length > PQ_GSS_MAX_PACKET_SIZE - sizeof(uint32))
221 {
223 (errmsg("server tried to send oversize GSSAPI packet (%zu > %zu)",
224 (size_t) output.length,
225 PQ_GSS_MAX_PACKET_SIZE - sizeof(uint32))));
226 errno = ECONNRESET;
227 return -1;
228 }
229
230 bytes_encrypted += input.length;
231 bytes_to_encrypt -= input.length;
232 PqGSSSendConsumed += input.length;
233
234 /* 4 network-order bytes of length, then payload */
235 netlen = pg_hton32(output.length);
236 memcpy(PqGSSSendBuffer + PqGSSSendLength, &netlen, sizeof(uint32));
237 PqGSSSendLength += sizeof(uint32);
238
239 memcpy(PqGSSSendBuffer + PqGSSSendLength, output.value, output.length);
240 PqGSSSendLength += output.length;
241
242 /* Release buffer storage allocated by GSSAPI */
243 gss_release_buffer(&minor, &output);
244 }
245
246 /* If we get here, our counters should all match up. */
248 Assert(len == bytes_encrypted);
249
250 /* We're reporting all the data as sent, so reset PqGSSSendConsumed. */
252
253 return bytes_encrypted;
254}
static char * PqGSSSendBuffer
static int PqGSSSendConsumed
static uint32 PqGSSMaxPktSize
static int PqGSSSendLength
static int PqGSSSendNext
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
Definition: be-secure.c:377
#define elog(elevel,...)
Definition: elog.h:226
#define pg_hton32(x)
Definition: pg_bswap.h:121

References _, Assert(), COMMERROR, ECONNRESET, elog, ereport, errmsg(), input, len, output, pg_GSS_error(), pg_hton32, port, PQ_GSS_MAX_PACKET_SIZE, PqGSSMaxPktSize, PqGSSSendBuffer, PqGSSSendConsumed, PqGSSSendLength, PqGSSSendNext, and secure_raw_write().

Referenced by secure_write().

◆ read_or_wait()

static ssize_t read_or_wait ( Port port,
ssize_t  len 
)
static

Definition at line 431 of file be-secure-gssapi.c.

432{
433 ssize_t ret;
434
435 /*
436 * Keep going until we either read in everything we were asked to, or we
437 * error out.
438 */
439 while (PqGSSRecvLength < len)
440 {
442
443 /*
444 * If we got back an error and it wasn't just
445 * EWOULDBLOCK/EAGAIN/EINTR, then give up.
446 */
447 if (ret < 0 &&
448 !(errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR))
449 return -1;
450
451 /*
452 * Ok, we got back either a positive value, zero, or a negative result
453 * indicating we should retry.
454 *
455 * If it was zero or negative, then we wait on the socket to be
456 * readable again.
457 */
458 if (ret <= 0)
459 {
462 port->sock, 0, WAIT_EVENT_GSS_OPEN_SERVER);
463
464 /*
465 * If we got back zero bytes, and then waited on the socket to be
466 * readable and got back zero bytes on a second read, then this is
467 * EOF and the client hung up on us.
468 *
469 * If we did get data here, then we can just fall through and
470 * handle it just as if we got data the first time.
471 *
472 * Otherwise loop back to the top and try again.
473 */
474 if (ret == 0)
475 {
477 if (ret == 0)
478 return -1;
479 }
480 if (ret < 0)
481 continue;
482 }
483
484 PqGSSRecvLength += ret;
485 }
486
487 return len;
488}
int WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
Definition: latch.c:223
#define WL_SOCKET_READABLE
Definition: waiteventset.h:35
#define WL_EXIT_ON_PM_DEATH
Definition: waiteventset.h:39
#define EINTR
Definition: win32_port.h:364
#define EAGAIN
Definition: win32_port.h:362

References EAGAIN, EINTR, EWOULDBLOCK, len, port, PqGSSRecvBuffer, PqGSSRecvLength, secure_raw_read(), WaitLatchOrSocket(), WL_EXIT_ON_PM_DEATH, and WL_SOCKET_READABLE.

Referenced by secure_open_gssapi().

◆ secure_open_gssapi()

ssize_t secure_open_gssapi ( Port port)

Definition at line 503 of file be-secure-gssapi.c.

504{
505 bool complete_next = false;
506 OM_uint32 major,
507 minor;
508 gss_cred_id_t delegated_creds;
509
510 INJECTION_POINT("backend-gssapi-startup", NULL);
511
512 /*
513 * Allocate subsidiary Port data for GSSAPI operations.
514 */
515 port->gss = (pg_gssinfo *)
516 MemoryContextAllocZero(TopMemoryContext, sizeof(pg_gssinfo));
517
518 delegated_creds = GSS_C_NO_CREDENTIAL;
519 port->gss->delegated_creds = false;
520
521 /*
522 * Allocate buffers and initialize state variables. By malloc'ing the
523 * buffers at this point, we avoid wasting static data space in processes
524 * that will never use them, and we ensure that the buffers are
525 * sufficiently aligned for the length-word accesses that we do in some
526 * places in this file.
527 *
528 * We'll use PQ_GSS_AUTH_BUFFER_SIZE-sized buffers until transport
529 * negotiation is complete, then switch to PQ_GSS_MAX_PACKET_SIZE.
530 */
536 (errcode(ERRCODE_OUT_OF_MEMORY),
537 errmsg("out of memory")));
540
541 /*
542 * Use the configured keytab, if there is one. As we now require MIT
543 * Kerberos, we might consider using the credential store extensions in
544 * the future instead of the environment variable.
545 */
546 if (pg_krb_server_keyfile != NULL && pg_krb_server_keyfile[0] != '\0')
547 {
548 if (setenv("KRB5_KTNAME", pg_krb_server_keyfile, 1) != 0)
549 {
550 /* The only likely failure cause is OOM, so use that errcode */
552 (errcode(ERRCODE_OUT_OF_MEMORY),
553 errmsg("could not set environment: %m")));
554 }
555 }
556
557 while (true)
558 {
559 ssize_t ret;
560 gss_buffer_desc input,
561 output = GSS_C_EMPTY_BUFFER;
562
563 /*
564 * The client always sends first, so try to go ahead and read the
565 * length and wait on the socket to be readable again if that fails.
566 */
567 ret = read_or_wait(port, sizeof(uint32));
568 if (ret < 0)
569 return ret;
570
571 /*
572 * Get the length for this packet from the length header.
573 */
574 input.length = pg_ntoh32(*(uint32 *) PqGSSRecvBuffer);
575
576 /* Done with the length, reset our buffer */
577 PqGSSRecvLength = 0;
578
579 /*
580 * During initialization, packets are always fully consumed and
581 * shouldn't ever be over PQ_GSS_AUTH_BUFFER_SIZE in total length.
582 *
583 * Verify on our side that the client doesn't do something funny.
584 */
585 if (input.length > PQ_GSS_AUTH_BUFFER_SIZE - sizeof(uint32))
586 {
588 (errmsg("oversize GSSAPI packet sent by the client (%zu > %zu)",
589 (size_t) input.length,
590 PQ_GSS_AUTH_BUFFER_SIZE - sizeof(uint32))));
591 return -1;
592 }
593
594 /*
595 * Get the rest of the packet so we can pass it to GSSAPI to accept
596 * the context.
597 */
598 ret = read_or_wait(port, input.length);
599 if (ret < 0)
600 return ret;
601
602 input.value = PqGSSRecvBuffer;
603
604 /* Process incoming data. (The client sends first.) */
605 major = gss_accept_sec_context(&minor, &port->gss->ctx,
606 GSS_C_NO_CREDENTIAL, &input,
607 GSS_C_NO_CHANNEL_BINDINGS,
608 &port->gss->name, NULL, &output, NULL,
609 NULL, pg_gss_accept_delegation ? &delegated_creds : NULL);
610
611 if (GSS_ERROR(major))
612 {
613 pg_GSS_error(_("could not accept GSSAPI security context"),
614 major, minor);
615 gss_release_buffer(&minor, &output);
616 return -1;
617 }
618 else if (!(major & GSS_S_CONTINUE_NEEDED))
619 {
620 /*
621 * rfc2744 technically permits context negotiation to be complete
622 * both with and without a packet to be sent.
623 */
624 complete_next = true;
625 }
626
627 if (delegated_creds != GSS_C_NO_CREDENTIAL)
628 {
629 pg_store_delegated_credential(delegated_creds);
630 port->gss->delegated_creds = true;
631 }
632
633 /* Done handling the incoming packet, reset our buffer */
634 PqGSSRecvLength = 0;
635
636 /*
637 * Check if we have data to send and, if we do, make sure to send it
638 * all
639 */
640 if (output.length > 0)
641 {
642 uint32 netlen = pg_hton32(output.length);
643
644 if (output.length > PQ_GSS_AUTH_BUFFER_SIZE - sizeof(uint32))
645 {
647 (errmsg("server tried to send oversize GSSAPI packet (%zu > %zu)",
648 (size_t) output.length,
649 PQ_GSS_AUTH_BUFFER_SIZE - sizeof(uint32))));
650 gss_release_buffer(&minor, &output);
651 return -1;
652 }
653
654 memcpy(PqGSSSendBuffer, &netlen, sizeof(uint32));
655 PqGSSSendLength += sizeof(uint32);
656
657 memcpy(PqGSSSendBuffer + PqGSSSendLength, output.value, output.length);
658 PqGSSSendLength += output.length;
659
660 /* we don't bother with PqGSSSendConsumed here */
661
663 {
666
667 /*
668 * If we got back an error and it wasn't just
669 * EWOULDBLOCK/EAGAIN/EINTR, then give up.
670 */
671 if (ret < 0 &&
672 !(errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR))
673 {
674 gss_release_buffer(&minor, &output);
675 return -1;
676 }
677
678 /* Wait and retry if we couldn't write yet */
679 if (ret <= 0)
680 {
683 port->sock, 0, WAIT_EVENT_GSS_OPEN_SERVER);
684 continue;
685 }
686
687 PqGSSSendNext += ret;
688 }
689
690 /* Done sending the packet, reset our buffer */
692
693 gss_release_buffer(&minor, &output);
694 }
695
696 /*
697 * If we got back that the connection is finished being set up, now
698 * that we've sent the last packet, exit our loop.
699 */
700 if (complete_next)
701 break;
702 }
703
704 /*
705 * Release the large authentication buffers and allocate the ones we want
706 * for normal operation.
707 */
716 (errcode(ERRCODE_OUT_OF_MEMORY),
717 errmsg("out of memory")));
720
721 /*
722 * Determine the max packet size which will fit in our buffer, after
723 * accounting for the length. be_gssapi_write will need this.
724 */
725 major = gss_wrap_size_limit(&minor, port->gss->ctx, 1, GSS_C_QOP_DEFAULT,
728
729 if (GSS_ERROR(major))
730 {
731 pg_GSS_error(_("GSSAPI size check error"), major, minor);
732 return -1;
733 }
734
735 port->gss->enc = true;
736
737 return 0;
738}
char * pg_krb_server_keyfile
Definition: auth.c:173
bool pg_gss_accept_delegation
Definition: auth.c:175
void pg_store_delegated_credential(gss_cred_id_t cred)
#define PQ_GSS_AUTH_BUFFER_SIZE
static ssize_t read_or_wait(Port *port, ssize_t len)
int errcode(int sqlerrcode)
Definition: elog.c:863
#define FATAL
Definition: elog.h:41
#define free(a)
Definition: header.h:65
#define malloc(a)
Definition: header.h:50
#define INJECTION_POINT(name, arg)
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1263
MemoryContext TopMemoryContext
Definition: mcxt.c:166
#define WL_SOCKET_WRITEABLE
Definition: waiteventset.h:36
#define setenv(x, y, z)
Definition: win32_port.h:545

References _, COMMERROR, EAGAIN, EINTR, ereport, errcode(), errmsg(), EWOULDBLOCK, FATAL, free, INJECTION_POINT, input, malloc, MemoryContextAllocZero(), output, pg_gss_accept_delegation, pg_GSS_error(), pg_hton32, pg_krb_server_keyfile, pg_ntoh32, pg_store_delegated_credential(), port, PQ_GSS_AUTH_BUFFER_SIZE, PQ_GSS_MAX_PACKET_SIZE, PqGSSMaxPktSize, PqGSSRecvBuffer, PqGSSRecvLength, PqGSSResultBuffer, PqGSSResultLength, PqGSSResultNext, PqGSSSendBuffer, PqGSSSendConsumed, PqGSSSendLength, PqGSSSendNext, read_or_wait(), secure_raw_write(), setenv, TopMemoryContext, WaitLatchOrSocket(), WL_EXIT_ON_PM_DEATH, and WL_SOCKET_WRITEABLE.

Referenced by ProcessStartupPacket().

Variable Documentation

◆ PqGSSMaxPktSize

uint32 PqGSSMaxPktSize
static

Definition at line 82 of file be-secure-gssapi.c.

Referenced by be_gssapi_write(), and secure_open_gssapi().

◆ PqGSSRecvBuffer

char* PqGSSRecvBuffer
static

Definition at line 74 of file be-secure-gssapi.c.

Referenced by be_gssapi_read(), read_or_wait(), and secure_open_gssapi().

◆ PqGSSRecvLength

int PqGSSRecvLength
static

Definition at line 75 of file be-secure-gssapi.c.

Referenced by be_gssapi_read(), read_or_wait(), and secure_open_gssapi().

◆ PqGSSResultBuffer

char* PqGSSResultBuffer
static

Definition at line 77 of file be-secure-gssapi.c.

Referenced by be_gssapi_read(), and secure_open_gssapi().

◆ PqGSSResultLength

int PqGSSResultLength
static

Definition at line 78 of file be-secure-gssapi.c.

Referenced by be_gssapi_read(), and secure_open_gssapi().

◆ PqGSSResultNext

int PqGSSResultNext
static

Definition at line 79 of file be-secure-gssapi.c.

Referenced by be_gssapi_read(), and secure_open_gssapi().

◆ PqGSSSendBuffer

char* PqGSSSendBuffer
static

Definition at line 67 of file be-secure-gssapi.c.

Referenced by be_gssapi_write(), and secure_open_gssapi().

◆ PqGSSSendConsumed

int PqGSSSendConsumed
static

Definition at line 71 of file be-secure-gssapi.c.

Referenced by be_gssapi_write(), and secure_open_gssapi().

◆ PqGSSSendLength

int PqGSSSendLength
static

Definition at line 68 of file be-secure-gssapi.c.

Referenced by be_gssapi_write(), and secure_open_gssapi().

◆ PqGSSSendNext

int PqGSSSendNext
static

Definition at line 69 of file be-secure-gssapi.c.

Referenced by be_gssapi_write(), and secure_open_gssapi().