wininet: Handle error flags only for masked-error mode.

This commit is contained in:
Jacek Caban 2012-05-28 13:54:32 +02:00 committed by Alexandre Julliard
parent ef30973370
commit 79259064c9
2 changed files with 76 additions and 17 deletions

View File

@ -247,41 +247,47 @@ static DWORD netconn_verify_cert(netconn_t *conn, PCCERT_CONTEXT cert, HCERTSTOR
errors = chain->TrustStatus.dwErrorStatus; errors = chain->TrustStatus.dwErrorStatus;
if (chain->TrustStatus.dwErrorStatus & ~supportedErrors) { 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; err = ERROR_INTERNET_SEC_INVALID_CERT;
errors &= supportedErrors; errors &= supportedErrors;
} }
if(errors & CERT_TRUST_IS_NOT_TIME_VALID) { 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)) if(!(conn->security_flags & SECURITY_FLAG_IGNORE_CERT_DATE_INVALID))
err = ERROR_INTERNET_SEC_CERT_DATE_INVALID; err = ERROR_INTERNET_SEC_CERT_DATE_INVALID;
errors &= ~CERT_TRUST_IS_NOT_TIME_VALID; errors &= ~CERT_TRUST_IS_NOT_TIME_VALID;
} }
if(errors & (CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_PARTIAL_CHAIN)) { 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)) if(!(conn->security_flags & SECURITY_FLAG_IGNORE_UNKNOWN_CA))
err = ERROR_INTERNET_INVALID_CA; err = ERROR_INTERNET_INVALID_CA;
errors &= ~(CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_PARTIAL_CHAIN); errors &= ~(CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_PARTIAL_CHAIN);
} }
if(errors & (CERT_TRUST_IS_OFFLINE_REVOCATION | CERT_TRUST_REVOCATION_STATUS_UNKNOWN)) { 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)) if(!(conn->security_flags & SECURITY_FLAG_IGNORE_REVOCATION))
err = ERROR_INTERNET_SEC_CERT_NO_REV; err = ERROR_INTERNET_SEC_CERT_NO_REV;
errors &= ~(CERT_TRUST_IS_OFFLINE_REVOCATION | CERT_TRUST_REVOCATION_STATUS_UNKNOWN); errors &= ~(CERT_TRUST_IS_OFFLINE_REVOCATION | CERT_TRUST_REVOCATION_STATUS_UNKNOWN);
} }
if(errors & CERT_TRUST_IS_REVOKED) { 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)) if(!(conn->security_flags & SECURITY_FLAG_IGNORE_REVOCATION))
err = ERROR_INTERNET_SEC_CERT_REVOKED; err = ERROR_INTERNET_SEC_CERT_REVOKED;
errors &= ~CERT_TRUST_IS_REVOKED; errors &= ~CERT_TRUST_IS_REVOKED;
} }
if(errors & CERT_TRUST_IS_NOT_VALID_FOR_USAGE) { 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)) if(!(conn->security_flags & SECURITY_FLAG_IGNORE_WRONG_USAGE))
err = ERROR_INTERNET_SEC_INVALID_CERT; err = ERROR_INTERNET_SEC_INVALID_CERT;
errors &= ~CERT_TRUST_IS_NOT_VALID_FOR_USAGE; 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(ret) {
if(policyStatus.dwError == CERT_E_CN_NO_MATCH) { 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; err = ERROR_INTERNET_SEC_CERT_CN_INVALID;
}else if(policyStatus.dwError) { }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; err = ERROR_INTERNET_SEC_INVALID_CERT;
} }
}else { }else {
@ -328,9 +336,10 @@ static DWORD netconn_verify_cert(netconn_t *conn, PCCERT_CONTEXT cert, HCERTSTOR
if(err) { if(err) {
WARN("failed %u\n", 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 == ERROR_INTERNET_INVALID_CA ? ERROR_INTERNET_SEC_CERT_REV_FAILED : ERROR_INTERNET_SEC_CERT_ERRORS;
}
return err; 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_STRENGTH_WEAK;
connection->security_flags |= SECURITY_FLAG_SECURE; 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; return ERROR_SUCCESS;
fail: fail:

View File

@ -2929,12 +2929,63 @@ static void test_security_flags(void)
ok(req != NULL, "HttpOpenRequest failed\n"); ok(req != NULL, "HttpOpenRequest failed\n");
CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED); 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; 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)); res = InternetSetOption(req, INTERNET_OPTION_ERROR_MASK, (void*)&flags, sizeof(flags));
ok(res, "InternetQueryOption(INTERNET_OPTION_ERROR_MASK failed: %u\n", GetLastError()); 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_CONNECTING_TO_SERVER);
SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER); SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION); 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), ok(req_error == ERROR_INTERNET_SEC_CERT_REV_FAILED || broken(req_error == ERROR_INTERNET_SEC_CERT_ERRORS),
"req_error = %d\n", req_error); "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_CONNECTING_TO_SERVER);
CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER); CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION); 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) { if(req_error != ERROR_INTERNET_SEC_CERT_REV_FAILED) {
win_skip("Unexpected cert errors, skipping security flags tests\n"); win_skip("Unexpected cert errors, skipping security flags tests\n");
close_async_handle(ses, hCompleteEvent, 2); close_async_handle(ses, hCompleteEvent, 3);
CloseHandle(hCompleteEvent); CloseHandle(hCompleteEvent);
return; return;
} }
@ -3013,7 +3062,7 @@ static void test_security_flags(void)
ok(res, "InternetReadFile failed: %u\n", GetLastError()); ok(res, "InternetReadFile failed: %u\n", GetLastError());
ok(size, "size = 0\n"); ok(size, "size = 0\n");
close_async_handle(ses, hCompleteEvent, 2); close_async_handle(ses, hCompleteEvent, 3);
/* Collect all existing persistent connections */ /* Collect all existing persistent connections */
res = InternetSetOptionA(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0); res = InternetSetOptionA(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);