* Continue GSS authentication with next token as needed. */
| 61 | * Continue GSS authentication with next token as needed. |
| 62 | */ |
| 63 | static int |
| 64 | pg_GSS_continue(PGconn *conn, int payloadlen) |
| 65 | { |
| 66 | OM_uint32 maj_stat, |
| 67 | min_stat, |
| 68 | lmin_s; |
| 69 | gss_buffer_desc ginbuf; |
| 70 | gss_buffer_desc goutbuf; |
| 71 | |
| 72 | /* |
| 73 | * On first call, there's no input token. On subsequent calls, read the |
| 74 | * input token into a GSS buffer. |
| 75 | */ |
| 76 | if (conn->gctx != GSS_C_NO_CONTEXT) |
| 77 | { |
| 78 | ginbuf.length = payloadlen; |
| 79 | ginbuf.value = malloc(payloadlen); |
| 80 | if (!ginbuf.value) |
| 81 | { |
| 82 | appendPQExpBuffer(&conn->errorMessage, |
| 83 | libpq_gettext("out of memory allocating GSSAPI buffer (%d)\n"), |
| 84 | payloadlen); |
| 85 | return STATUS_ERROR; |
| 86 | } |
| 87 | if (pqGetnchar(ginbuf.value, payloadlen, conn)) |
| 88 | { |
| 89 | /* |
| 90 | * Shouldn't happen, because the caller should've ensured that the |
| 91 | * whole message is already in the input buffer. |
| 92 | */ |
| 93 | free(ginbuf.value); |
| 94 | return STATUS_ERROR; |
| 95 | } |
| 96 | } |
| 97 | else |
| 98 | { |
| 99 | ginbuf.length = 0; |
| 100 | ginbuf.value = NULL; |
| 101 | } |
| 102 | |
| 103 | maj_stat = gss_init_sec_context(&min_stat, |
| 104 | GSS_C_NO_CREDENTIAL, |
| 105 | &conn->gctx, |
| 106 | conn->gtarg_nam, |
| 107 | GSS_C_NO_OID, |
| 108 | GSS_C_MUTUAL_FLAG, |
| 109 | 0, |
| 110 | GSS_C_NO_CHANNEL_BINDINGS, |
| 111 | (ginbuf.value == NULL) ? GSS_C_NO_BUFFER : &ginbuf, |
| 112 | NULL, |
| 113 | &goutbuf, |
| 114 | NULL, |
| 115 | NULL); |
| 116 | |
| 117 | if (ginbuf.value) |
| 118 | free(ginbuf.value); |
| 119 | |
| 120 | if (goutbuf.length != 0) |
no test coverage detected