PostgreSQL Source Code git master
Loading...
Searching...
No Matches
be-secure.c File Reference
#include "postgres.h"
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include "libpq/libpq.h"
#include "miscadmin.h"
#include "storage/latch.h"
#include "tcop/tcopprot.h"
#include "utils/injection_point.h"
#include "utils/wait_event.h"
Include dependency graph for be-secure.c:

Go to the source code of this file.

Functions

int secure_initialize (bool isServerStart)
 
void secure_destroy (void)
 
bool secure_loaded_verify_locations (void)
 
int secure_open_server (Port *port)
 
void secure_close (Port *port)
 
ssize_t secure_read (Port *port, void *ptr, size_t len)
 
ssize_t secure_raw_read (Port *port, void *ptr, size_t len)
 
ssize_t secure_write (Port *port, const void *ptr, size_t len)
 
ssize_t secure_raw_write (Port *port, const void *ptr, size_t len)
 

Variables

charssl_library
 
charssl_cert_file
 
charssl_key_file
 
charssl_ca_file
 
charssl_crl_file
 
charssl_crl_dir
 
charssl_dh_params_file
 
charssl_passphrase_command
 
bool ssl_passphrase_command_supports_reload
 
charSSLCipherSuites = NULL
 
charSSLCipherList = NULL
 
charSSLECDHCurve
 
bool SSLPreferServerCiphers
 
int ssl_min_protocol_version = PG_TLS1_2_VERSION
 
int ssl_max_protocol_version = PG_TLS_ANY
 
bool ssl_sni = false
 

Function Documentation

◆ secure_close()

void secure_close ( Port port)

Definition at line 171 of file be-secure.c.

172{
173#ifdef USE_SSL
174 if (port->ssl_in_use)
176#endif
177}
void be_tls_close(Port *port)
static int port
Definition pg_regress.c:115

References be_tls_close(), and port.

Referenced by socket_close().

◆ secure_destroy()

void secure_destroy ( void  )

Definition at line 92 of file be-secure.c.

93{
94#ifdef USE_SSL
96#endif
97}
void be_tls_destroy(void)

References be_tls_destroy().

Referenced by process_pm_reload_request().

◆ secure_initialize()

int secure_initialize ( bool  isServerStart)

Definition at line 79 of file be-secure.c.

80{
81#ifdef USE_SSL
83#else
84 return 0;
85#endif
86}
int be_tls_init(bool isServerStart)
static int fb(int x)

References be_tls_init(), and fb().

Referenced by BackendMain(), PostmasterMain(), and process_pm_reload_request().

◆ secure_loaded_verify_locations()

bool secure_loaded_verify_locations ( void  )

Definition at line 103 of file be-secure.c.

104{
105#ifdef USE_SSL
107#else
108 return false;
109#endif
110}

References fb().

Referenced by ClientAuthentication().

◆ secure_open_server()

int secure_open_server ( Port port)

Definition at line 116 of file be-secure.c.

117{
118#ifdef USE_SSL
119 int r = 0;
120 ssize_t len;
121
122 /* push unencrypted buffered data back through SSL setup */
124 if (len > 0)
125 {
126 char *buf = palloc(len);
127
129 if (pq_getbytes(buf, len) == EOF)
130 return STATUS_ERROR; /* shouldn't be possible */
132 port->raw_buf = buf;
133 port->raw_buf_remaining = len;
134 port->raw_buf_consumed = 0;
135 }
137
138 INJECTION_POINT("backend-ssl-startup", NULL);
139
141
142 if (port->raw_buf_remaining > 0)
143 {
144 /*
145 * This shouldn't be possible -- it would mean the client sent
146 * encrypted data before we established a session key...
147 */
148 elog(LOG, "buffered unencrypted data remains after negotiating SSL connection");
149 return STATUS_ERROR;
150 }
151 if (port->raw_buf != NULL)
152 {
153 pfree(port->raw_buf);
154 port->raw_buf = NULL;
155 }
156
158 (errmsg_internal("SSL connection from DN:\"%s\" CN:\"%s\"",
159 port->peer_dn ? port->peer_dn : "(anonymous)",
160 port->peer_cn ? port->peer_cn : "(anonymous)")));
161 return r;
162#else
163 return 0;
164#endif
165}
int be_tls_open_server(Port *port)
#define Assert(condition)
Definition c.h:945
#define STATUS_ERROR
Definition c.h:1261
#define LOG
Definition elog.h:31
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define DEBUG2
Definition elog.h:29
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
#define INJECTION_POINT(name, arg)
void pfree(void *pointer)
Definition mcxt.c:1616
void * palloc(Size size)
Definition mcxt.c:1387
const void size_t len
static char buf[DEFAULT_XLOG_SEG_SIZE]
ssize_t pq_buffer_remaining_data(void)
Definition pqcomm.c:1128
int pq_getbytes(void *b, size_t len)
Definition pqcomm.c:1063
void pq_endmsgread(void)
Definition pqcomm.c:1166
void pq_startmsgread(void)
Definition pqcomm.c:1142

References Assert, be_tls_open_server(), buf, DEBUG2, elog, ereport, errmsg_internal(), fb(), INJECTION_POINT, len, LOG, palloc(), pfree(), port, pq_buffer_remaining_data(), pq_endmsgread(), pq_getbytes(), pq_startmsgread(), and STATUS_ERROR.

Referenced by ProcessSSLStartup(), and ProcessStartupPacket().

◆ secure_raw_read()

ssize_t secure_raw_read ( Port port,
void ptr,
size_t  len 
)

Definition at line 272 of file be-secure.c.

273{
274 ssize_t n;
275
276 /* Read from the "unread" buffered data first. c.f. libpq-be.h */
277 if (port->raw_buf_remaining > 0)
278 {
279 /* consume up to len bytes from the raw_buf */
280 if (len > port->raw_buf_remaining)
281 len = port->raw_buf_remaining;
282 Assert(port->raw_buf);
283 memcpy(ptr, port->raw_buf + port->raw_buf_consumed, len);
284 port->raw_buf_consumed += len;
285 port->raw_buf_remaining -= len;
286 return len;
287 }
288
289 /*
290 * Try to read from the socket without blocking. If it succeeds we're
291 * done, otherwise we'll wait for the socket using the latch mechanism.
292 */
293#ifdef WIN32
294 pgwin32_noblock = true;
295#endif
296 n = recv(port->sock, ptr, len, 0);
297#ifdef WIN32
298 pgwin32_noblock = false;
299#endif
300
301 return n;
302}
int pgwin32_noblock
Definition socket.c:28
#define recv(s, buf, len, flags)
Definition win32_port.h:501

References Assert, fb(), len, pgwin32_noblock, port, and recv.

Referenced by be_gssapi_read(), port_bio_read(), read_or_wait(), and secure_read().

◆ secure_raw_write()

ssize_t secure_raw_write ( Port port,
const void ptr,
size_t  len 
)

Definition at line 381 of file be-secure.c.

382{
383 ssize_t n;
384
385#ifdef WIN32
386 pgwin32_noblock = true;
387#endif
388 n = send(port->sock, ptr, len, 0);
389#ifdef WIN32
390 pgwin32_noblock = false;
391#endif
392
393 return n;
394}
#define send(s, buf, len, flags)
Definition win32_port.h:502

References fb(), len, pgwin32_noblock, port, and send.

Referenced by be_gssapi_write(), port_bio_write(), secure_open_gssapi(), and secure_write().

◆ secure_read()

ssize_t secure_read ( Port port,
void ptr,
size_t  len 
)

Definition at line 183 of file be-secure.c.

184{
185 ssize_t n;
186 int waitfor;
187
188 /* Deal with any already-pending interrupt condition. */
190
191retry:
192#ifdef USE_SSL
193 waitfor = 0;
194 if (port->ssl_in_use)
195 {
196 n = be_tls_read(port, ptr, len, &waitfor);
197 }
198 else
199#endif
200#ifdef ENABLE_GSS
201 if (port->gss && port->gss->enc)
202 {
203 n = be_gssapi_read(port, ptr, len);
205 }
206 else
207#endif
208 {
209 n = secure_raw_read(port, ptr, len);
211 }
212
213 /* In blocking mode, wait until the socket is ready */
214 if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
215 {
216 WaitEvent event;
217
219
221
222 WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
224
225 /*
226 * If the postmaster has died, it's not safe to continue running,
227 * because it is the postmaster's job to kill us if some other backend
228 * exits uncleanly. Moreover, we won't run very well in this state;
229 * helper processes like walwriter and the bgwriter will exit, so
230 * performance may be poor. Finally, if we don't exit, pg_ctl will be
231 * unable to restart the postmaster without manual intervention, so no
232 * new connections can be accepted. Exiting clears the deck for a
233 * postmaster restart.
234 *
235 * (Note that we only make this check when we would otherwise sleep on
236 * our latch. We might still continue running for a while if the
237 * postmaster is killed in mid-query, or even through multiple queries
238 * if we never have to wait for read. We don't want to burn too many
239 * cycles checking for this very rare condition, and this should cause
240 * us to exit quickly in most cases.)
241 */
242 if (event.events & WL_POSTMASTER_DEATH)
245 errmsg("terminating connection due to unexpected postmaster exit")));
246
247 /* Handle interrupt. */
248 if (event.events & WL_LATCH_SET)
249 {
252
253 /*
254 * We'll retry the read. Most likely it will return immediately
255 * because there's still no data available, and we'll wait for the
256 * socket to become ready again.
257 */
258 }
259 goto retry;
260 }
261
262 /*
263 * Process interrupts that happened during a successful (or non-blocking,
264 * or hard-failed) read.
265 */
267
268 return n;
269}
ssize_t be_gssapi_read(Port *port, void *ptr, size_t len)
ssize_t be_tls_read(Port *port, void *ptr, size_t len, int *waitfor)
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
Definition be-secure.c:272
int errcode(int sqlerrcode)
Definition elog.c:874
#define FATAL
Definition elog.h:41
struct Latch * MyLatch
Definition globals.c:63
void ResetLatch(Latch *latch)
Definition latch.c:374
#define FeBeWaitSetSocketPos
Definition libpq.h:66
static char * errmsg
void ProcessClientReadInterrupt(bool blocked)
Definition postgres.c:502
WaitEventSet * FeBeWaitSet
Definition pqcomm.c:167
uint32 events
void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
int WaitEventSetWait(WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info)
#define WL_SOCKET_READABLE
#define WL_LATCH_SET
#define WL_POSTMASTER_DEATH
#define EWOULDBLOCK
Definition win32_port.h:367
#define EAGAIN
Definition win32_port.h:359

References Assert, be_gssapi_read(), be_tls_read(), EAGAIN, ereport, errcode(), errmsg, WaitEvent::events, EWOULDBLOCK, FATAL, fb(), FeBeWaitSet, FeBeWaitSetSocketPos, len, ModifyWaitEvent(), MyLatch, port, ProcessClientReadInterrupt(), ResetLatch(), secure_raw_read(), WaitEventSetWait(), WL_LATCH_SET, WL_POSTMASTER_DEATH, and WL_SOCKET_READABLE.

Referenced by pq_getbyte_if_available(), and pq_recvbuf().

◆ secure_write()

ssize_t secure_write ( Port port,
const void ptr,
size_t  len 
)

Definition at line 309 of file be-secure.c.

310{
311 ssize_t n;
312 int waitfor;
313
314 /* Deal with any already-pending interrupt condition. */
316
317retry:
318 waitfor = 0;
319#ifdef USE_SSL
320 if (port->ssl_in_use)
321 {
322 n = be_tls_write(port, ptr, len, &waitfor);
323 }
324 else
325#endif
326#ifdef ENABLE_GSS
327 if (port->gss && port->gss->enc)
328 {
329 n = be_gssapi_write(port, ptr, len);
331 }
332 else
333#endif
334 {
335 n = secure_raw_write(port, ptr, len);
337 }
338
339 if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
340 {
341 WaitEvent event;
342
344
346
347 WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
349
350 /* See comments in secure_read. */
351 if (event.events & WL_POSTMASTER_DEATH)
354 errmsg("terminating connection due to unexpected postmaster exit")));
355
356 /* Handle interrupt. */
357 if (event.events & WL_LATCH_SET)
358 {
361
362 /*
363 * We'll retry the write. Most likely it will return immediately
364 * because there's still no buffer space available, and we'll wait
365 * for the socket to become ready again.
366 */
367 }
368 goto retry;
369 }
370
371 /*
372 * Process interrupts that happened during a successful (or non-blocking,
373 * or hard-failed) write.
374 */
376
377 return n;
378}
ssize_t be_gssapi_write(Port *port, const void *ptr, size_t len)
ssize_t be_tls_write(Port *port, const void *ptr, size_t len, int *waitfor)
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
Definition be-secure.c:381
void ProcessClientWriteInterrupt(bool blocked)
Definition postgres.c:548
#define WL_SOCKET_WRITEABLE

References Assert, be_gssapi_write(), be_tls_write(), EAGAIN, ereport, errcode(), errmsg, WaitEvent::events, EWOULDBLOCK, FATAL, fb(), FeBeWaitSet, FeBeWaitSetSocketPos, len, ModifyWaitEvent(), MyLatch, port, ProcessClientWriteInterrupt(), ResetLatch(), secure_raw_write(), WaitEventSetWait(), WL_LATCH_SET, WL_POSTMASTER_DEATH, and WL_SOCKET_WRITEABLE.

Referenced by internal_flush_buffer(), and ProcessStartupPacket().

Variable Documentation

◆ ssl_ca_file

char* ssl_ca_file

Definition at line 40 of file be-secure.c.

Referenced by be_tls_init().

◆ ssl_cert_file

char* ssl_cert_file

Definition at line 38 of file be-secure.c.

Referenced by be_tls_init().

◆ ssl_crl_dir

char* ssl_crl_dir

Definition at line 42 of file be-secure.c.

Referenced by init_host_context().

◆ ssl_crl_file

char* ssl_crl_file

Definition at line 41 of file be-secure.c.

Referenced by init_host_context().

◆ ssl_dh_params_file

char* ssl_dh_params_file

Definition at line 43 of file be-secure.c.

Referenced by initialize_dh().

◆ ssl_key_file

char* ssl_key_file

Definition at line 39 of file be-secure.c.

Referenced by be_tls_init(), and check_ssl_key_file_permissions().

◆ ssl_library

char* ssl_library

Definition at line 37 of file be-secure.c.

◆ ssl_max_protocol_version

int ssl_max_protocol_version = PG_TLS_ANY

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

Referenced by be_tls_init(), and be_tls_open_server().

◆ ssl_min_protocol_version

int ssl_min_protocol_version = PG_TLS1_2_VERSION

Definition at line 61 of file be-secure.c.

Referenced by be_tls_init(), and be_tls_open_server().

◆ ssl_passphrase_command

char* ssl_passphrase_command

Definition at line 44 of file be-secure.c.

Referenced by be_tls_init(), default_openssl_tls_init(), and set_rot13().

◆ ssl_passphrase_command_supports_reload

bool ssl_passphrase_command_supports_reload

Definition at line 45 of file be-secure.c.

Referenced by be_tls_init(), and default_openssl_tls_init().

◆ ssl_sni

bool ssl_sni = false

Definition at line 65 of file be-secure.c.

Referenced by be_tls_init(), and init_host_context().

◆ SSLCipherList

char* SSLCipherList = NULL

Definition at line 53 of file be-secure.c.

Referenced by be_tls_init().

◆ SSLCipherSuites

char* SSLCipherSuites = NULL

Definition at line 52 of file be-secure.c.

Referenced by be_tls_init().

◆ SSLECDHCurve

char* SSLECDHCurve

Definition at line 56 of file be-secure.c.

Referenced by initialize_ecdh().

◆ SSLPreferServerCiphers

bool SSLPreferServerCiphers

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

Referenced by be_tls_init().