|
11 | 11 | *
|
12 | 12 | *
|
13 | 13 | * IDENTIFICATION
|
14 |
| - * $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.87 2008/12/03 20:04:26 mha Exp $ |
| 14 | + * $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.88 2008/12/14 19:39:37 mha Exp $ |
15 | 15 | *
|
16 | 16 | * Since the server static private key ($DataDir/server.key)
|
17 | 17 | * will normally be stored unencrypted so that the database
|
@@ -394,45 +394,71 @@ secure_write(Port *port, void *ptr, size_t len)
|
394 | 394 | #ifdefUSE_SSL
|
395 | 395 |
|
396 | 396 | /*
|
397 |
| - * Private substitute BIO: this wraps the SSL library's standard socket BIO |
398 |
| - * so that we can enable and disable interrupts just while calling recv(). |
399 |
| - * We cannot have interrupts occurring while the bulk of openssl runs, |
400 |
| - * because it uses malloc() and possibly other non-reentrant libc facilities. |
| 397 | + * Private substitute BIO: this does the sending and receiving using send() and |
| 398 | + * recv() instead. This is so that we can enable and disable interrupts |
| 399 | + * just while calling recv(). We cannot have interrupts occurring while |
| 400 | + * the bulk of openssl runs, because it uses malloc() and possibly other |
| 401 | + * non-reentrant libc facilities. We also need to call send() and recv() |
| 402 | + * directly so it gets passed through the socket/signals layer on Win32. |
| 403 | + * |
| 404 | + * They are closely modelled on the original socket implementations in OpenSSL. |
401 | 405 | *
|
402 |
| - * As of openssl 0.9.7, we can use the reasonably clean method of interposing |
403 |
| - * a wrapper around the standard socket BIO's sock_read() method. This relies |
404 |
| - * on the fact that sock_read() doesn't call anything non-reentrant, in fact |
405 |
| - * not much of anything at all except recv(). If this ever changes we'd |
406 |
| - * probably need to duplicate the code of sock_read() in order to push the |
407 |
| - * interrupt enable/disable down yet another level. |
408 | 406 | */
|
409 | 407 |
|
410 | 408 | staticboolmy_bio_initialized= false;
|
411 | 409 | staticBIO_METHODmy_bio_methods;
|
412 |
| -staticint(*std_sock_read) (BIO*h,char*buf,intsize); |
413 | 410 |
|
414 | 411 | staticint
|
415 | 412 | my_sock_read(BIO*h,char*buf,intsize)
|
416 | 413 | {
|
417 |
| -intres; |
| 414 | +intres=0; |
418 | 415 |
|
419 | 416 | prepare_for_client_read();
|
420 | 417 |
|
421 |
| -res=std_sock_read(h,buf,size); |
| 418 | +if (buf!=NULL) |
| 419 | +{ |
| 420 | +res=recv(h->num,buf,size,0); |
| 421 | +BIO_clear_retry_flags(h); |
| 422 | +if (res <=0) |
| 423 | +{ |
| 424 | +/* If we were interrupted, tell caller to retry */ |
| 425 | +if (errno==EINTR) |
| 426 | +{ |
| 427 | +BIO_set_retry_read(h); |
| 428 | +} |
| 429 | +} |
| 430 | +} |
422 | 431 |
|
423 | 432 | client_read_ended();
|
424 | 433 |
|
425 | 434 | returnres;
|
426 | 435 | }
|
427 | 436 |
|
| 437 | +staticint |
| 438 | +my_sock_write(BIO*h,constchar*buf,intsize) |
| 439 | +{ |
| 440 | +intres=0; |
| 441 | + |
| 442 | +res=send(h->num,buf,size,0); |
| 443 | +if (res <=0) |
| 444 | +{ |
| 445 | +if (errno==EINTR) |
| 446 | +{ |
| 447 | +BIO_set_retry_write(h); |
| 448 | +} |
| 449 | +} |
| 450 | + |
| 451 | +returnres; |
| 452 | +} |
| 453 | + |
428 | 454 | staticBIO_METHOD*
|
429 | 455 | my_BIO_s_socket(void)
|
430 | 456 | {
|
431 | 457 | if (!my_bio_initialized)
|
432 | 458 | {
|
433 | 459 | memcpy(&my_bio_methods,BIO_s_socket(),sizeof(BIO_METHOD));
|
434 |
| -std_sock_read=my_bio_methods.bread; |
435 | 460 | my_bio_methods.bread=my_sock_read;
|
| 461 | +my_bio_methods.bwrite=my_sock_write; |
436 | 462 | my_bio_initialized= true;
|
437 | 463 | }
|
438 | 464 | return&my_bio_methods;
|
|