|
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 | #define RENEGOTIATION_LIMIT (512 * 1024 * 1024) |
103 | 103 |
|
104 | 104 | static SSL_CTX *SSL_context = NULL; |
| 105 | +static bool ssl_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 | +#ifdef USE_SSL |
| 213 | + return ssl_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 if we have a root.crt file. |
| 771 | + * Attempt to load CA store, so we can 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 | + else if (!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 |
|
|
0 commit comments