|
11 | 11 | *
|
12 | 12 | *
|
13 | 13 | * IDENTIFICATION
|
14 |
| - * $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.115 2009/01/01 17:24:03 momjian Exp $ |
| 14 | + * $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.116 2009/01/07 12:02:46 mha Exp $ |
15 | 15 | *
|
16 | 16 | * NOTES
|
17 | 17 | *
|
@@ -560,11 +560,18 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
560 | 560 | PGconn*conn= (PGconn*)SSL_get_app_data(ssl);
|
561 | 561 | charsebuf[256];
|
562 | 562 |
|
563 |
| -if (!pqGetHomeDirectory(homedir,sizeof(homedir))) |
| 563 | +/* |
| 564 | + * If conn->sslcert or conn->sslkey is not set, we don't need the home |
| 565 | + * directory to find the required files. |
| 566 | + */ |
| 567 | +if (!conn->sslcert|| !conn->sslkey) |
564 | 568 | {
|
565 |
| -printfPQExpBuffer(&conn->errorMessage, |
566 |
| -libpq_gettext("could not get user information\n")); |
567 |
| -return0; |
| 569 | +if (!pqGetHomeDirectory(homedir,sizeof(homedir))) |
| 570 | +{ |
| 571 | +printfPQExpBuffer(&conn->errorMessage, |
| 572 | +libpq_gettext("cannot find home directory to locate client certificate files")); |
| 573 | +return0; |
| 574 | +} |
568 | 575 | }
|
569 | 576 |
|
570 | 577 | /* read the user certificate */
|
@@ -964,76 +971,85 @@ initialize_SSL(PGconn *conn)
|
964 | 971 | * If sslverify is set to anything other than "none", perform certificate
|
965 | 972 | * verification. If set to "cn" we will also do further verifications after
|
966 | 973 | * the connection has been completed.
|
| 974 | + * |
| 975 | + * If we are going to look for either root certificate or CRL in the home directory, |
| 976 | + * we need pqGetHomeDirectory() to succeed. In other cases, we don't need to |
| 977 | + * get the home directory explicitly. |
967 | 978 | */
|
968 |
| - |
969 |
| -/* Set up to verify server cert, if root.crt is present */ |
970 |
| -if (pqGetHomeDirectory(homedir,sizeof(homedir))) |
| 979 | +if (!conn->sslrootcert|| !conn->sslcrl) |
971 | 980 | {
|
972 |
| -if (conn->sslrootcert) |
973 |
| -strncpy(fnbuf,conn->sslrootcert,sizeof(fnbuf)); |
974 |
| -else |
975 |
| -snprintf(fnbuf,sizeof(fnbuf),"%s/%s",homedir,ROOT_CERT_FILE); |
976 |
| - |
977 |
| -if (stat(fnbuf,&buf)==0) |
| 981 | +if (!pqGetHomeDirectory(homedir,sizeof(homedir))) |
978 | 982 | {
|
979 |
| -X509_STORE*cvstore; |
980 |
| - |
981 |
| -if (!SSL_CTX_load_verify_locations(SSL_context,fnbuf,NULL)) |
| 983 | +if (strcmp(conn->sslverify,"none")!=0) |
982 | 984 | {
|
983 |
| -char*err=SSLerrmessage(); |
984 |
| - |
985 | 985 | printfPQExpBuffer(&conn->errorMessage,
|
986 |
| -libpq_gettext("could not read root certificate file \"%s\": %s\n"), |
987 |
| -fnbuf,err); |
988 |
| -SSLerrfree(err); |
| 986 | +libpq_gettext("cannot find home directory to locate root certificate file")); |
989 | 987 | return-1;
|
990 | 988 | }
|
| 989 | +} |
| 990 | +} |
| 991 | +else |
| 992 | +{ |
| 993 | +homedir[0]='\0'; |
| 994 | +} |
991 | 995 |
|
992 |
| -if ((cvstore=SSL_CTX_get_cert_store(SSL_context))!=NULL) |
993 |
| -{ |
994 |
| -if (conn->sslcrl) |
995 |
| -strncpy(fnbuf,conn->sslcrl,sizeof(fnbuf)); |
996 |
| -else |
997 |
| -snprintf(fnbuf,sizeof(fnbuf),"%s/%s",homedir,ROOT_CRL_FILE); |
998 | 996 |
|
999 |
| -/* setting the flags to check against the complete CRL chain */ |
1000 |
| -if (X509_STORE_load_locations(cvstore,fnbuf,NULL)!=0) |
1001 |
| -/* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */ |
1002 |
| -#ifdefX509_V_FLAG_CRL_CHECK |
1003 |
| -X509_STORE_set_flags(cvstore, |
1004 |
| -X509_V_FLAG_CRL_CHECK |X509_V_FLAG_CRL_CHECK_ALL); |
1005 |
| -/* if not found, silently ignore; we do not require CRL */ |
1006 |
| -#else |
1007 |
| -{ |
1008 |
| -char*err=SSLerrmessage(); |
1009 | 997 |
|
1010 |
| -printfPQExpBuffer(&conn->errorMessage, |
1011 |
| -libpq_gettext("SSL library does not support CRL certificates (file \"%s\")\n"), |
1012 |
| -fnbuf); |
1013 |
| -SSLerrfree(err); |
1014 |
| -return-1; |
1015 |
| -} |
1016 |
| -#endif |
1017 |
| -} |
| 998 | +if (conn->sslrootcert) |
| 999 | +strncpy(fnbuf,conn->sslrootcert,sizeof(fnbuf)); |
| 1000 | +else |
| 1001 | +snprintf(fnbuf,sizeof(fnbuf),"%s/%s",homedir,ROOT_CERT_FILE); |
| 1002 | + |
| 1003 | +if (stat(fnbuf,&buf)==0) |
| 1004 | +{ |
| 1005 | +X509_STORE*cvstore; |
| 1006 | + |
| 1007 | +if (!SSL_CTX_load_verify_locations(SSL_context,fnbuf,NULL)) |
| 1008 | +{ |
| 1009 | +char*err=SSLerrmessage(); |
1018 | 1010 |
|
1019 |
| -SSL_CTX_set_verify(SSL_context,SSL_VERIFY_PEER,verify_cb); |
| 1011 | +printfPQExpBuffer(&conn->errorMessage, |
| 1012 | +libpq_gettext("could not read root certificate file \"%s\": %s\n"), |
| 1013 | +fnbuf,err); |
| 1014 | +SSLerrfree(err); |
| 1015 | +return-1; |
1020 | 1016 | }
|
1021 |
| -else |
| 1017 | + |
| 1018 | +if ((cvstore=SSL_CTX_get_cert_store(SSL_context))!=NULL) |
1022 | 1019 | {
|
1023 |
| -if (strcmp(conn->sslverify,"none")!=0) |
| 1020 | +if (conn->sslcrl) |
| 1021 | +strncpy(fnbuf,conn->sslcrl,sizeof(fnbuf)); |
| 1022 | +else |
| 1023 | +snprintf(fnbuf,sizeof(fnbuf),"%s/%s",homedir,ROOT_CRL_FILE); |
| 1024 | + |
| 1025 | +/* setting the flags to check against the complete CRL chain */ |
| 1026 | +if (X509_STORE_load_locations(cvstore,fnbuf,NULL)!=0) |
| 1027 | +/* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */ |
| 1028 | +#ifdefX509_V_FLAG_CRL_CHECK |
| 1029 | +X509_STORE_set_flags(cvstore, |
| 1030 | +X509_V_FLAG_CRL_CHECK |X509_V_FLAG_CRL_CHECK_ALL); |
| 1031 | +/* if not found, silently ignore; we do not require CRL */ |
| 1032 | +#else |
1024 | 1033 | {
|
| 1034 | +char*err=SSLerrmessage(); |
| 1035 | + |
1025 | 1036 | printfPQExpBuffer(&conn->errorMessage,
|
1026 |
| -libpq_gettext("root certificate file (%s) not found"),fnbuf); |
| 1037 | +libpq_gettext("SSL library does not support CRL certificates (file \"%s\")\n"), |
| 1038 | +fnbuf); |
| 1039 | +SSLerrfree(err); |
1027 | 1040 | return-1;
|
1028 | 1041 | }
|
| 1042 | +#endif |
1029 | 1043 | }
|
1030 |
| -} |
| 1044 | + |
| 1045 | +SSL_CTX_set_verify(SSL_context,SSL_VERIFY_PEER,verify_cb); |
| 1046 | +}/* root certificate exists */ |
1031 | 1047 | else
|
1032 | 1048 | {
|
1033 | 1049 | if (strcmp(conn->sslverify,"none")!=0)
|
1034 | 1050 | {
|
1035 | 1051 | printfPQExpBuffer(&conn->errorMessage,
|
1036 |
| -libpq_gettext("cannot find home directory to locateroot certificate file")); |
| 1052 | +libpq_gettext("root certificate file (%s) not found"),fnbuf); |
1037 | 1053 | return-1;
|
1038 | 1054 | }
|
1039 | 1055 | }
|
|