PostgreSQL Source Code: src/interfaces/libpq/fe-secure.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
20
21#include <signal.h>
22#include <fcntl.h>
23#include <ctype.h>
24
25#ifdef WIN32
26#include "win32.h"
27#else
34#endif
35
36#include <sys/stat.h>
37
38#ifdef WIN32
40#else
41#include <pthread.h>
42#endif
43
47
48
49
50
51
52
53#ifndef WIN32
54
55#define SIGPIPE_MASKED(conn) ((conn)->sigpipe_so || (conn)->sigpipe_flag)
56
58{
62};
63
64#define DECLARE_SIGPIPE_INFO(spinfo) struct sigpipe_info spinfo
65
66#define DISABLE_SIGPIPE(conn, spinfo, failaction) \
67 do { \
68 (spinfo).got_epipe = false; \
69 if (!SIGPIPE_MASKED(conn)) \
70 { \
71 if (pq_block_sigpipe(&(spinfo).oldsigmask, \
72 &(spinfo).sigpipe_pending) < 0) \
73 failaction; \
74 } \
75 } while (0)
76
77#define REMEMBER_EPIPE(spinfo, cond) \
78 do { \
79 if (cond) \
80 (spinfo).got_epipe = true; \
81 } while (0)
82
83#define RESTORE_SIGPIPE(conn, spinfo) \
84 do { \
85 if (!SIGPIPE_MASKED(conn)) \
86 pq_reset_sigpipe(&(spinfo).oldsigmask, (spinfo).sigpipe_pending, \
87 (spinfo).got_epipe); \
88 } while (0)
89#else
90
91#define DECLARE_SIGPIPE_INFO(spinfo)
92#define DISABLE_SIGPIPE(conn, spinfo, failaction)
93#define REMEMBER_EPIPE(spinfo, cond)
94#define RESTORE_SIGPIPE(conn, spinfo)
95#endif
96
97
98
99
100
101
102int
104{
106 return 0;
108}
109
110
111
112
113
114
115
116void
118{
119
120}
121
122
123
124
125
126
127
128void
130{
131
132}
133
134
135
136
139{
140#ifdef USE_SSL
142#else
143
145#endif
146}
147
148
149
150
151void
153{
154#ifdef USE_SSL
156#endif
157}
158
159
160
161
162
163
164
165
166ssize_t
168{
169 ssize_t n;
170
171#ifdef USE_SSL
173 {
175 }
176 else
177#endif
178#ifdef ENABLE_GSS
179 if (conn->gssenc)
180 {
182 }
183 else
184#endif
185 {
187 }
188
189 return n;
190}
191
192ssize_t
194{
195 ssize_t n;
196 int result_errno = 0;
198
200
202
203 if (n < 0)
204 {
206
207
208 switch (result_errno)
209 {
210#ifdef EAGAIN
212#endif
213#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
215#endif
217
218 break;
219
220 case EPIPE:
223 "\tThis probably means the server terminated abnormally\n"
224 "\tbefore or while processing the request.");
225 break;
226
227 case 0:
228
229 n = 0;
230 break;
231
232 default:
235 sebuf, sizeof(sebuf)));
236 break;
237 }
238 }
239
240
242
243 return n;
244}
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266ssize_t
268{
269 ssize_t n;
270
271#ifdef USE_SSL
273 {
275 }
276 else
277#endif
278#ifdef ENABLE_GSS
279 if (conn->gssenc)
280 {
282 }
283 else
284#endif
285 {
287 }
288
289 return n;
290}
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315ssize_t
317{
318 ssize_t n;
319 int flags = 0;
320 int result_errno = 0;
321 char msgbuf[1024];
323
325
326
327
328
329
330
331
332
334 return len;
335
336#ifdef MSG_NOSIGNAL
338 flags |= MSG_NOSIGNAL;
339
340retry_masked:
341#endif
342
344
346
347 if (n < 0)
348 {
350
351
352
353
354
355
356#ifdef MSG_NOSIGNAL
357 if (flags != 0 && result_errno == EINVAL)
358 {
360 flags = 0;
361 goto retry_masked;
362 }
363#endif
364
365
366 switch (result_errno)
367 {
368#ifdef EAGAIN
370#endif
371#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
373#endif
375
376 break;
377
378 case EPIPE:
379
381
382
383
386
387
388 snprintf(msgbuf, sizeof(msgbuf),
389 libpq_gettext("server closed the connection unexpectedly\n"
390 "\tThis probably means the server terminated abnormally\n"
391 "\tbefore or while processing the request."));
392
393 strlcat(msgbuf, "\n", sizeof(msgbuf));
395
397 break;
398
399 default:
401
402
403 snprintf(msgbuf, sizeof(msgbuf),
404 libpq_gettext("could not send data to server: %s"),
406 sebuf, sizeof(sebuf)));
407
408 strlcat(msgbuf, "\n", sizeof(msgbuf));
410
412 break;
413 }
414 }
415
417
418
420
421 return n;
422}
423
424
425#ifndef USE_SSL
426
427void *
429{
430 return NULL;
431}
432
433void *
435{
436 return NULL;
437}
438
439const char *
441{
442 return NULL;
443}
444
445const char *const *
447{
448 static const char *const result[] = {NULL};
449
450 return result;
451}
452#endif
453
454
455
456
457
458#ifndef USE_OPENSSL
459
462{
463 return NULL;
464}
465
466void
468{
469 return;
470}
471
472int
474{
475 return 0;
476}
477#endif
478
479
480#ifndef ENABLE_GSS
481
482void *
484{
485 return NULL;
486}
487
488int
490{
491 return 0;
492}
493
494#endif
495
496
497#if !defined(WIN32)
498
499
500
501
502
503int
505{
506 sigset_t sigpipe_sigset;
507 sigset_t sigset;
508
509 sigemptyset(&sigpipe_sigset);
510 sigaddset(&sigpipe_sigset, SIGPIPE);
511
512
513 SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset));
515 return -1;
516
517
518 if (sigismember(osigset, SIGPIPE))
519 {
520
521 if (sigpending(&sigset) != 0)
522 return -1;
523
524 if (sigismember(&sigset, SIGPIPE))
525 *sigpipe_pending = true;
526 else
527 *sigpipe_pending = false;
528 }
529 else
530 *sigpipe_pending = false;
531
532 return 0;
533}
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553void
555{
557 int signo;
558 sigset_t sigset;
559
560
561 if (got_epipe && !sigpipe_pending)
562 {
563 if (sigpending(&sigset) == 0 &&
564 sigismember(&sigset, SIGPIPE))
565 {
566 sigset_t sigpipe_sigset;
567
568 sigemptyset(&sigpipe_sigset);
569 sigaddset(&sigpipe_sigset, SIGPIPE);
570
571 sigwait(&sigpipe_sigset, &signo);
572 }
573 }
574
575
576 pthread_sigmask(SIG_SETMASK, osigset, NULL);
577
579}
580
581#endif
ssize_t pg_GSS_read(PGconn *conn, void *ptr, size_t len)
ssize_t pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
PostgresPollingStatusType pgtls_open_client(PGconn *conn)
ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len)
ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len)
void pgtls_close(PGconn *conn)
ssize_t pqsecure_write(PGconn *conn, const void *ptr, size_t len)
void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
void PQinitSSL(int do_init)
void * PQgetssl(PGconn *conn)
PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL(void)
void * PQsslStruct(PGconn *conn, const char *struct_name)
#define REMEMBER_EPIPE(spinfo, cond)
int pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
void * PQgetgssctx(PGconn *conn)
int PQdefaultSSLKeyPassHook_OpenSSL(char *buf, int size, PGconn *conn)
PostgresPollingStatusType pqsecure_open_client(PGconn *conn)
int PQgssEncInUse(PGconn *conn)
#define DISABLE_SIGPIPE(conn, spinfo, failaction)
void PQinitOpenSSL(int do_ssl, int do_crypto)
int PQsslInUse(PGconn *conn)
ssize_t pqsecure_read(PGconn *conn, void *ptr, size_t len)
ssize_t pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
ssize_t pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
const char * PQsslAttribute(PGconn *conn, const char *attribute_name)
void pqsecure_close(PGconn *conn)
const char *const * PQsslAttributeNames(PGconn *conn)
#define DECLARE_SIGPIPE_INFO(spinfo)
void PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook)
#define RESTORE_SIGPIPE(conn, spinfo)
int(* PQsslKeyPassHook_OpenSSL_type)(char *buf, int size, PGconn *conn)
PostgresPollingStatusType
#define SOCK_ERRNO_SET(e)
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
static void do_init(void)
#define PG_STRERROR_R_BUFLEN
size_t strlcat(char *dst, const char *src, size_t siz)
#define recv(s, buf, len, flags)
#define send(s, buf, len, flags)