00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include "postgres.h"
00052
00053 #include <sys/stat.h>
00054 #include <signal.h>
00055 #include <fcntl.h>
00056 #include <ctype.h>
00057 #include <sys/socket.h>
00058 #include <unistd.h>
00059 #include <netdb.h>
00060 #include <netinet/in.h>
00061 #ifdef HAVE_NETINET_TCP_H
00062 #include <netinet/tcp.h>
00063 #include <arpa/inet.h>
00064 #endif
00065
00066 #ifdef USE_SSL
00067 #include <openssl/ssl.h>
00068 #include <openssl/dh.h>
00069 #if SSLEAY_VERSION_NUMBER >= 0x0907000L
00070 #include <openssl/conf.h>
00071 #endif
00072 #endif
00073
00074 #include "libpq/libpq.h"
00075 #include "tcop/tcopprot.h"
00076 #include "utils/memutils.h"
00077
00078
00079 #ifdef USE_SSL
00080
00081 static DH *load_dh_file(int keylength);
00082 static DH *load_dh_buffer(const char *, size_t);
00083 static DH *tmp_dh_cb(SSL *s, int is_export, int keylength);
00084 static int verify_cb(int, X509_STORE_CTX *);
00085 static void info_cb(const SSL *ssl, int type, int args);
00086 static void initialize_SSL(void);
00087 static int open_server_SSL(Port *);
00088 static void close_SSL(Port *);
00089 static const char *SSLerrmessage(void);
00090 #endif
00091
00092 char *ssl_cert_file;
00093 char *ssl_key_file;
00094 char *ssl_ca_file;
00095 char *ssl_crl_file;
00096
00097
00098
00099
00100
00101
00102 int ssl_renegotiation_limit;
00103
00104 #ifdef USE_SSL
00105 static SSL_CTX *SSL_context = NULL;
00106 static bool ssl_loaded_verify_locations = false;
00107 #endif
00108
00109
00110 char *SSLCipherSuites = NULL;
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 #ifdef USE_SSL
00139
00140 static const char file_dh512[] =
00141 "-----BEGIN DH PARAMETERS-----\n\
00142 MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak\n\
00143 XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC\n\
00144 -----END DH PARAMETERS-----\n";
00145
00146 static const char file_dh1024[] =
00147 "-----BEGIN DH PARAMETERS-----\n\
00148 MIGHAoGBAPSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsY\n\
00149 jY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6\n\
00150 ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpL3jHAgEC\n\
00151 -----END DH PARAMETERS-----\n";
00152
00153 static const char file_dh2048[] =
00154 "-----BEGIN DH PARAMETERS-----\n\
00155 MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV\n\
00156 89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50\n\
00157 T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb\n\
00158 zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX\n\
00159 Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT\n\
00160 CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg==\n\
00161 -----END DH PARAMETERS-----\n";
00162
00163 static const char file_dh4096[] =
00164 "-----BEGIN DH PARAMETERS-----\n\
00165 MIICCAKCAgEA+hRyUsFN4VpJ1O8JLcCo/VWr19k3BCgJ4uk+d+KhehjdRqNDNyOQ\n\
00166 l/MOyQNQfWXPeGKmOmIig6Ev/nm6Nf9Z2B1h3R4hExf+zTiHnvVPeRBhjdQi81rt\n\
00167 Xeoh6TNrSBIKIHfUJWBh3va0TxxjQIs6IZOLeVNRLMqzeylWqMf49HsIXqbcokUS\n\
00168 Vt1BkvLdW48j8PPv5DsKRN3tloTxqDJGo9tKvj1Fuk74A+Xda1kNhB7KFlqMyN98\n\
00169 VETEJ6c7KpfOo30mnK30wqw3S8OtaIR/maYX72tGOno2ehFDkq3pnPtEbD2CScxc\n\
00170 alJC+EL7RPk5c/tgeTvCngvc1KZn92Y//EI7G9tPZtylj2b56sHtMftIoYJ9+ODM\n\
00171 sccD5Piz/rejE3Ome8EOOceUSCYAhXn8b3qvxVI1ddd1pED6FHRhFvLrZxFvBEM9\n\
00172 ERRMp5QqOaHJkM+Dxv8Cj6MqrCbfC4u+ZErxodzuusgDgvZiLF22uxMZbobFWyte\n\
00173 OvOzKGtwcTqO/1wV5gKkzu1ZVswVUQd5Gg8lJicwqRWyyNRczDDoG9jVDxmogKTH\n\
00174 AaqLulO7R8Ifa1SwF2DteSGVtgWEN8gDpN3RBmmPTDngyF2DHb5qmpnznwtFKdTL\n\
00175 KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=\n\
00176 -----END DH PARAMETERS-----\n";
00177 #endif
00178
00179
00180
00181
00182
00183
00184
00185
00186 int
00187 secure_initialize(void)
00188 {
00189 #ifdef USE_SSL
00190 initialize_SSL();
00191 #endif
00192
00193 return 0;
00194 }
00195
00196
00197
00198
00199 bool
00200 secure_loaded_verify_locations(void)
00201 {
00202 #ifdef USE_SSL
00203 return ssl_loaded_verify_locations;
00204 #else
00205 return false;
00206 #endif
00207 }
00208
00209
00210
00211
00212 int
00213 secure_open_server(Port *port)
00214 {
00215 int r = 0;
00216
00217 #ifdef USE_SSL
00218 r = open_server_SSL(port);
00219 #endif
00220
00221 return r;
00222 }
00223
00224
00225
00226
00227 void
00228 secure_close(Port *port)
00229 {
00230 #ifdef USE_SSL
00231 if (port->ssl)
00232 close_SSL(port);
00233 #endif
00234 }
00235
00236
00237
00238
00239 ssize_t
00240 secure_read(Port *port, void *ptr, size_t len)
00241 {
00242 ssize_t n;
00243
00244 #ifdef USE_SSL
00245 if (port->ssl)
00246 {
00247 int err;
00248
00249 rloop:
00250 errno = 0;
00251 n = SSL_read(port->ssl, ptr, len);
00252 err = SSL_get_error(port->ssl, n);
00253 switch (err)
00254 {
00255 case SSL_ERROR_NONE:
00256 port->count += n;
00257 break;
00258 case SSL_ERROR_WANT_READ:
00259 case SSL_ERROR_WANT_WRITE:
00260 if (port->noblock)
00261 {
00262 errno = EWOULDBLOCK;
00263 n = -1;
00264 break;
00265 }
00266 #ifdef WIN32
00267 pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
00268 (err == SSL_ERROR_WANT_READ) ?
00269 FD_READ | FD_CLOSE : FD_WRITE | FD_CLOSE,
00270 INFINITE);
00271 #endif
00272 goto rloop;
00273 case SSL_ERROR_SYSCALL:
00274
00275 if (n != -1)
00276 {
00277 errno = ECONNRESET;
00278 n = -1;
00279 }
00280 break;
00281 case SSL_ERROR_SSL:
00282 ereport(COMMERROR,
00283 (errcode(ERRCODE_PROTOCOL_VIOLATION),
00284 errmsg("SSL error: %s", SSLerrmessage())));
00285
00286 case SSL_ERROR_ZERO_RETURN:
00287 errno = ECONNRESET;
00288 n = -1;
00289 break;
00290 default:
00291 ereport(COMMERROR,
00292 (errcode(ERRCODE_PROTOCOL_VIOLATION),
00293 errmsg("unrecognized SSL error code: %d",
00294 err)));
00295 n = -1;
00296 break;
00297 }
00298 }
00299 else
00300 #endif
00301 {
00302 prepare_for_client_read();
00303
00304 n = recv(port->sock, ptr, len, 0);
00305
00306 client_read_ended();
00307 }
00308
00309 return n;
00310 }
00311
00312
00313
00314
00315 ssize_t
00316 secure_write(Port *port, void *ptr, size_t len)
00317 {
00318 ssize_t n;
00319
00320 #ifdef USE_SSL
00321 if (port->ssl)
00322 {
00323 int err;
00324
00325 if (ssl_renegotiation_limit && port->count > ssl_renegotiation_limit * 1024L)
00326 {
00327 SSL_set_session_id_context(port->ssl, (void *) &SSL_context,
00328 sizeof(SSL_context));
00329 if (SSL_renegotiate(port->ssl) <= 0)
00330 ereport(COMMERROR,
00331 (errcode(ERRCODE_PROTOCOL_VIOLATION),
00332 errmsg("SSL renegotiation failure")));
00333 if (SSL_do_handshake(port->ssl) <= 0)
00334 ereport(COMMERROR,
00335 (errcode(ERRCODE_PROTOCOL_VIOLATION),
00336 errmsg("SSL renegotiation failure")));
00337 if (port->ssl->state != SSL_ST_OK)
00338 ereport(COMMERROR,
00339 (errcode(ERRCODE_PROTOCOL_VIOLATION),
00340 errmsg("SSL failed to send renegotiation request")));
00341 port->ssl->state |= SSL_ST_ACCEPT;
00342 SSL_do_handshake(port->ssl);
00343 if (port->ssl->state != SSL_ST_OK)
00344 ereport(COMMERROR,
00345 (errcode(ERRCODE_PROTOCOL_VIOLATION),
00346 errmsg("SSL renegotiation failure")));
00347 port->count = 0;
00348 }
00349
00350 wloop:
00351 errno = 0;
00352 n = SSL_write(port->ssl, ptr, len);
00353 err = SSL_get_error(port->ssl, n);
00354 switch (err)
00355 {
00356 case SSL_ERROR_NONE:
00357 port->count += n;
00358 break;
00359 case SSL_ERROR_WANT_READ:
00360 case SSL_ERROR_WANT_WRITE:
00361 #ifdef WIN32
00362 pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
00363 (err == SSL_ERROR_WANT_READ) ?
00364 FD_READ | FD_CLOSE : FD_WRITE | FD_CLOSE,
00365 INFINITE);
00366 #endif
00367 goto wloop;
00368 case SSL_ERROR_SYSCALL:
00369
00370 if (n != -1)
00371 {
00372 errno = ECONNRESET;
00373 n = -1;
00374 }
00375 break;
00376 case SSL_ERROR_SSL:
00377 ereport(COMMERROR,
00378 (errcode(ERRCODE_PROTOCOL_VIOLATION),
00379 errmsg("SSL error: %s", SSLerrmessage())));
00380
00381 case SSL_ERROR_ZERO_RETURN:
00382 errno = ECONNRESET;
00383 n = -1;
00384 break;
00385 default:
00386 ereport(COMMERROR,
00387 (errcode(ERRCODE_PROTOCOL_VIOLATION),
00388 errmsg("unrecognized SSL error code: %d",
00389 err)));
00390 n = -1;
00391 break;
00392 }
00393 }
00394 else
00395 #endif
00396 n = send(port->sock, ptr, len, 0);
00397
00398 return n;
00399 }
00400
00401
00402
00403
00404 #ifdef USE_SSL
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 static bool my_bio_initialized = false;
00418 static BIO_METHOD my_bio_methods;
00419
00420 static int
00421 my_sock_read(BIO *h, char *buf, int size)
00422 {
00423 int res = 0;
00424
00425 prepare_for_client_read();
00426
00427 if (buf != NULL)
00428 {
00429 res = recv(h->num, buf, size, 0);
00430 BIO_clear_retry_flags(h);
00431 if (res <= 0)
00432 {
00433
00434 if (errno == EINTR)
00435 {
00436 BIO_set_retry_read(h);
00437 }
00438 }
00439 }
00440
00441 client_read_ended();
00442
00443 return res;
00444 }
00445
00446 static int
00447 my_sock_write(BIO *h, const char *buf, int size)
00448 {
00449 int res = 0;
00450
00451 res = send(h->num, buf, size, 0);
00452 if (res <= 0)
00453 {
00454 if (errno == EINTR)
00455 {
00456 BIO_set_retry_write(h);
00457 }
00458 }
00459
00460 return res;
00461 }
00462
00463 static BIO_METHOD *
00464 my_BIO_s_socket(void)
00465 {
00466 if (!my_bio_initialized)
00467 {
00468 memcpy(&my_bio_methods, BIO_s_socket(), sizeof(BIO_METHOD));
00469 my_bio_methods.bread = my_sock_read;
00470 my_bio_methods.bwrite = my_sock_write;
00471 my_bio_initialized = true;
00472 }
00473 return &my_bio_methods;
00474 }
00475
00476
00477 static int
00478 my_SSL_set_fd(SSL *s, int fd)
00479 {
00480 int ret = 0;
00481 BIO *bio = NULL;
00482
00483 bio = BIO_new(my_BIO_s_socket());
00484
00485 if (bio == NULL)
00486 {
00487 SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
00488 goto err;
00489 }
00490 BIO_set_fd(bio, fd, BIO_NOCLOSE);
00491 SSL_set_bio(s, bio, bio);
00492 ret = 1;
00493 err:
00494 return ret;
00495 }
00496
00497
00498
00499
00500
00501
00502
00503
00504 static DH *
00505 load_dh_file(int keylength)
00506 {
00507 FILE *fp;
00508 char fnbuf[MAXPGPATH];
00509 DH *dh = NULL;
00510 int codes;
00511
00512
00513 snprintf(fnbuf, sizeof(fnbuf), "dh%d.pem", keylength);
00514 if ((fp = fopen(fnbuf, "r")) == NULL)
00515 return NULL;
00516
00517
00518 dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
00519
00520 fclose(fp);
00521
00522
00523 if (dh != NULL && 8 * DH_size(dh) < keylength)
00524 {
00525 elog(LOG, "DH errors (%s): %d bits expected, %d bits found",
00526 fnbuf, keylength, 8 * DH_size(dh));
00527 dh = NULL;
00528 }
00529
00530
00531 if (dh != NULL)
00532 {
00533 if (DH_check(dh, &codes) == 0)
00534 {
00535 elog(LOG, "DH_check error (%s): %s", fnbuf, SSLerrmessage());
00536 return NULL;
00537 }
00538 if (codes & DH_CHECK_P_NOT_PRIME)
00539 {
00540 elog(LOG, "DH error (%s): p is not prime", fnbuf);
00541 return NULL;
00542 }
00543 if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
00544 (codes & DH_CHECK_P_NOT_SAFE_PRIME))
00545 {
00546 elog(LOG,
00547 "DH error (%s): neither suitable generator or safe prime",
00548 fnbuf);
00549 return NULL;
00550 }
00551 }
00552
00553 return dh;
00554 }
00555
00556
00557
00558
00559
00560
00561
00562 static DH *
00563 load_dh_buffer(const char *buffer, size_t len)
00564 {
00565 BIO *bio;
00566 DH *dh = NULL;
00567
00568 bio = BIO_new_mem_buf((char *) buffer, len);
00569 if (bio == NULL)
00570 return NULL;
00571 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
00572 if (dh == NULL)
00573 ereport(DEBUG2,
00574 (errmsg_internal("DH load buffer: %s",
00575 SSLerrmessage())));
00576 BIO_free(bio);
00577
00578 return dh;
00579 }
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594 static DH *
00595 tmp_dh_cb(SSL *s, int is_export, int keylength)
00596 {
00597 DH *r = NULL;
00598 static DH *dh = NULL;
00599 static DH *dh512 = NULL;
00600 static DH *dh1024 = NULL;
00601 static DH *dh2048 = NULL;
00602 static DH *dh4096 = NULL;
00603
00604 switch (keylength)
00605 {
00606 case 512:
00607 if (dh512 == NULL)
00608 dh512 = load_dh_file(keylength);
00609 if (dh512 == NULL)
00610 dh512 = load_dh_buffer(file_dh512, sizeof file_dh512);
00611 r = dh512;
00612 break;
00613
00614 case 1024:
00615 if (dh1024 == NULL)
00616 dh1024 = load_dh_file(keylength);
00617 if (dh1024 == NULL)
00618 dh1024 = load_dh_buffer(file_dh1024, sizeof file_dh1024);
00619 r = dh1024;
00620 break;
00621
00622 case 2048:
00623 if (dh2048 == NULL)
00624 dh2048 = load_dh_file(keylength);
00625 if (dh2048 == NULL)
00626 dh2048 = load_dh_buffer(file_dh2048, sizeof file_dh2048);
00627 r = dh2048;
00628 break;
00629
00630 case 4096:
00631 if (dh4096 == NULL)
00632 dh4096 = load_dh_file(keylength);
00633 if (dh4096 == NULL)
00634 dh4096 = load_dh_buffer(file_dh4096, sizeof file_dh4096);
00635 r = dh4096;
00636 break;
00637
00638 default:
00639 if (dh == NULL)
00640 dh = load_dh_file(keylength);
00641 r = dh;
00642 }
00643
00644
00645 if (r == NULL || 8 * DH_size(r) < keylength)
00646 {
00647 ereport(DEBUG2,
00648 (errmsg_internal("DH: generating parameters (%d bits)",
00649 keylength)));
00650 r = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL);
00651 }
00652
00653 return r;
00654 }
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667 static int
00668 verify_cb(int ok, X509_STORE_CTX *ctx)
00669 {
00670 return ok;
00671 }
00672
00673
00674
00675
00676
00677 static void
00678 info_cb(const SSL *ssl, int type, int args)
00679 {
00680 switch (type)
00681 {
00682 case SSL_CB_HANDSHAKE_START:
00683 ereport(DEBUG4,
00684 (errmsg_internal("SSL: handshake start")));
00685 break;
00686 case SSL_CB_HANDSHAKE_DONE:
00687 ereport(DEBUG4,
00688 (errmsg_internal("SSL: handshake done")));
00689 break;
00690 case SSL_CB_ACCEPT_LOOP:
00691 ereport(DEBUG4,
00692 (errmsg_internal("SSL: accept loop")));
00693 break;
00694 case SSL_CB_ACCEPT_EXIT:
00695 ereport(DEBUG4,
00696 (errmsg_internal("SSL: accept exit (%d)", args)));
00697 break;
00698 case SSL_CB_CONNECT_LOOP:
00699 ereport(DEBUG4,
00700 (errmsg_internal("SSL: connect loop")));
00701 break;
00702 case SSL_CB_CONNECT_EXIT:
00703 ereport(DEBUG4,
00704 (errmsg_internal("SSL: connect exit (%d)", args)));
00705 break;
00706 case SSL_CB_READ_ALERT:
00707 ereport(DEBUG4,
00708 (errmsg_internal("SSL: read alert (0x%04x)", args)));
00709 break;
00710 case SSL_CB_WRITE_ALERT:
00711 ereport(DEBUG4,
00712 (errmsg_internal("SSL: write alert (0x%04x)", args)));
00713 break;
00714 }
00715 }
00716
00717
00718
00719
00720 static void
00721 initialize_SSL(void)
00722 {
00723 struct stat buf;
00724
00725 STACK_OF(X509_NAME) *root_cert_list = NULL;
00726
00727 if (!SSL_context)
00728 {
00729 #if SSLEAY_VERSION_NUMBER >= 0x0907000L
00730 OPENSSL_config(NULL);
00731 #endif
00732 SSL_library_init();
00733 SSL_load_error_strings();
00734 SSL_context = SSL_CTX_new(SSLv23_method());
00735 if (!SSL_context)
00736 ereport(FATAL,
00737 (errmsg("could not create SSL context: %s",
00738 SSLerrmessage())));
00739
00740
00741
00742
00743
00744 SSL_CTX_set_mode(SSL_context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
00745
00746
00747
00748
00749 if (SSL_CTX_use_certificate_chain_file(SSL_context,
00750 ssl_cert_file) != 1)
00751 ereport(FATAL,
00752 (errcode(ERRCODE_CONFIG_FILE_ERROR),
00753 errmsg("could not load server certificate file \"%s\": %s",
00754 ssl_cert_file, SSLerrmessage())));
00755
00756 if (stat(ssl_key_file, &buf) != 0)
00757 ereport(FATAL,
00758 (errcode_for_file_access(),
00759 errmsg("could not access private key file \"%s\": %m",
00760 ssl_key_file)));
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770 #if !defined(WIN32) && !defined(__CYGWIN__)
00771 if (!S_ISREG(buf.st_mode) || buf.st_mode & (S_IRWXG | S_IRWXO))
00772 ereport(FATAL,
00773 (errcode(ERRCODE_CONFIG_FILE_ERROR),
00774 errmsg("private key file \"%s\" has group or world access",
00775 ssl_key_file),
00776 errdetail("Permissions should be u=rw (0600) or less.")));
00777 #endif
00778
00779 if (SSL_CTX_use_PrivateKey_file(SSL_context,
00780 ssl_key_file,
00781 SSL_FILETYPE_PEM) != 1)
00782 ereport(FATAL,
00783 (errmsg("could not load private key file \"%s\": %s",
00784 ssl_key_file, SSLerrmessage())));
00785
00786 if (SSL_CTX_check_private_key(SSL_context) != 1)
00787 ereport(FATAL,
00788 (errmsg("check of private key failed: %s",
00789 SSLerrmessage())));
00790 }
00791
00792
00793 SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
00794 SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2);
00795
00796
00797 if (SSL_CTX_set_cipher_list(SSL_context, SSLCipherSuites) != 1)
00798 elog(FATAL, "could not set the cipher list (no valid ciphers available)");
00799
00800
00801
00802
00803 if (ssl_ca_file[0])
00804 {
00805 if (SSL_CTX_load_verify_locations(SSL_context, ssl_ca_file, NULL) != 1 ||
00806 (root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
00807 ereport(FATAL,
00808 (errmsg("could not load root certificate file \"%s\": %s",
00809 ssl_ca_file, SSLerrmessage())));
00810 }
00811
00812
00813
00814
00815
00816
00817 if (ssl_crl_file[0])
00818 {
00819 X509_STORE *cvstore = SSL_CTX_get_cert_store(SSL_context);
00820
00821 if (cvstore)
00822 {
00823
00824 if (X509_STORE_load_locations(cvstore, ssl_crl_file, NULL) == 1)
00825 {
00826
00827 #ifdef X509_V_FLAG_CRL_CHECK
00828 X509_STORE_set_flags(cvstore,
00829 X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
00830 #else
00831 ereport(LOG,
00832 (errmsg("SSL certificate revocation list file \"%s\" ignored",
00833 ssl_crl_file),
00834 errdetail("SSL library does not support certificate revocation lists.")));
00835 #endif
00836 }
00837 else
00838 ereport(FATAL,
00839 (errmsg("could not load SSL certificate revocation list file \"%s\": %s",
00840 ssl_crl_file, SSLerrmessage())));
00841 }
00842 }
00843
00844 if (ssl_ca_file[0])
00845 {
00846
00847
00848
00849
00850
00851 SSL_CTX_set_verify(SSL_context,
00852 (SSL_VERIFY_PEER |
00853 SSL_VERIFY_CLIENT_ONCE),
00854 verify_cb);
00855
00856
00857 ssl_loaded_verify_locations = true;
00858
00859
00860
00861
00862
00863
00864 SSL_CTX_set_client_CA_list(SSL_context, root_cert_list);
00865 }
00866 }
00867
00868
00869
00870
00871 static int
00872 open_server_SSL(Port *port)
00873 {
00874 int r;
00875 int err;
00876
00877 Assert(!port->ssl);
00878 Assert(!port->peer);
00879
00880 if (!(port->ssl = SSL_new(SSL_context)))
00881 {
00882 ereport(COMMERROR,
00883 (errcode(ERRCODE_PROTOCOL_VIOLATION),
00884 errmsg("could not initialize SSL connection: %s",
00885 SSLerrmessage())));
00886 close_SSL(port);
00887 return -1;
00888 }
00889 if (!my_SSL_set_fd(port->ssl, port->sock))
00890 {
00891 ereport(COMMERROR,
00892 (errcode(ERRCODE_PROTOCOL_VIOLATION),
00893 errmsg("could not set SSL socket: %s",
00894 SSLerrmessage())));
00895 close_SSL(port);
00896 return -1;
00897 }
00898
00899 aloop:
00900 r = SSL_accept(port->ssl);
00901 if (r <= 0)
00902 {
00903 err = SSL_get_error(port->ssl, r);
00904 switch (err)
00905 {
00906 case SSL_ERROR_WANT_READ:
00907 case SSL_ERROR_WANT_WRITE:
00908 #ifdef WIN32
00909 pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
00910 (err == SSL_ERROR_WANT_READ) ?
00911 FD_READ | FD_CLOSE | FD_ACCEPT : FD_WRITE | FD_CLOSE,
00912 INFINITE);
00913 #endif
00914 goto aloop;
00915 case SSL_ERROR_SYSCALL:
00916 if (r < 0)
00917 ereport(COMMERROR,
00918 (errcode_for_socket_access(),
00919 errmsg("could not accept SSL connection: %m")));
00920 else
00921 ereport(COMMERROR,
00922 (errcode(ERRCODE_PROTOCOL_VIOLATION),
00923 errmsg("could not accept SSL connection: EOF detected")));
00924 break;
00925 case SSL_ERROR_SSL:
00926 ereport(COMMERROR,
00927 (errcode(ERRCODE_PROTOCOL_VIOLATION),
00928 errmsg("could not accept SSL connection: %s",
00929 SSLerrmessage())));
00930 break;
00931 case SSL_ERROR_ZERO_RETURN:
00932 ereport(COMMERROR,
00933 (errcode(ERRCODE_PROTOCOL_VIOLATION),
00934 errmsg("could not accept SSL connection: EOF detected")));
00935 break;
00936 default:
00937 ereport(COMMERROR,
00938 (errcode(ERRCODE_PROTOCOL_VIOLATION),
00939 errmsg("unrecognized SSL error code: %d",
00940 err)));
00941 break;
00942 }
00943 close_SSL(port);
00944 return -1;
00945 }
00946
00947 port->count = 0;
00948
00949
00950 port->peer = SSL_get_peer_certificate(port->ssl);
00951
00952
00953 port->peer_cn = NULL;
00954 if (port->peer != NULL)
00955 {
00956 int len;
00957
00958 len = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
00959 NID_commonName, NULL, 0);
00960 if (len != -1)
00961 {
00962 char *peer_cn;
00963
00964 peer_cn = MemoryContextAlloc(TopMemoryContext, len + 1);
00965 r = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
00966 NID_commonName, peer_cn, len + 1);
00967 peer_cn[len] = '\0';
00968 if (r != len)
00969 {
00970
00971 pfree(peer_cn);
00972 close_SSL(port);
00973 return -1;
00974 }
00975
00976
00977
00978
00979
00980 if (len != strlen(peer_cn))
00981 {
00982 ereport(COMMERROR,
00983 (errcode(ERRCODE_PROTOCOL_VIOLATION),
00984 errmsg("SSL certificate's common name contains embedded null")));
00985 pfree(peer_cn);
00986 close_SSL(port);
00987 return -1;
00988 }
00989
00990 port->peer_cn = peer_cn;
00991 }
00992 }
00993
00994 ereport(DEBUG2,
00995 (errmsg("SSL connection from \"%s\"",
00996 port->peer_cn ? port->peer_cn : "(anonymous)")));
00997
00998
00999 SSL_CTX_set_info_callback(SSL_context, info_cb);
01000
01001 return 0;
01002 }
01003
01004
01005
01006
01007 static void
01008 close_SSL(Port *port)
01009 {
01010 if (port->ssl)
01011 {
01012 SSL_shutdown(port->ssl);
01013 SSL_free(port->ssl);
01014 port->ssl = NULL;
01015 }
01016
01017 if (port->peer)
01018 {
01019 X509_free(port->peer);
01020 port->peer = NULL;
01021 }
01022
01023 if (port->peer_cn)
01024 {
01025 pfree(port->peer_cn);
01026 port->peer_cn = NULL;
01027 }
01028 }
01029
01030
01031
01032
01033
01034
01035
01036
01037 static const char *
01038 SSLerrmessage(void)
01039 {
01040 unsigned long errcode;
01041 const char *errreason;
01042 static char errbuf[32];
01043
01044 errcode = ERR_get_error();
01045 if (errcode == 0)
01046 return _("no SSL error reported");
01047 errreason = ERR_reason_error_string(errcode);
01048 if (errreason != NULL)
01049 return errreason;
01050 snprintf(errbuf, sizeof(errbuf), _("SSL error code %lu"), errcode);
01051 return errbuf;
01052 }
01053
01054 #endif