|
11 | 11 | * |
12 | 12 | * |
13 | 13 | * IDENTIFICATION |
14 | | - * $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.85 2008/10/24 12:24:35 mha Exp $ |
| 14 | + * $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.86 2008/11/20 09:29:36 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 |
@@ -102,6 +102,7 @@ static const char *SSLerrmessage(void); |
102 | 102 | #defineRENEGOTIATION_LIMIT (512 * 1024 * 1024) |
103 | 103 |
|
104 | 104 | staticSSL_CTX*SSL_context=NULL; |
| 105 | +staticboolssl_loaded_verify_locations= false; |
105 | 106 |
|
106 | 107 | /* GUC variable controlling SSL cipher list */ |
107 | 108 | char*SSLCipherSuites=NULL; |
@@ -202,6 +203,19 @@ secure_destroy(void) |
202 | 203 | #endif |
203 | 204 | } |
204 | 205 |
|
| 206 | +/* |
| 207 | + * Indicate if we have loaded the root CA store to verify certificates |
| 208 | + */ |
| 209 | +bool |
| 210 | +secure_loaded_verify_locations(void) |
| 211 | +{ |
| 212 | +#ifdefUSE_SSL |
| 213 | +returnssl_loaded_verify_locations; |
| 214 | +#endif |
| 215 | + |
| 216 | +return false; |
| 217 | +} |
| 218 | + |
205 | 219 | /* |
206 | 220 | *Attempt to negotiate secure session. |
207 | 221 | */ |
@@ -754,15 +768,34 @@ initialize_SSL(void) |
754 | 768 | elog(FATAL,"could not set the cipher list (no valid ciphers available)"); |
755 | 769 |
|
756 | 770 | /* |
757 | | - *Require and check client certificates only ifwehave a root.crt file. |
| 771 | + *Attempt to load CA store, sowecan verify client certificates if needed. |
758 | 772 | */ |
759 | | -if (!SSL_CTX_load_verify_locations(SSL_context,ROOT_CERT_FILE,NULL)) |
| 773 | +if (access(ROOT_CERT_FILE,R_OK)) |
760 | 774 | { |
761 | | -/* Not fatal - we do not require client certificates */ |
762 | | -ereport(LOG, |
| 775 | +ssl_loaded_verify_locations= false; |
| 776 | + |
| 777 | +/* |
| 778 | + * If root certificate file simply not found. Don't log an error here, because |
| 779 | + * it's quite likely the user isn't planning on using client certificates. |
| 780 | + * If we can't access it for other reasons, it is an error. |
| 781 | + */ |
| 782 | +if (errno!=ENOENT) |
| 783 | +{ |
| 784 | +ereport(FATAL, |
| 785 | +(errmsg("could not access root certificate file \"%s\": %m", |
| 786 | +ROOT_CERT_FILE))); |
| 787 | +} |
| 788 | +} |
| 789 | +elseif (!SSL_CTX_load_verify_locations(SSL_context,ROOT_CERT_FILE,NULL)) |
| 790 | +{ |
| 791 | +/* |
| 792 | + * File was there, but we could not load it. This means the file is somehow |
| 793 | + * broken, and we cannot do verification at all - so abort here. |
| 794 | + */ |
| 795 | +ssl_loaded_verify_locations= false; |
| 796 | +ereport(FATAL, |
763 | 797 | (errmsg("could not load root certificate file \"%s\": %s", |
764 | | -ROOT_CERT_FILE,SSLerrmessage()), |
765 | | -errdetail("Will not verify client certificates."))); |
| 798 | +ROOT_CERT_FILE,SSLerrmessage()))); |
766 | 799 | } |
767 | 800 | else |
768 | 801 | { |
@@ -795,13 +828,18 @@ initialize_SSL(void) |
795 | 828 | ROOT_CRL_FILE,SSLerrmessage()), |
796 | 829 | errdetail("Certificates will not be checked against revocation list."))); |
797 | 830 | } |
798 | | -} |
799 | 831 |
|
800 | | -SSL_CTX_set_verify(SSL_context, |
801 | | - (SSL_VERIFY_PEER | |
802 | | -SSL_VERIFY_FAIL_IF_NO_PEER_CERT | |
803 | | -SSL_VERIFY_CLIENT_ONCE), |
804 | | -verify_cb); |
| 832 | +/* |
| 833 | + * Always ask for SSL client cert, but don't fail if it's not presented. We'll fail later in this case, |
| 834 | + * based on what we find in pg_hba.conf. |
| 835 | + */ |
| 836 | +SSL_CTX_set_verify(SSL_context, |
| 837 | + (SSL_VERIFY_PEER | |
| 838 | +SSL_VERIFY_CLIENT_ONCE), |
| 839 | +verify_cb); |
| 840 | + |
| 841 | +ssl_loaded_verify_locations= true; |
| 842 | +} |
805 | 843 | } |
806 | 844 | } |
807 | 845 |
|
|