MCPcopy Create free account
hub / github.com/apache/cloudberry / pg_GSS_write

Function pg_GSS_write

src/interfaces/libpq/fe-secure-gssapi.c:92–258  ·  view source on GitHub ↗

* Attempt to write len bytes of data from ptr to a GSSAPI-encrypted connection. * * The connection must be already set up for GSSAPI encryption (i.e., GSSAPI * transport negotiation is complete). * * On success, returns the number of data bytes consumed (possibly less than * len). On failure, returns -1 with errno set appropriately. If the errno * indicates a non-retryable error, a messag

Source from the content-addressed store, hash-verified

90 * once the socket is ready.
91 */
92ssize_t
93pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
94{
95 OM_uint32 major,
96 minor;
97 gss_buffer_desc input,
98 output = GSS_C_EMPTY_BUFFER;
99 ssize_t ret = -1;
100 size_t bytes_sent = 0;
101 size_t bytes_to_encrypt;
102 size_t bytes_encrypted;
103 gss_ctx_id_t gctx = conn->gctx;
104
105 /*
106 * When we get a failure, we must not tell the caller we have successfully
107 * transmitted everything, else it won't retry. Hence a "success"
108 * (positive) return value must only count source bytes corresponding to
109 * fully-transmitted encrypted packets. The amount of source data
110 * corresponding to the current partly-transmitted packet is remembered in
111 * PqGSSSendConsumed. On a retry, the caller *must* be sending that data
112 * again, so if it offers a len less than that, something is wrong.
113 */
114 if (len < PqGSSSendConsumed)
115 {
116 appendPQExpBufferStr(&conn->errorMessage,
117 "GSSAPI caller failed to retransmit all data needing to be retried\n");
118 errno = EINVAL;
119 return -1;
120 }
121
122 /* Discount whatever source data we already encrypted. */
123 bytes_to_encrypt = len - PqGSSSendConsumed;
124 bytes_encrypted = PqGSSSendConsumed;
125
126 /*
127 * Loop through encrypting data and sending it out until it's all done or
128 * pqsecure_raw_write() complains (which would likely mean that the socket
129 * is non-blocking and the requested send() would block, or there was some
130 * kind of actual error).
131 */
132 while (bytes_to_encrypt || PqGSSSendLength)
133 {
134 int conf_state = 0;
135 uint32 netlen;
136
137 /*
138 * Check if we have data in the encrypted output buffer that needs to
139 * be sent (possibly left over from a previous call), and if so, try
140 * to send it. If we aren't able to, return that fact back up to the
141 * caller.
142 */
143 if (PqGSSSendLength)
144 {
145 ssize_t ret;
146 ssize_t amount = PqGSSSendLength - PqGSSSendNext;
147
148 ret = pqsecure_raw_write(conn, PqGSSSendBuffer + PqGSSSendNext, amount);
149 if (ret <= 0)

Callers 1

pqsecure_writeFunction · 0.85

Calls 5

appendPQExpBufferStrFunction · 0.85
pqsecure_raw_writeFunction · 0.85
pg_GSS_errorFunction · 0.85
libpq_gettextFunction · 0.85
appendPQExpBufferFunction · 0.85

Tested by

no test coverage detected