* Read up to len bytes of data into ptr from a GSSAPI-encrypted connection. * * The connection must be already set up for GSSAPI encryption (i.e., GSSAPI * transport negotiation is complete). * * Returns the number of data bytes read, or on failure, returns -1 * with errno set appropriately. If the errno indicates a non-retryable * error, a message is added to conn->errorMessage. For retr
| 269 | * caller should call again once the socket is ready. |
| 270 | */ |
| 271 | ssize_t |
| 272 | pg_GSS_read(PGconn *conn, void *ptr, size_t len) |
| 273 | { |
| 274 | OM_uint32 major, |
| 275 | minor; |
| 276 | gss_buffer_desc input = GSS_C_EMPTY_BUFFER, |
| 277 | output = GSS_C_EMPTY_BUFFER; |
| 278 | ssize_t ret; |
| 279 | size_t bytes_returned = 0; |
| 280 | gss_ctx_id_t gctx = conn->gctx; |
| 281 | |
| 282 | /* |
| 283 | * The plan here is to read one incoming encrypted packet into |
| 284 | * PqGSSRecvBuffer, decrypt it into PqGSSResultBuffer, and then dole out |
| 285 | * data from there to the caller. When we exhaust the current input |
| 286 | * packet, read another. |
| 287 | */ |
| 288 | while (bytes_returned < len) |
| 289 | { |
| 290 | int conf_state = 0; |
| 291 | |
| 292 | /* Check if we have data in our buffer that we can return immediately */ |
| 293 | if (PqGSSResultNext < PqGSSResultLength) |
| 294 | { |
| 295 | size_t bytes_in_buffer = PqGSSResultLength - PqGSSResultNext; |
| 296 | size_t bytes_to_copy = Min(bytes_in_buffer, len - bytes_returned); |
| 297 | |
| 298 | /* |
| 299 | * Copy the data from our result buffer into the caller's buffer, |
| 300 | * at the point where we last left off filling their buffer. |
| 301 | */ |
| 302 | memcpy((char *) ptr + bytes_returned, PqGSSResultBuffer + PqGSSResultNext, bytes_to_copy); |
| 303 | PqGSSResultNext += bytes_to_copy; |
| 304 | bytes_returned += bytes_to_copy; |
| 305 | |
| 306 | /* |
| 307 | * At this point, we've either filled the caller's buffer or |
| 308 | * emptied our result buffer. Either way, return to caller. In |
| 309 | * the second case, we could try to read another encrypted packet, |
| 310 | * but the odds are good that there isn't one available. (If this |
| 311 | * isn't true, we chose too small a max packet size.) In any |
| 312 | * case, there's no harm letting the caller process the data we've |
| 313 | * already returned. |
| 314 | */ |
| 315 | break; |
| 316 | } |
| 317 | |
| 318 | /* Result buffer is empty, so reset buffer pointers */ |
| 319 | PqGSSResultLength = PqGSSResultNext = 0; |
| 320 | |
| 321 | /* |
| 322 | * Because we chose above to return immediately as soon as we emit |
| 323 | * some data, bytes_returned must be zero at this point. Therefore |
| 324 | * the failure exits below can just return -1 without worrying about |
| 325 | * whether we already emitted some data. |
| 326 | */ |
| 327 | Assert(bytes_returned == 0); |
| 328 |
no test coverage detected