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 "libpq/pqformat.h"
#include "miscadmin.h"
#include "pgstat.h"
Include dependency graph for be-secure-gssapi.c:

Go to the source code of this file.

Macros

#define PQ_GSS_SEND_BUFFER_SIZE   16384
 
#define PQ_GSS_RECV_BUFFER_SIZE   16384
 

Functions

ssize_t be_gssapi_write (Port *port, 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)
 

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_RECV_BUFFER_SIZE

#define PQ_GSS_RECV_BUFFER_SIZE   16384

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

Referenced by be_gssapi_read(), and secure_open_gssapi().

◆ PQ_GSS_SEND_BUFFER_SIZE

#define PQ_GSS_SEND_BUFFER_SIZE   16384

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

Referenced by be_gssapi_write(), and secure_open_gssapi().

Function Documentation

◆ be_gssapi_get_auth()

bool be_gssapi_get_auth ( Port port)

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

References Port::gss.

Referenced by pgstat_bestart().

650 {
651  if (!port || !port->gss)
652  return false;
653 
654  return port->gss->auth;
655 }
void * gss
Definition: libpq-be.h:184

◆ be_gssapi_get_enc()

bool be_gssapi_get_enc ( Port port)

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

References Port::gss.

Referenced by pgstat_bestart().

662 {
663  if (!port || !port->gss)
664  return false;
665 
666  return port->gss->enc;
667 }
void * gss
Definition: libpq-be.h:184

◆ be_gssapi_get_princ()

const char* be_gssapi_get_princ ( Port port)

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

References Port::gss.

Referenced by pgstat_bestart().

674 {
675  if (!port || !port->gss->auth)
676  return NULL;
677 
678  return port->gss->princ;
679 }
void * gss
Definition: libpq-be.h:184

◆ be_gssapi_read()

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

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

References Assert, ereport, errmsg(), EWOULDBLOCK, FATAL, gettext_noop, Port::gss, Min, output(), pg_GSS_error(), PQ_GSS_RECV_BUFFER_SIZE, PqGSSRecvBuffer, PqGSSRecvLength, PqGSSResultBuffer, PqGSSResultLength, PqGSSResultNext, and secure_raw_read().

Referenced by secure_read().

243 {
244  OM_uint32 major,
245  minor;
246  gss_buffer_desc input,
247  output;
248  ssize_t ret;
249  size_t bytes_returned = 0;
250  gss_ctx_id_t gctx = port->gss->ctx;
251 
252  /*
253  * The plan here is to read one incoming encrypted packet into
254  * PqGSSRecvBuffer, decrypt it into PqGSSResultBuffer, and then dole out
255  * data from there to the caller. When we exhaust the current input
256  * packet, read another.
257  */
258  while (bytes_returned < len)
259  {
260  int conf_state = 0;
261 
262  /* Check if we have data in our buffer that we can return immediately */
264  {
265  size_t bytes_in_buffer = PqGSSResultLength - PqGSSResultNext;
266  size_t bytes_to_copy = Min(bytes_in_buffer, len - bytes_returned);
267 
268  /*
269  * Copy the data from our result buffer into the caller's buffer,
270  * at the point where we last left off filling their buffer.
271  */
272  memcpy((char *) ptr + bytes_returned, PqGSSResultBuffer + PqGSSResultNext, bytes_to_copy);
273  PqGSSResultNext += bytes_to_copy;
274  bytes_returned += bytes_to_copy;
275 
276  /*
277  * At this point, we've either filled the caller's buffer or
278  * emptied our result buffer. Either way, return to caller. In
279  * the second case, we could try to read another encrypted packet,
280  * but the odds are good that there isn't one available. (If this
281  * isn't true, we chose too small a max packet size.) In any
282  * case, there's no harm letting the caller process the data we've
283  * already returned.
284  */
285  break;
286  }
287 
288  /* Result buffer is empty, so reset buffer pointers */
289  PqGSSResultLength = PqGSSResultNext = 0;
290 
291  /*
292  * Because we chose above to return immediately as soon as we emit
293  * some data, bytes_returned must be zero at this point. Therefore
294  * the failure exits below can just return -1 without worrying about
295  * whether we already emitted some data.
296  */
297  Assert(bytes_returned == 0);
298 
299  /*
300  * At this point, our result buffer is empty with more bytes being
301  * requested to be read. We are now ready to load the next packet and
302  * decrypt it (entirely) into our result buffer.
303  */
304 
305  /* Collect the length if we haven't already */
306  if (PqGSSRecvLength < sizeof(uint32))
307  {
309  sizeof(uint32) - PqGSSRecvLength);
310 
311  /* If ret <= 0, secure_raw_read already set the correct errno */
312  if (ret <= 0)
313  return ret;
314 
315  PqGSSRecvLength += ret;
316 
317  /* If we still haven't got the length, return to the caller */
318  if (PqGSSRecvLength < sizeof(uint32))
319  {
320  errno = EWOULDBLOCK;
321  return -1;
322  }
323  }
324 
325  /* Decode the packet length and check for overlength packet */
326  input.length = ntohl(*(uint32 *) PqGSSRecvBuffer);
327 
328  if (input.length > PQ_GSS_RECV_BUFFER_SIZE - sizeof(uint32))
329  ereport(FATAL,
330  (errmsg("oversize GSSAPI packet sent by the client (%zu > %zu)",
331  (size_t) input.length,
332  PQ_GSS_RECV_BUFFER_SIZE - sizeof(uint32))));
333 
334  /*
335  * Read as much of the packet as we are able to on this call into
336  * wherever we left off from the last time we were called.
337  */
339  input.length - (PqGSSRecvLength - sizeof(uint32)));
340  /* If ret <= 0, secure_raw_read already set the correct errno */
341  if (ret <= 0)
342  return ret;
343 
344  PqGSSRecvLength += ret;
345 
346  /* If we don't yet have the whole packet, return to the caller */
347  if (PqGSSRecvLength - sizeof(uint32) < input.length)
348  {
349  errno = EWOULDBLOCK;
350  return -1;
351  }
352 
353  /*
354  * We now have the full packet and we can perform the decryption and
355  * refill our result buffer, then loop back up to pass data back to
356  * the caller.
357  */
358  output.value = NULL;
359  output.length = 0;
360  input.value = PqGSSRecvBuffer + sizeof(uint32);
361 
362  major = gss_unwrap(&minor, gctx, &input, &output, &conf_state, NULL);
363  if (major != GSS_S_COMPLETE)
364  pg_GSS_error(FATAL, gettext_noop("GSSAPI unwrap error"),
365  major, minor);
366 
367  if (conf_state == 0)
368  ereport(FATAL,
369  (errmsg("incoming GSSAPI message did not use confidentiality")));
370 
371  memcpy(PqGSSResultBuffer, output.value, output.length);
372  PqGSSResultLength = output.length;
373 
374  /* Our receive buffer is now empty, reset it */
375  PqGSSRecvLength = 0;
376 
377  /* Release buffer storage allocated by GSSAPI */
378  gss_release_buffer(&minor, &output);
379  }
380 
381  return bytes_returned;
382 }
static int PqGSSResultNext
static void output(uint64 loop_count)
#define Min(x, y)
Definition: c.h:920
#define gettext_noop(x)
Definition: c.h:1160
static int PqGSSRecvLength
#define PQ_GSS_RECV_BUFFER_SIZE
static char * PqGSSResultBuffer
#define FATAL
Definition: elog.h:52
unsigned int uint32
Definition: c.h:367
static int PqGSSResultLength
static char * PqGSSRecvBuffer
#define ereport(elevel,...)
Definition: elog.h:144
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
Definition: be-secure.c:234
#define Assert(condition)
Definition: c.h:738
void * gss
Definition: libpq-be.h:184
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define EWOULDBLOCK
Definition: win32_port.h:329
void pg_GSS_error(int severity, const char *errmsg, OM_uint32 maj_stat, OM_uint32 min_stat)

◆ be_gssapi_write()

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

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

References Assert, elog, ereport, errmsg(), FATAL, gettext_noop, Port::gss, output(), pg_GSS_error(), PQ_GSS_SEND_BUFFER_SIZE, PqGSSMaxPktSize, PqGSSSendBuffer, PqGSSSendConsumed, PqGSSSendLength, PqGSSSendNext, and secure_raw_write().

Referenced by secure_write().

91 {
92  OM_uint32 major,
93  minor;
94  gss_buffer_desc input,
95  output;
96  size_t bytes_sent = 0;
97  size_t bytes_to_encrypt;
98  size_t bytes_encrypted;
99  gss_ctx_id_t gctx = port->gss->ctx;
100 
101  /*
102  * When we get a failure, we must not tell the caller we have successfully
103  * transmitted everything, else it won't retry. Hence a "success"
104  * (positive) return value must only count source bytes corresponding to
105  * fully-transmitted encrypted packets. The amount of source data
106  * corresponding to the current partly-transmitted packet is remembered in
107  * PqGSSSendConsumed. On a retry, the caller *must* be sending that data
108  * again, so if it offers a len less than that, something is wrong.
109  */
110  if (len < PqGSSSendConsumed)
111  elog(FATAL, "GSSAPI caller failed to retransmit all data needing to be retried");
112 
113  /* Discount whatever source data we already encrypted. */
114  bytes_to_encrypt = len - PqGSSSendConsumed;
115  bytes_encrypted = PqGSSSendConsumed;
116 
117  /*
118  * Loop through encrypting data and sending it out until it's all done or
119  * secure_raw_write() complains (which would likely mean that the socket
120  * is non-blocking and the requested send() would block, or there was some
121  * kind of actual error).
122  */
123  while (bytes_to_encrypt || PqGSSSendLength)
124  {
125  int conf_state = 0;
126  uint32 netlen;
127 
128  /*
129  * Check if we have data in the encrypted output buffer that needs to
130  * be sent (possibly left over from a previous call), and if so, try
131  * to send it. If we aren't able to, return that fact back up to the
132  * caller.
133  */
134  if (PqGSSSendLength)
135  {
136  ssize_t ret;
137  ssize_t amount = PqGSSSendLength - PqGSSSendNext;
138 
139  ret = secure_raw_write(port, PqGSSSendBuffer + PqGSSSendNext, amount);
140  if (ret <= 0)
141  {
142  /*
143  * Report any previously-sent data; if there was none, reflect
144  * the secure_raw_write result up to our caller. When there
145  * was some, we're effectively assuming that any interesting
146  * failure condition will recur on the next try.
147  */
148  if (bytes_sent)
149  return bytes_sent;
150  return ret;
151  }
152 
153  /*
154  * Check if this was a partial write, and if so, move forward that
155  * far in our buffer and try again.
156  */
157  if (ret != amount)
158  {
159  PqGSSSendNext += ret;
160  continue;
161  }
162 
163  /* We've successfully sent whatever data was in that packet. */
164  bytes_sent += PqGSSSendConsumed;
165 
166  /* All encrypted data was sent, our buffer is empty now. */
167  PqGSSSendLength = PqGSSSendNext = PqGSSSendConsumed = 0;
168  }
169 
170  /*
171  * Check if there are any bytes left to encrypt. If not, we're done.
172  */
173  if (!bytes_to_encrypt)
174  break;
175 
176  /*
177  * Check how much we are being asked to send, if it's too much, then
178  * we will have to loop and possibly be called multiple times to get
179  * through all the data.
180  */
181  if (bytes_to_encrypt > PqGSSMaxPktSize)
182  input.length = PqGSSMaxPktSize;
183  else
184  input.length = bytes_to_encrypt;
185 
186  input.value = (char *) ptr + bytes_encrypted;
187 
188  output.value = NULL;
189  output.length = 0;
190 
191  /* Create the next encrypted packet */
192  major = gss_wrap(&minor, gctx, 1, GSS_C_QOP_DEFAULT,
193  &input, &conf_state, &output);
194  if (major != GSS_S_COMPLETE)
195  pg_GSS_error(FATAL, gettext_noop("GSSAPI wrap error"), major, minor);
196 
197  if (conf_state == 0)
198  ereport(FATAL,
199  (errmsg("outgoing GSSAPI message would not use confidentiality")));
200 
201  if (output.length > PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32))
202  ereport(FATAL,
203  (errmsg("server tried to send oversize GSSAPI packet (%zu > %zu)",
204  (size_t) output.length,
205  PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32))));
206 
207  bytes_encrypted += input.length;
208  bytes_to_encrypt -= input.length;
209  PqGSSSendConsumed += input.length;
210 
211  /* 4 network-order bytes of length, then payload */
212  netlen = htonl(output.length);
213  memcpy(PqGSSSendBuffer + PqGSSSendLength, &netlen, sizeof(uint32));
214  PqGSSSendLength += sizeof(uint32);
215 
216  memcpy(PqGSSSendBuffer + PqGSSSendLength, output.value, output.length);
217  PqGSSSendLength += output.length;
218 
219  /* Release buffer storage allocated by GSSAPI */
220  gss_release_buffer(&minor, &output);
221  }
222 
223  /* If we get here, our counters should all match up. */
224  Assert(bytes_sent == len);
225  Assert(bytes_sent == bytes_encrypted);
226 
227  return bytes_sent;
228 }
static int PqGSSSendConsumed
static void output(uint64 loop_count)
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
Definition: be-secure.c:330
#define gettext_noop(x)
Definition: c.h:1160
static int PqGSSSendLength
#define FATAL
Definition: elog.h:52
unsigned int uint32
Definition: c.h:367
static int PqGSSSendNext
static uint32 PqGSSMaxPktSize
static char * PqGSSSendBuffer
#define ereport(elevel,...)
Definition: elog.h:144
#define Assert(condition)
Definition: c.h:738
#define PQ_GSS_SEND_BUFFER_SIZE
void * gss
Definition: libpq-be.h:184
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
void pg_GSS_error(int severity, const char *errmsg, OM_uint32 maj_stat, OM_uint32 min_stat)

◆ read_or_wait()

static ssize_t read_or_wait ( Port port,
ssize_t  len 
)
static

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

References EAGAIN, EINTR, EWOULDBLOCK, MyLatch, PqGSSRecvBuffer, PqGSSRecvLength, secure_raw_read(), Port::sock, WAIT_EVENT_GSS_OPEN_SERVER, WaitLatchOrSocket(), WL_EXIT_ON_PM_DEATH, and WL_SOCKET_READABLE.

Referenced by secure_open_gssapi().

394 {
395  ssize_t ret;
396 
397  /*
398  * Keep going until we either read in everything we were asked to, or we
399  * error out.
400  */
401  while (PqGSSRecvLength < len)
402  {
404 
405  /*
406  * If we got back an error and it wasn't just
407  * EWOULDBLOCK/EAGAIN/EINTR, then give up.
408  */
409  if (ret < 0 &&
410  !(errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR))
411  return -1;
412 
413  /*
414  * Ok, we got back either a positive value, zero, or a negative result
415  * indicating we should retry.
416  *
417  * If it was zero or negative, then we wait on the socket to be
418  * readable again.
419  */
420  if (ret <= 0)
421  {
424  port->sock, 0, WAIT_EVENT_GSS_OPEN_SERVER);
425 
426  /*
427  * If we got back zero bytes, and then waited on the socket to be
428  * readable and got back zero bytes on a second read, then this is
429  * EOF and the client hung up on us.
430  *
431  * If we did get data here, then we can just fall through and
432  * handle it just as if we got data the first time.
433  *
434  * Otherwise loop back to the top and try again.
435  */
436  if (ret == 0)
437  {
439  if (ret == 0)
440  return -1;
441  }
442  if (ret < 0)
443  continue;
444  }
445 
446  PqGSSRecvLength += ret;
447  }
448 
449  return len;
450 }
#define EAGAIN
Definition: win32_port.h:321
#define WL_SOCKET_READABLE
Definition: latch.h:125
pgsocket sock
Definition: libpq-be.h:122
static int PqGSSRecvLength
int WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
Definition: latch.c:390
static char * PqGSSRecvBuffer
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
Definition: be-secure.c:234
struct Latch * MyLatch
Definition: globals.c:54
#define EWOULDBLOCK
Definition: win32_port.h:329
#define EINTR
Definition: win32_port.h:323
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:129

◆ secure_open_gssapi()

ssize_t secure_open_gssapi ( Port port)

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

References EAGAIN, EINTR, ereport, errcode(), errmsg(), ERROR, EWOULDBLOCK, FATAL, gettext_noop, Port::gss, malloc, MyLatch, output(), pg_GSS_error(), pg_krb_server_keyfile, PQ_GSS_RECV_BUFFER_SIZE, PQ_GSS_SEND_BUFFER_SIZE, PqGSSMaxPktSize, PqGSSRecvBuffer, PqGSSRecvLength, PqGSSResultBuffer, PqGSSResultLength, PqGSSResultNext, PqGSSSendBuffer, PqGSSSendConsumed, PqGSSSendLength, PqGSSSendNext, read_or_wait(), secure_raw_write(), Port::sock, WAIT_EVENT_GSS_OPEN_SERVER, WaitLatchOrSocket(), WL_EXIT_ON_PM_DEATH, and WL_SOCKET_WRITEABLE.

Referenced by ProcessStartupPacket().

466 {
467  bool complete_next = false;
468  OM_uint32 major,
469  minor;
470 
471  /*
472  * Allocate buffers and initialize state variables. By malloc'ing the
473  * buffers at this point, we avoid wasting static data space in processes
474  * that will never use them, and we ensure that the buffers are
475  * sufficiently aligned for the length-word accesses that we do in some
476  * places in this file.
477  */
482  ereport(FATAL,
483  (errcode(ERRCODE_OUT_OF_MEMORY),
484  errmsg("out of memory")));
487 
488  /*
489  * Use the configured keytab, if there is one. Unfortunately, Heimdal
490  * doesn't support the cred store extensions, so use the env var.
491  */
492  if (pg_krb_server_keyfile != NULL && strlen(pg_krb_server_keyfile) > 0)
493  setenv("KRB5_KTNAME", pg_krb_server_keyfile, 1);
494 
495  while (true)
496  {
497  ssize_t ret;
498  gss_buffer_desc input,
499  output = GSS_C_EMPTY_BUFFER;
500 
501  /*
502  * The client always sends first, so try to go ahead and read the
503  * length and wait on the socket to be readable again if that fails.
504  */
505  ret = read_or_wait(port, sizeof(uint32));
506  if (ret < 0)
507  return ret;
508 
509  /*
510  * Get the length for this packet from the length header.
511  */
512  input.length = ntohl(*(uint32 *) PqGSSRecvBuffer);
513 
514  /* Done with the length, reset our buffer */
515  PqGSSRecvLength = 0;
516 
517  /*
518  * During initialization, packets are always fully consumed and
519  * shouldn't ever be over PQ_GSS_RECV_BUFFER_SIZE in length.
520  *
521  * Verify on our side that the client doesn't do something funny.
522  */
523  if (input.length > PQ_GSS_RECV_BUFFER_SIZE)
524  ereport(FATAL,
525  (errmsg("oversize GSSAPI packet sent by the client (%zu > %d)",
526  (size_t) input.length,
528 
529  /*
530  * Get the rest of the packet so we can pass it to GSSAPI to accept
531  * the context.
532  */
533  ret = read_or_wait(port, input.length);
534  if (ret < 0)
535  return ret;
536 
537  input.value = PqGSSRecvBuffer;
538 
539  /* Process incoming data. (The client sends first.) */
540  major = gss_accept_sec_context(&minor, &port->gss->ctx,
541  GSS_C_NO_CREDENTIAL, &input,
542  GSS_C_NO_CHANNEL_BINDINGS,
543  &port->gss->name, NULL, &output, NULL,
544  NULL, NULL);
545  if (GSS_ERROR(major))
546  {
547  pg_GSS_error(ERROR, gettext_noop("could not accept GSSAPI security context"),
548  major, minor);
549  gss_release_buffer(&minor, &output);
550  return -1;
551  }
552  else if (!(major & GSS_S_CONTINUE_NEEDED))
553  {
554  /*
555  * rfc2744 technically permits context negotiation to be complete
556  * both with and without a packet to be sent.
557  */
558  complete_next = true;
559  }
560 
561  /* Done handling the incoming packet, reset our buffer */
562  PqGSSRecvLength = 0;
563 
564  /*
565  * Check if we have data to send and, if we do, make sure to send it
566  * all
567  */
568  if (output.length > 0)
569  {
570  uint32 netlen = htonl(output.length);
571 
572  if (output.length > PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32))
573  ereport(FATAL,
574  (errmsg("server tried to send oversize GSSAPI packet (%zu > %zu)",
575  (size_t) output.length,
576  PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32))));
577 
578  memcpy(PqGSSSendBuffer, (char *) &netlen, sizeof(uint32));
579  PqGSSSendLength += sizeof(uint32);
580 
581  memcpy(PqGSSSendBuffer + PqGSSSendLength, output.value, output.length);
582  PqGSSSendLength += output.length;
583 
584  /* we don't bother with PqGSSSendConsumed here */
585 
587  {
590 
591  /*
592  * If we got back an error and it wasn't just
593  * EWOULDBLOCK/EAGAIN/EINTR, then give up.
594  */
595  if (ret < 0 &&
596  !(errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR))
597  {
598  gss_release_buffer(&minor, &output);
599  return -1;
600  }
601 
602  /* Wait and retry if we couldn't write yet */
603  if (ret <= 0)
604  {
607  port->sock, 0, WAIT_EVENT_GSS_OPEN_SERVER);
608  continue;
609  }
610 
611  PqGSSSendNext += ret;
612  }
613 
614  /* Done sending the packet, reset our buffer */
616 
617  gss_release_buffer(&minor, &output);
618  }
619 
620  /*
621  * If we got back that the connection is finished being set up, now
622  * that we've sent the last packet, exit our loop.
623  */
624  if (complete_next)
625  break;
626  }
627 
628  /*
629  * Determine the max packet size which will fit in our buffer, after
630  * accounting for the length. be_gssapi_write will need this.
631  */
632  major = gss_wrap_size_limit(&minor, port->gss->ctx, 1, GSS_C_QOP_DEFAULT,
634  &PqGSSMaxPktSize);
635 
636  if (GSS_ERROR(major))
637  pg_GSS_error(FATAL, gettext_noop("GSSAPI size check error"),
638  major, minor);
639 
640  port->gss->enc = true;
641 
642  return 0;
643 }
static int PqGSSSendConsumed
#define WL_SOCKET_WRITEABLE
Definition: latch.h:126
static int PqGSSResultNext
#define EAGAIN
Definition: win32_port.h:321
static void output(uint64 loop_count)
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
Definition: be-secure.c:330
#define gettext_noop(x)
Definition: c.h:1160
int errcode(int sqlerrcode)
Definition: elog.c:610
static int PqGSSSendLength
pgsocket sock
Definition: libpq-be.h:122
static int PqGSSRecvLength
#define malloc(a)
Definition: header.h:50
#define PQ_GSS_RECV_BUFFER_SIZE
#define ERROR
Definition: elog.h:43
static char * PqGSSResultBuffer
#define FATAL
Definition: elog.h:52
int WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
Definition: latch.c:390
unsigned int uint32
Definition: c.h:367
static int PqGSSSendNext
static uint32 PqGSSMaxPktSize
static int PqGSSResultLength
static char * PqGSSRecvBuffer
static char * PqGSSSendBuffer
#define ereport(elevel,...)
Definition: elog.h:144
static ssize_t read_or_wait(Port *port, ssize_t len)
#define PQ_GSS_SEND_BUFFER_SIZE
char * pg_krb_server_keyfile
Definition: auth.c:169
void * gss
Definition: libpq-be.h:184
int errmsg(const char *fmt,...)
Definition: elog.c:824
struct Latch * MyLatch
Definition: globals.c:54
#define EWOULDBLOCK
Definition: win32_port.h:329
#define EINTR
Definition: win32_port.h:323
void pg_GSS_error(int severity, const char *errmsg, OM_uint32 maj_stat, OM_uint32 min_stat)
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:129

Variable Documentation

◆ PqGSSMaxPktSize

uint32 PqGSSMaxPktSize
static

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

Referenced by be_gssapi_write(), and secure_open_gssapi().

◆ PqGSSRecvBuffer

char* PqGSSRecvBuffer
static

Definition at line 65 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 66 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 68 of file be-secure-gssapi.c.

Referenced by be_gssapi_read(), and secure_open_gssapi().

◆ PqGSSResultLength

int PqGSSResultLength
static

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

Referenced by be_gssapi_read(), and secure_open_gssapi().

◆ PqGSSResultNext

int PqGSSResultNext
static

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

Referenced by be_gssapi_read(), and secure_open_gssapi().

◆ PqGSSSendBuffer

char* PqGSSSendBuffer
static

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

Referenced by be_gssapi_write(), and secure_open_gssapi().

◆ PqGSSSendConsumed

int PqGSSSendConsumed
static

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

Referenced by be_gssapi_write(), and secure_open_gssapi().

◆ PqGSSSendLength

int PqGSSSendLength
static

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

Referenced by be_gssapi_write(), and secure_open_gssapi().

◆ PqGSSSendNext

int PqGSSSendNext
static

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

Referenced by be_gssapi_write(), and secure_open_gssapi().