|
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 | } |
|