Fix timing-dependent failure in GSSAPI data transmission.
[pgsql.git] / src / interfaces / libpq / fe-secure-gssapi.c
blob1b750d69447780a1c8f5bf8f7f48ef0670ac77b5
1 /*-------------------------------------------------------------------------
3 * fe-secure-gssapi.c
4 * The front-end (client) encryption support for GSSAPI
6 * Portions Copyright (c) 2016-2019, PostgreSQL Global Development Group
8 * IDENTIFICATION
9 * src/interfaces/libpq/fe-secure-gssapi.c
11 *-------------------------------------------------------------------------
14 #include "postgres_fe.h"
16 #include "libpq-fe.h"
17 #include "libpq-int.h"
18 #include "fe-gssapi-common.h"
19 #include "port/pg_bswap.h"
23 * Require encryption support, as well as mutual authentication and
24 * tamperproofing measures.
26 #define GSS_REQUIRED_FLAGS GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | \
27 GSS_C_SEQUENCE_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG
30 * Handle the encryption/decryption of data using GSSAPI.
32 * In the encrypted data stream on the wire, we break up the data
33 * into packets where each packet starts with a uint32-size length
34 * word (in network byte order), then encrypted data of that length
35 * immediately following. Decryption yields the same data stream
36 * that would appear when not using encryption.
38 * Encrypted data typically ends up being larger than the same data
39 * unencrypted, so we use fixed-size buffers for handling the
40 * encryption/decryption which are larger than PQComm's buffer will
41 * typically be to minimize the times where we have to make multiple
42 * packets (and therefore multiple recv/send calls for a single
43 * read/write call to us).
45 * NOTE: The client and server have to agree on the max packet size,
46 * because we have to pass an entire packet to GSSAPI at a time and we
47 * don't want the other side to send arbitrarily huge packets as we
48 * would have to allocate memory for them to then pass them to GSSAPI.
50 * Therefore, these two #define's are effectively part of the protocol
51 * spec and can't ever be changed.
53 #define PQ_GSS_SEND_BUFFER_SIZE 16384
54 #define PQ_GSS_RECV_BUFFER_SIZE 16384
57 * We need these state variables per-connection. To allow the functions
58 * in this file to look mostly like those in be-secure-gssapi.c, set up
59 * these macros.
61 #define PqGSSSendBuffer (conn->gss_SendBuffer)
62 #define PqGSSSendLength (conn->gss_SendLength)
63 #define PqGSSSendNext (conn->gss_SendNext)
64 #define PqGSSSendConsumed (conn->gss_SendConsumed)
65 #define PqGSSRecvBuffer (conn->gss_RecvBuffer)
66 #define PqGSSRecvLength (conn->gss_RecvLength)
67 #define PqGSSResultBuffer (conn->gss_ResultBuffer)
68 #define PqGSSResultLength (conn->gss_ResultLength)
69 #define PqGSSResultNext (conn->gss_ResultNext)
70 #define PqGSSMaxPktSize (conn->gss_MaxPktSize)
74 * Attempt to write len bytes of data from ptr to a GSSAPI-encrypted connection.
76 * The connection must be already set up for GSSAPI encryption (i.e., GSSAPI
77 * transport negotiation is complete).
79 * On success, returns the number of data bytes consumed (possibly less than
80 * len). On failure, returns -1 with errno set appropriately. If the errno
81 * indicates a non-retryable error, a message is put into conn->errorMessage.
82 * For retryable errors, caller should call again (passing the same or more
83 * data) once the socket is ready.
85 ssize_t
86 pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
88 OM_uint32 major,
89 minor;
90 gss_buffer_desc input,
91 output = GSS_C_EMPTY_BUFFER;
92 ssize_t ret = -1;
93 size_t bytes_to_encrypt;
94 size_t bytes_encrypted;
95 gss_ctx_id_t gctx = conn->gctx;
98 * When we get a retryable failure, we must not tell the caller we have
99 * successfully transmitted everything, else it won't retry. For
100 * simplicity, we claim we haven't transmitted anything until we have
101 * successfully transmitted all "len" bytes. Between calls, the amount of
102 * the current input data that's already been encrypted and placed into
103 * PqGSSSendBuffer (and perhaps transmitted) is remembered in
104 * PqGSSSendConsumed. On a retry, the caller *must* be sending that data
105 * again, so if it offers a len less than that, something is wrong.
107 * Note: it may seem attractive to report partial write completion once
108 * we've successfully sent any encrypted packets. However, that can cause
109 * problems for callers; notably, pqPutMsgEnd's heuristic to send only
110 * full 8K blocks interacts badly with such a hack. We won't save much,
111 * typically, by letting callers discard data early, so don't risk it.
113 if (len < PqGSSSendConsumed)
115 printfPQExpBuffer(&conn->errorMessage,
116 "GSSAPI caller failed to retransmit all data needing to be retried\n");
117 errno = EINVAL;
118 return -1;
121 /* Discount whatever source data we already encrypted. */
122 bytes_to_encrypt = len - PqGSSSendConsumed;
123 bytes_encrypted = PqGSSSendConsumed;
126 * Loop through encrypting data and sending it out until it's all done or
127 * pqsecure_raw_write() complains (which would likely mean that the socket
128 * is non-blocking and the requested send() would block, or there was some
129 * kind of actual error).
131 while (bytes_to_encrypt || PqGSSSendLength)
133 int conf_state = 0;
134 uint32 netlen;
137 * Check if we have data in the encrypted output buffer that needs to
138 * be sent (possibly left over from a previous call), and if so, try
139 * to send it. If we aren't able to, return that fact back up to the
140 * caller.
142 if (PqGSSSendLength)
144 ssize_t retval;
145 ssize_t amount = PqGSSSendLength - PqGSSSendNext;
147 retval = pqsecure_raw_write(conn, PqGSSSendBuffer + PqGSSSendNext, amount);
148 if (retval <= 0)
149 return retval;
152 * Check if this was a partial write, and if so, move forward that
153 * far in our buffer and try again.
155 if (retval < amount)
157 PqGSSSendNext += retval;
158 continue;
161 /* We've successfully sent whatever data was in the buffer. */
162 PqGSSSendLength = PqGSSSendNext = 0;
166 * Check if there are any bytes left to encrypt. If not, we're done.
168 if (!bytes_to_encrypt)
169 break;
172 * Check how much we are being asked to send, if it's too much, then
173 * we will have to loop and possibly be called multiple times to get
174 * through all the data.
176 if (bytes_to_encrypt > PqGSSMaxPktSize)
177 input.length = PqGSSMaxPktSize;
178 else
179 input.length = bytes_to_encrypt;
181 input.value = (char *) ptr + bytes_encrypted;
183 output.value = NULL;
184 output.length = 0;
187 * Create the next encrypted packet. Any failure here is considered a
188 * hard failure, so we return -1 even if some data has been sent.
190 major = gss_wrap(&minor, gctx, 1, GSS_C_QOP_DEFAULT,
191 &input, &conf_state, &output);
192 if (major != GSS_S_COMPLETE)
194 pg_GSS_error(libpq_gettext("GSSAPI wrap error"), conn, major, minor);
195 errno = EIO; /* for lack of a better idea */
196 goto cleanup;
199 if (conf_state == 0)
201 printfPQExpBuffer(&conn->errorMessage,
202 libpq_gettext("outgoing GSSAPI message would not use confidentiality\n"));
203 errno = EIO; /* for lack of a better idea */
204 goto cleanup;
207 if (output.length > PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32))
209 printfPQExpBuffer(&conn->errorMessage,
210 libpq_gettext("client tried to send oversize GSSAPI packet (%zu > %zu)\n"),
211 (size_t) output.length,
212 PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32));
213 errno = EIO; /* for lack of a better idea */
214 goto cleanup;
217 bytes_encrypted += input.length;
218 bytes_to_encrypt -= input.length;
219 PqGSSSendConsumed += input.length;
221 /* 4 network-order bytes of length, then payload */
222 netlen = htonl(output.length);
223 memcpy(PqGSSSendBuffer + PqGSSSendLength, &netlen, sizeof(uint32));
224 PqGSSSendLength += sizeof(uint32);
226 memcpy(PqGSSSendBuffer + PqGSSSendLength, output.value, output.length);
227 PqGSSSendLength += output.length;
229 /* Release buffer storage allocated by GSSAPI */
230 gss_release_buffer(&minor, &output);
233 /* If we get here, our counters should all match up. */
234 Assert(len == PqGSSSendConsumed);
235 Assert(len == bytes_encrypted);
237 /* We're reporting all the data as sent, so reset PqGSSSendConsumed. */
238 PqGSSSendConsumed = 0;
240 ret = bytes_encrypted;
242 cleanup:
243 /* Release GSSAPI buffer storage, if we didn't already */
244 if (output.value != NULL)
245 gss_release_buffer(&minor, &output);
246 return ret;
250 * Read up to len bytes of data into ptr from a GSSAPI-encrypted connection.
252 * The connection must be already set up for GSSAPI encryption (i.e., GSSAPI
253 * transport negotiation is complete).
255 * Returns the number of data bytes read, or on failure, returns -1
256 * with errno set appropriately. If the errno indicates a non-retryable
257 * error, a message is put into conn->errorMessage. For retryable errors,
258 * caller should call again once the socket is ready.
260 ssize_t
261 pg_GSS_read(PGconn *conn, void *ptr, size_t len)
263 OM_uint32 major,
264 minor;
265 gss_buffer_desc input = GSS_C_EMPTY_BUFFER,
266 output = GSS_C_EMPTY_BUFFER;
267 ssize_t ret;
268 size_t bytes_returned = 0;
269 gss_ctx_id_t gctx = conn->gctx;
272 * The plan here is to read one incoming encrypted packet into
273 * PqGSSRecvBuffer, decrypt it into PqGSSResultBuffer, and then dole out
274 * data from there to the caller. When we exhaust the current input
275 * packet, read another.
277 while (bytes_returned < len)
279 int conf_state = 0;
281 /* Check if we have data in our buffer that we can return immediately */
282 if (PqGSSResultNext < PqGSSResultLength)
284 size_t bytes_in_buffer = PqGSSResultLength - PqGSSResultNext;
285 size_t bytes_to_copy = Min(bytes_in_buffer, len - bytes_returned);
288 * Copy the data from our result buffer into the caller's buffer,
289 * at the point where we last left off filling their buffer.
291 memcpy((char *) ptr + bytes_returned, PqGSSResultBuffer + PqGSSResultNext, bytes_to_copy);
292 PqGSSResultNext += bytes_to_copy;
293 bytes_returned += bytes_to_copy;
296 * At this point, we've either filled the caller's buffer or
297 * emptied our result buffer. Either way, return to caller. In
298 * the second case, we could try to read another encrypted packet,
299 * but the odds are good that there isn't one available. (If this
300 * isn't true, we chose too small a max packet size.) In any
301 * case, there's no harm letting the caller process the data we've
302 * already returned.
304 break;
307 /* Result buffer is empty, so reset buffer pointers */
308 PqGSSResultLength = PqGSSResultNext = 0;
311 * Because we chose above to return immediately as soon as we emit
312 * some data, bytes_returned must be zero at this point. Therefore
313 * the failure exits below can just return -1 without worrying about
314 * whether we already emitted some data.
316 Assert(bytes_returned == 0);
319 * At this point, our result buffer is empty with more bytes being
320 * requested to be read. We are now ready to load the next packet and
321 * decrypt it (entirely) into our result buffer.
324 /* Collect the length if we haven't already */
325 if (PqGSSRecvLength < sizeof(uint32))
327 ret = pqsecure_raw_read(conn, PqGSSRecvBuffer + PqGSSRecvLength,
328 sizeof(uint32) - PqGSSRecvLength);
330 /* If ret <= 0, pqsecure_raw_read already set the correct errno */
331 if (ret <= 0)
332 return ret;
334 PqGSSRecvLength += ret;
336 /* If we still haven't got the length, return to the caller */
337 if (PqGSSRecvLength < sizeof(uint32))
339 errno = EWOULDBLOCK;
340 return -1;
344 /* Decode the packet length and check for overlength packet */
345 input.length = ntohl(*(uint32 *) PqGSSRecvBuffer);
347 if (input.length > PQ_GSS_RECV_BUFFER_SIZE - sizeof(uint32))
349 printfPQExpBuffer(&conn->errorMessage,
350 libpq_gettext("oversize GSSAPI packet sent by the server (%zu > %zu)\n"),
351 (size_t) input.length,
352 PQ_GSS_RECV_BUFFER_SIZE - sizeof(uint32));
353 errno = EIO; /* for lack of a better idea */
354 return -1;
358 * Read as much of the packet as we are able to on this call into
359 * wherever we left off from the last time we were called.
361 ret = pqsecure_raw_read(conn, PqGSSRecvBuffer + PqGSSRecvLength,
362 input.length - (PqGSSRecvLength - sizeof(uint32)));
363 /* If ret <= 0, pqsecure_raw_read already set the correct errno */
364 if (ret <= 0)
365 return ret;
367 PqGSSRecvLength += ret;
369 /* If we don't yet have the whole packet, return to the caller */
370 if (PqGSSRecvLength - sizeof(uint32) < input.length)
372 errno = EWOULDBLOCK;
373 return -1;
377 * We now have the full packet and we can perform the decryption and
378 * refill our result buffer, then loop back up to pass data back to
379 * the caller. Note that error exits below here must take care of
380 * releasing the gss output buffer.
382 output.value = NULL;
383 output.length = 0;
384 input.value = PqGSSRecvBuffer + sizeof(uint32);
386 major = gss_unwrap(&minor, gctx, &input, &output, &conf_state, NULL);
387 if (major != GSS_S_COMPLETE)
389 pg_GSS_error(libpq_gettext("GSSAPI unwrap error"), conn,
390 major, minor);
391 ret = -1;
392 errno = EIO; /* for lack of a better idea */
393 goto cleanup;
396 if (conf_state == 0)
398 printfPQExpBuffer(&conn->errorMessage,
399 libpq_gettext("incoming GSSAPI message did not use confidentiality\n"));
400 ret = -1;
401 errno = EIO; /* for lack of a better idea */
402 goto cleanup;
405 memcpy(PqGSSResultBuffer, output.value, output.length);
406 PqGSSResultLength = output.length;
408 /* Our receive buffer is now empty, reset it */
409 PqGSSRecvLength = 0;
411 /* Release buffer storage allocated by GSSAPI */
412 gss_release_buffer(&minor, &output);
415 ret = bytes_returned;
417 cleanup:
418 /* Release GSSAPI buffer storage, if we didn't already */
419 if (output.value != NULL)
420 gss_release_buffer(&minor, &output);
421 return ret;
425 * Simple wrapper for reading from pqsecure_raw_read.
427 * This takes the same arguments as pqsecure_raw_read, plus an output parameter
428 * to return the number of bytes read. This handles if blocking would occur and
429 * if we detect EOF on the connection.
431 static PostgresPollingStatusType
432 gss_read(PGconn *conn, void *recv_buffer, size_t length, ssize_t *ret)
434 *ret = pqsecure_raw_read(conn, recv_buffer, length);
435 if (*ret < 0)
437 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
438 return PGRES_POLLING_READING;
439 else
440 return PGRES_POLLING_FAILED;
443 /* Check for EOF */
444 if (*ret == 0)
446 int result = pqReadReady(conn);
448 if (result < 0)
449 return PGRES_POLLING_FAILED;
451 if (!result)
452 return PGRES_POLLING_READING;
454 *ret = pqsecure_raw_read(conn, recv_buffer, length);
455 if (*ret < 0)
457 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
458 return PGRES_POLLING_READING;
459 else
460 return PGRES_POLLING_FAILED;
462 if (*ret == 0)
463 return PGRES_POLLING_FAILED;
466 return PGRES_POLLING_OK;
470 * Negotiate GSSAPI transport for a connection. When complete, returns
471 * PGRES_POLLING_OK. Will return PGRES_POLLING_READING or
472 * PGRES_POLLING_WRITING as appropriate whenever it would block, and
473 * PGRES_POLLING_FAILED if transport could not be negotiated.
475 PostgresPollingStatusType
476 pqsecure_open_gss(PGconn *conn)
478 ssize_t ret;
479 OM_uint32 major,
480 minor;
481 uint32 netlen;
482 PostgresPollingStatusType result;
483 gss_buffer_desc input = GSS_C_EMPTY_BUFFER,
484 output = GSS_C_EMPTY_BUFFER;
487 * If first time through for this connection, allocate buffers and
488 * initialize state variables. By malloc'ing the buffers separately, we
489 * ensure that they are sufficiently aligned for the length-word accesses
490 * that we do in some places in this file.
492 if (PqGSSSendBuffer == NULL)
494 PqGSSSendBuffer = malloc(PQ_GSS_SEND_BUFFER_SIZE);
495 PqGSSRecvBuffer = malloc(PQ_GSS_RECV_BUFFER_SIZE);
496 PqGSSResultBuffer = malloc(PQ_GSS_RECV_BUFFER_SIZE);
497 if (!PqGSSSendBuffer || !PqGSSRecvBuffer || !PqGSSResultBuffer)
499 printfPQExpBuffer(&conn->errorMessage,
500 libpq_gettext("out of memory\n"));
501 return PGRES_POLLING_FAILED;
503 PqGSSSendLength = PqGSSSendNext = PqGSSSendConsumed = 0;
504 PqGSSRecvLength = PqGSSResultLength = PqGSSResultNext = 0;
508 * Check if we have anything to send from a prior call and if so, send it.
510 if (PqGSSSendLength)
512 ssize_t amount = PqGSSSendLength - PqGSSSendNext;
514 ret = pqsecure_raw_write(conn, PqGSSSendBuffer + PqGSSSendNext, amount);
515 if (ret < 0)
517 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
518 return PGRES_POLLING_WRITING;
519 else
520 return PGRES_POLLING_FAILED;
523 if (ret < amount)
525 PqGSSSendNext += ret;
526 return PGRES_POLLING_WRITING;
529 PqGSSSendLength = PqGSSSendNext = 0;
533 * Client sends first, and sending creates a context, therefore this will
534 * be false the first time through, and then when we get called again we
535 * will check for incoming data.
537 if (conn->gctx)
539 /* Process any incoming data we might have */
541 /* See if we are still trying to get the length */
542 if (PqGSSRecvLength < sizeof(uint32))
544 /* Attempt to get the length first */
545 result = gss_read(conn, PqGSSRecvBuffer + PqGSSRecvLength, sizeof(uint32) - PqGSSRecvLength, &ret);
546 if (result != PGRES_POLLING_OK)
547 return result;
549 PqGSSRecvLength += ret;
551 if (PqGSSRecvLength < sizeof(uint32))
552 return PGRES_POLLING_READING;
556 * Check if we got an error packet
558 * This is safe to do because we shouldn't ever get a packet over 8192
559 * and therefore the actual length bytes, being that they are in
560 * network byte order, for any real packet will start with two zero
561 * bytes.
563 if (PqGSSRecvBuffer[0] == 'E')
566 * For an error packet during startup, we don't get a length, so
567 * simply read as much as we can fit into our buffer (as a string,
568 * so leave a spot at the end for a NULL byte too) and report that
569 * back to the caller.
571 result = gss_read(conn, PqGSSRecvBuffer + PqGSSRecvLength, PQ_GSS_RECV_BUFFER_SIZE - PqGSSRecvLength - 1, &ret);
572 if (result != PGRES_POLLING_OK)
573 return result;
575 PqGSSRecvLength += ret;
577 Assert(PqGSSRecvLength < PQ_GSS_RECV_BUFFER_SIZE);
578 PqGSSRecvBuffer[PqGSSRecvLength] = '\0';
579 printfPQExpBuffer(&conn->errorMessage, "%s\n", PqGSSRecvBuffer + 1);
581 return PGRES_POLLING_FAILED;
585 * We should have the whole length at this point, so pull it out and
586 * then read whatever we have left of the packet
589 /* Get the length and check for over-length packet */
590 input.length = ntohl(*(uint32 *) PqGSSRecvBuffer);
591 if (input.length > PQ_GSS_RECV_BUFFER_SIZE - sizeof(uint32))
593 printfPQExpBuffer(&conn->errorMessage,
594 libpq_gettext("oversize GSSAPI packet sent by the server (%zu > %zu)\n"),
595 (size_t) input.length,
596 PQ_GSS_RECV_BUFFER_SIZE - sizeof(uint32));
597 return PGRES_POLLING_FAILED;
601 * Read as much of the packet as we are able to on this call into
602 * wherever we left off from the last time we were called.
604 result = gss_read(conn, PqGSSRecvBuffer + PqGSSRecvLength,
605 input.length - (PqGSSRecvLength - sizeof(uint32)), &ret);
606 if (result != PGRES_POLLING_OK)
607 return result;
609 PqGSSRecvLength += ret;
612 * If we got less than the rest of the packet then we need to return
613 * and be called again.
615 if (PqGSSRecvLength - sizeof(uint32) < input.length)
616 return PGRES_POLLING_READING;
618 input.value = PqGSSRecvBuffer + sizeof(uint32);
621 /* Load the service name (no-op if already done */
622 ret = pg_GSS_load_servicename(conn);
623 if (ret != STATUS_OK)
624 return PGRES_POLLING_FAILED;
627 * Call GSS init context, either with an empty input, or with a complete
628 * packet from the server.
630 major = gss_init_sec_context(&minor, conn->gcred, &conn->gctx,
631 conn->gtarg_nam, GSS_C_NO_OID,
632 GSS_REQUIRED_FLAGS, 0, 0, &input, NULL,
633 &output, NULL, NULL);
635 /* GSS Init Sec Context uses the whole packet, so clear it */
636 PqGSSRecvLength = 0;
638 if (GSS_ERROR(major))
640 pg_GSS_error(libpq_gettext("could not initiate GSSAPI security context"),
641 conn, major, minor);
642 return PGRES_POLLING_FAILED;
645 if (output.length == 0)
648 * We're done - hooray! Set flag to tell the low-level I/O routines
649 * to do GSS wrapping/unwrapping.
651 conn->gssenc = true;
653 /* Clean up */
654 gss_release_cred(&minor, &conn->gcred);
655 conn->gcred = GSS_C_NO_CREDENTIAL;
656 gss_release_buffer(&minor, &output);
659 * Determine the max packet size which will fit in our buffer, after
660 * accounting for the length. pg_GSS_write will need this.
662 major = gss_wrap_size_limit(&minor, conn->gctx, 1, GSS_C_QOP_DEFAULT,
663 PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32),
664 &PqGSSMaxPktSize);
666 if (GSS_ERROR(major))
668 pg_GSS_error(libpq_gettext("GSSAPI size check error"), conn,
669 major, minor);
670 return PGRES_POLLING_FAILED;
673 return PGRES_POLLING_OK;
676 /* Must have output.length > 0 */
677 if (output.length > PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32))
679 pg_GSS_error(libpq_gettext("GSSAPI context establishment error"),
680 conn, major, minor);
681 gss_release_buffer(&minor, &output);
682 return PGRES_POLLING_FAILED;
685 /* Queue the token for writing */
686 netlen = htonl(output.length);
688 memcpy(PqGSSSendBuffer, (char *) &netlen, sizeof(uint32));
689 PqGSSSendLength += sizeof(uint32);
691 memcpy(PqGSSSendBuffer + PqGSSSendLength, output.value, output.length);
692 PqGSSSendLength += output.length;
694 /* We don't bother with PqGSSSendConsumed here */
696 /* Release buffer storage allocated by GSSAPI */
697 gss_release_buffer(&minor, &output);
699 /* Ask to be called again to write data */
700 return PGRES_POLLING_WRITING;
704 * GSSAPI Information functions.
708 * Return the GSSAPI Context itself.
710 void *
711 PQgetgssctx(PGconn *conn)
713 if (!conn)
714 return NULL;
716 return conn->gctx;
720 * Return true if GSSAPI encryption is in use.
723 PQgssEncInUse(PGconn *conn)
725 if (!conn || !conn->gctx)
726 return 0;
728 return conn->gssenc;