From 79259064c9c9cd754dfc246988b9626bbcd1f3b9 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 28 May 2012 13:54:32 +0200 Subject: [PATCH] wininet: Handle error flags only for masked-error mode. --- dlls/wininet/netconnection.c | 32 ++++++++++++------- dlls/wininet/tests/http.c | 61 ++++++++++++++++++++++++++++++++---- 2 files changed, 76 insertions(+), 17 deletions(-) diff --git a/dlls/wininet/netconnection.c b/dlls/wininet/netconnection.c index 238d3650471..8117884fc35 100644 --- a/dlls/wininet/netconnection.c +++ b/dlls/wininet/netconnection.c @@ -247,41 +247,47 @@ static DWORD netconn_verify_cert(netconn_t *conn, PCCERT_CONTEXT cert, HCERTSTOR errors = chain->TrustStatus.dwErrorStatus; if (chain->TrustStatus.dwErrorStatus & ~supportedErrors) { - WARN("CERT_TRUST_IS_NOT_TIME_VALID, unknown error flags\n"); + if(conn->mask_errors) + WARN("CERT_TRUST_IS_NOT_TIME_VALID, unknown error flags\n"); err = ERROR_INTERNET_SEC_INVALID_CERT; errors &= supportedErrors; } if(errors & CERT_TRUST_IS_NOT_TIME_VALID) { - WARN("CERT_TRUST_IS_NOT_TIME_VALID, unknown error flags\n"); + if(conn->mask_errors) + WARN("CERT_TRUST_IS_NOT_TIME_VALID, unknown error flags\n"); if(!(conn->security_flags & SECURITY_FLAG_IGNORE_CERT_DATE_INVALID)) err = ERROR_INTERNET_SEC_CERT_DATE_INVALID; errors &= ~CERT_TRUST_IS_NOT_TIME_VALID; } if(errors & (CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_PARTIAL_CHAIN)) { - conn->security_flags |= _SECURITY_FLAG_CERT_INVALID_CA; + if(conn->mask_errors) + conn->security_flags |= _SECURITY_FLAG_CERT_INVALID_CA; if(!(conn->security_flags & SECURITY_FLAG_IGNORE_UNKNOWN_CA)) err = ERROR_INTERNET_INVALID_CA; errors &= ~(CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_PARTIAL_CHAIN); } if(errors & (CERT_TRUST_IS_OFFLINE_REVOCATION | CERT_TRUST_REVOCATION_STATUS_UNKNOWN)) { - WARN("TRUST_IS_OFFLINE_REVOCATION | CERT_TRUST_REVOCATION_STATUS_UNKNOWN, unknown error flags\n"); + if(conn->mask_errors) + WARN("TRUST_IS_OFFLINE_REVOCATION | CERT_TRUST_REVOCATION_STATUS_UNKNOWN, unknown error flags\n"); if(!(conn->security_flags & SECURITY_FLAG_IGNORE_REVOCATION)) err = ERROR_INTERNET_SEC_CERT_NO_REV; errors &= ~(CERT_TRUST_IS_OFFLINE_REVOCATION | CERT_TRUST_REVOCATION_STATUS_UNKNOWN); } if(errors & CERT_TRUST_IS_REVOKED) { - WARN("TRUST_IS_OFFLINE_REVOCATION | CERT_TRUST_REVOCATION_STATUS_UNKNOWN, unknown error flags\n"); + if(conn->mask_errors) + WARN("TRUST_IS_OFFLINE_REVOCATION | CERT_TRUST_REVOCATION_STATUS_UNKNOWN, unknown error flags\n"); if(!(conn->security_flags & SECURITY_FLAG_IGNORE_REVOCATION)) err = ERROR_INTERNET_SEC_CERT_REVOKED; errors &= ~CERT_TRUST_IS_REVOKED; } if(errors & CERT_TRUST_IS_NOT_VALID_FOR_USAGE) { - WARN("CERT_TRUST_IS_NOT_VALID_FOR_USAGE, unknown error flags\n"); + if(conn->mask_errors) + WARN("CERT_TRUST_IS_NOT_VALID_FOR_USAGE, unknown error flags\n"); if(!(conn->security_flags & SECURITY_FLAG_IGNORE_WRONG_USAGE)) err = ERROR_INTERNET_SEC_INVALID_CERT; errors &= ~CERT_TRUST_IS_NOT_VALID_FOR_USAGE; @@ -313,10 +319,12 @@ static DWORD netconn_verify_cert(netconn_t *conn, PCCERT_CONTEXT cert, HCERTSTOR */ if(ret) { if(policyStatus.dwError == CERT_E_CN_NO_MATCH) { - conn->security_flags |= _SECURITY_FLAG_CERT_INVALID_CN; + if(conn->mask_errors) + conn->security_flags |= _SECURITY_FLAG_CERT_INVALID_CN; err = ERROR_INTERNET_SEC_CERT_CN_INVALID; }else if(policyStatus.dwError) { - WARN("unknown error flags for policy status %x\n", policyStatus.dwError); + if(conn->mask_errors) + WARN("unknown error flags for policy status %x\n", policyStatus.dwError); err = ERROR_INTERNET_SEC_INVALID_CERT; } }else { @@ -328,9 +336,10 @@ static DWORD netconn_verify_cert(netconn_t *conn, PCCERT_CONTEXT cert, HCERTSTOR if(err) { WARN("failed %u\n", err); - conn->server->security_flags |= conn->security_flags & _SECURITY_ERROR_FLAGS_MASK; - if(conn->mask_errors) + if(conn->mask_errors) { + conn->server->security_flags |= conn->security_flags & _SECURITY_ERROR_FLAGS_MASK; return err == ERROR_INTERNET_INVALID_CA ? ERROR_INTERNET_SEC_CERT_REV_FAILED : ERROR_INTERNET_SEC_CERT_ERRORS; + } return err; } @@ -772,7 +781,8 @@ DWORD NETCON_secure_connect(netconn_t *connection) connection->security_flags |= SECURITY_FLAG_STRENGTH_WEAK; connection->security_flags |= SECURITY_FLAG_SECURE; - connection->server->security_flags = connection->security_flags; + if(connection->mask_errors) + connection->server->security_flags = connection->security_flags; return ERROR_SUCCESS; fail: diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c index 2cfc2af8c85..2e7b6935ce8 100644 --- a/dlls/wininet/tests/http.c +++ b/dlls/wininet/tests/http.c @@ -2929,12 +2929,63 @@ static void test_security_flags(void) ok(req != NULL, "HttpOpenRequest failed\n"); CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED); + test_secflags_option(req, 0); + set_secflags(req, SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_IGNORE_REVOCATION); + test_secflags_option(req, SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_IGNORE_REVOCATION); + + SET_EXPECT(INTERNET_STATUS_RESOLVING_NAME); + SET_EXPECT(INTERNET_STATUS_NAME_RESOLVED); + SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER); + SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER); + SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST); + SET_EXPECT(INTERNET_STATUS_REQUEST_SENT); + SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE); + SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED); + SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE); + SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY); + SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT); + + res = HttpSendRequest(req, NULL, 0, NULL, 0); + ok(!res && GetLastError() == ERROR_IO_PENDING, "HttpSendRequest failed: %u\n", GetLastError()); + + WaitForSingleObject(hCompleteEvent, INFINITE); + ok(req_error == ERROR_SUCCESS, "req_error = %d\n", req_error); + + todo_wine CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME); + todo_wine CHECK_NOT_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED); + CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER); + CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER); + CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST); + CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT); + CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE); + CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED); + CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE); + CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY); + CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT); + + test_request_flags(req, 0); + test_secflags_option(req, SECURITY_FLAG_SECURE|SECURITY_FLAG_IGNORE_UNKNOWN_CA| + SECURITY_FLAG_IGNORE_REVOCATION|SECURITY_FLAG_STRENGTH_STRONG); + + res = InternetReadFile(req, buf, sizeof(buf), &size); + ok(res, "InternetReadFile failed: %u\n", GetLastError()); + ok(size, "size = 0\n"); + + /* Collect all existing persistent connections */ + res = InternetSetOptionA(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0); + ok(res, "InternetSetOption(INTERNET_OPTION_END_BROWSER_SESSION) failed: %u\n", GetLastError()); + + SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED); + req = HttpOpenRequest(conn, "GET", "/tests/hello.html", NULL, NULL, NULL, + INTERNET_FLAG_SECURE|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_RELOAD|INTERNET_FLAG_NO_CACHE_WRITE, + 0xdeadbeef); + ok(req != NULL, "HttpOpenRequest failed\n"); + CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED); + flags = INTERNET_ERROR_MASK_COMBINED_SEC_CERT|INTERNET_ERROR_MASK_LOGIN_FAILURE_DISPLAY_ENTITY_BODY; res = InternetSetOption(req, INTERNET_OPTION_ERROR_MASK, (void*)&flags, sizeof(flags)); ok(res, "InternetQueryOption(INTERNET_OPTION_ERROR_MASK failed: %u\n", GetLastError()); - SET_EXPECT(INTERNET_STATUS_RESOLVING_NAME); - SET_EXPECT(INTERNET_STATUS_NAME_RESOLVED); SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER); SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER); SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION); @@ -2950,8 +3001,6 @@ static void test_security_flags(void) ok(req_error == ERROR_INTERNET_SEC_CERT_REV_FAILED || broken(req_error == ERROR_INTERNET_SEC_CERT_ERRORS), "req_error = %d\n", req_error); - todo_wine CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME); - todo_wine CHECK_NOT_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED); CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER); CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER); CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION); @@ -2963,7 +3012,7 @@ static void test_security_flags(void) if(req_error != ERROR_INTERNET_SEC_CERT_REV_FAILED) { win_skip("Unexpected cert errors, skipping security flags tests\n"); - close_async_handle(ses, hCompleteEvent, 2); + close_async_handle(ses, hCompleteEvent, 3); CloseHandle(hCompleteEvent); return; } @@ -3013,7 +3062,7 @@ static void test_security_flags(void) ok(res, "InternetReadFile failed: %u\n", GetLastError()); ok(size, "size = 0\n"); - close_async_handle(ses, hCompleteEvent, 2); + close_async_handle(ses, hCompleteEvent, 3); /* Collect all existing persistent connections */ res = InternetSetOptionA(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);