📄 ssldlgs.c
字号:
/* ### sjlee: this is a very ugly way to differentiate among different * buttons */ rv = SSM_HTTPParamValue(req, "do_ok", &tmpStr); if (rv == SSM_SUCCESS) { /* "OK" button was clicked */ rv = ssm_http_client_auth_handle_ok_button(req); goto done; } rv = SSM_HTTPParamValue(req, "do_cancel", &tmpStr); if (rv == SSM_SUCCESS) { /* "Cancel" button was clicked */ rv = ssm_http_client_auth_handle_cancel_button(req); goto done; } rv = SSM_HTTPParamValue(req, "do_help", &tmpStr); if (rv == SSM_SUCCESS) { /* "help" button was clicked */ /* just use cancel handler for now */ rv = ssm_http_client_auth_handle_cancel_button(req); goto done; }loser: if (rv == SSM_SUCCESS) { SSM_DEBUG("Don't know which button was clicked.\n"); rv = SSM_FAILURE; } SSM_LockResource(req->target); conn->m_UIInfo.chosen = -1; conn->m_UIInfo.UICompleted = PR_TRUE; SSM_NotifyResource(req->target); SSM_UnlockResource(req->target);done: /* this actually includes the error cases returned from individual * button handlers */ return rv;}SSMStatus ssm_http_client_auth_handle_ok_button(HTTPRequest* req){ SSMStatus rv; SSMSSLDataConnection* conn; char* chosen = NULL; int i; conn = (SSMSSLDataConnection*)(req->target); SSM_LockResource(req->target); /* retrieve the chosen nickname */ rv = SSM_HTTPParamValue(req, "chosen", &chosen); if (rv != SSM_SUCCESS) { goto loser; } PR_ASSERT(chosen != NULL); PR_sscanf(chosen, "%ld", &i); PR_ASSERT(i >= 0 && i < conn->m_UIInfo.numFilteredCerts); rv = SSM_HTTPCloseAndSleep(req); if (rv != SSM_SUCCESS) { goto loser; } /* set the predicate to true and unblock the SSL thread */ conn->m_UIInfo.chosen = i; conn->m_UIInfo.UICompleted = PR_TRUE; SSM_NotifyResource(req->target); SSM_UnlockResource(req->target); return rv; /* SSM_SUCCESS */loser: /* still we want to unblock the SSL thread: it will see NULL nickname */ conn->m_UIInfo.chosen = -1; conn->m_UIInfo.UICompleted = PR_TRUE; SSM_NotifyResource(req->target); SSM_UnlockResource(req->target); return rv;}SSMStatus ssm_http_client_auth_handle_cancel_button(HTTPRequest* req){ SSMStatus rv; SSMSSLDataConnection* conn; conn = (SSMSSLDataConnection*)(req->target); SSM_LockResource(req->target); /* close the window */ rv = SSM_HTTPCloseAndSleep(req); if (rv != SSM_SUCCESS) { goto loser; }loser: /* set the predicate to true and unblock the SSL thread */ conn->m_UIInfo.chosen = -1; conn->m_UIInfo.UICompleted = PR_TRUE; SSM_NotifyResource(req->target); SSM_UnlockResource(req->target); return rv;}/* * Function: SECStatus SSM_SSLMakeCertExpiredDialog() * Purpose: dispatch the UI event to create the server cert expired * dialog * Arguments and return values * - cert: server cert we are dealing with * - conn: SSL connection object * - returns: SECSuccess if successful *and* the user decides to trust * the cert; appropriate error code otherwise */SECStatus SSM_SSLMakeCertExpiredDialog(CERTCertificate* cert, SSMSSLDataConnection* conn){ SECStatus rv; int64 now; int64 notBefore; int64 notAfter; char* baseRef = NULL; /* compare the time and determine which dialog box to bring up */ now = PR_Now(); rv = CERT_GetCertTimes(cert, ¬Before, ¬After); if (rv != SECSuccess) { return rv; } if (LL_CMP(now, >, notAfter)) { baseRef = PL_strdup("bad_server_cert_expired"); } else { baseRef = PL_strdup("bad_server_cert_not_yet_valid"); } if (baseRef == NULL) { return SECFailure; } SSM_LockResource(SSMRESOURCE(conn)); conn->m_UIInfo.UICompleted = PR_FALSE; conn->m_UIInfo.trustBadServerCert = BSCA_NO; /* fire up the UI */ if (SSMControlConnection_SendUIEvent(SSMCONTROLCONNECTION(conn), "get", baseRef, SSMRESOURCE(conn), NULL,&SSMRESOURCE(conn)->m_clientContext) != SSM_SUCCESS) { rv = SECFailure; goto loser; } /* wait until the UI event is complete */ while (conn->m_UIInfo.UICompleted == PR_FALSE) { SSM_WaitResource(SSMRESOURCE(conn), PR_INTERVAL_NO_TIMEOUT); } if (conn->m_UIInfo.trustBadServerCert == BSCA_NO) { /* user did not want to continue. Cancel here. */ if (rv == SECSuccess) { rv = SECFailure; } goto loser; } /* ### sjlee: warning! accessing cert fields directly */ cert->timeOK = PR_TRUE;#if 0 /* Setting timeOK suffices. Setting trust flags is unnecessary. */ rv = SSM_SSLServerCertResetTrust(cert, conn->m_UIInfo.trustBadServerCert); if (rv != SECSuccess) { goto loser; }#endifloser: conn->m_UIInfo.trustBadServerCert = BSCA_NO; conn->m_UIInfo.UICompleted = PR_FALSE; SSM_UnlockResource(SSMRESOURCE(conn)); if (baseRef != NULL) { PR_Free(baseRef); } return rv;}SECStatus SSM_SSLServerCertResetTrust(CERTCertificate* cert, SSMBadServerCertAccept accept){ char* nickname = NULL; CERTCertTrust trust; CERTCertTrust* trustPtr = NULL; SECStatus rv; if (accept == BSCA_NO) { /* this usually shouldn't happen */ goto loser; } else if (accept == BSCA_PERMANENT) { memset((void*)&trust, 0, sizeof(trust)); /*trust.sslFlags = CERTDB_VALID_PEER | CERTDB_TRUSTED;*/ /* this resets the SSL flags CERTDB_VALID_PEER | CERTDB_TRUSTED */ rv = CERT_DecodeTrustString(&trust, "P"); if (rv != SECSuccess) { goto loser; } /* XXX not neccessary? */ /* if (mystate->postwarn) { trust.sslFlags |= CERTDB_SEND_WARN; rv = CERT_DecodeTrustString(&trust, "w"); } */ nickname = ssm_default_server_nickname(cert); if (nickname == NULL) { goto loser; } /* add a temporary certificate to the permanent database */ rv = CERT_AddTempCertToPerm(cert, nickname, &trust); if (nickname != NULL) { PR_Free(nickname); } if (rv != SECSuccess) { goto loser; } } else if (accept == BSCA_SESSION) { /* bump the ref count on the cert so that it stays around for * the entire session */ /* ### sjlee: warning: accessing fields directly */ cert->keepSession = PR_TRUE; if (cert->trust != NULL) { trustPtr = cert->trust; } else { trustPtr = (CERTCertTrust*)PORT_ArenaZAlloc(cert->arena, sizeof(CERTCertTrust)); cert->trust = trustPtr; } if (trustPtr == NULL) { goto loser; } /* set the trust value */ /*trustptr->sslFlags |= (CERTDB_VALID_PEER | CERTDB_TRUSTED);*/ /* reset the trust SSL bit to CERTDB_VALID_PEER | CERTDB_TRUSTED */ rv = CERT_DecodeTrustString(trustPtr, "P"); if (rv != SECSuccess) { goto loser; } /* if (mystate->postwarn) { trustptr->sslFlags |= CERTDB_SEND_WARN; rv = CERT_DecodeTrustString(trustptr, "w"); } */ } return rv;loser: if (rv == SECSuccess) { rv = SECFailure; } return rv;}/* This is also called in oldfunc.c when creating default nickname for * a new certificate. */void _ssm_compress_spaces(char* psrc){ char* pdst; char c; PRBool lastspace = PR_FALSE; if (psrc == NULL) { return; } pdst = psrc; while (((c = *psrc) != 0) && isspace(c)) { psrc++; /* swallow leading spaces */ } while ((c = *psrc++) != 0) { if (isspace(c)) { if (!lastspace) { *pdst++ = ' '; } lastspace = PR_TRUE; } else { *pdst++ = c; lastspace = PR_FALSE; } } *pdst = '\0'; /* if the last character is a space, then remove it too */ pdst--; c = *pdst; if (isspace(c)) { *pdst = '\0'; } return;}/* * Function: char* ssm_default_server_nickname() * Purpose: creates a default nickname for a bad server cert in case the * user wanted to continue * Arguments and return values * - cert: cert in question * - returns: the composed nickname; NULL if failure */static char* ssm_default_server_nickname(CERTCertificate* cert){ char* nickname = NULL; int count; PRBool conflict; char* servername = NULL; servername = CERT_GetCommonName(&cert->subject); if (servername == NULL) { goto loser; } count = 1; while (1) { if (count == 1) { nickname = PR_smprintf("%s", servername); } else { nickname = PR_smprintf("%s #%d", servername, count); } if (nickname == NULL) { goto loser; } _ssm_compress_spaces(nickname); conflict = SEC_CertNicknameConflict(nickname, &cert->derSubject, cert->dbhandle); if (conflict == PR_SUCCESS) { goto done; } /* free the nickname */ PORT_Free(nickname); count++; } loser: if (nickname != NULL) { PR_Free(nickname); nickname = NULL; }done: if (servername != NULL) { PR_Free(servername); } return nickname;}SSMStatus SSM_CurrentTimeKeywordHandler(SSMTextGenContext* cx){ SSMStatus rv; char* wrapper = NULL; char* key = NULL; char* utf8Now = NULL; int64 now; const PRIntn TIME_WRAPPER = (PRIntn)0; /* we have one keyword */ /* check arguments */ /* ### sjlee: might as well make this a helper function because most * keyword handlers will use this checking */ PR_ASSERT(cx != NULL); /* PR_ASSERT(cx->m_request != NULL);*/ PR_ASSERT(cx->m_params != NULL); PR_ASSERT(cx->m_result != NULL); if (cx == NULL || cx->m_params == NULL || cx->m_result == NULL) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); goto loser; } /* REMOVED CALL */;}/* this function handles the button clicks for all server auth failure dialogs * except the unknown issuers case */SSMStatus SSM_ServerAuthFailureButtonHandler(HTTPRequest* req){ SSMStatus rv; SSMResource* res; SSMSSLDataConnection* conn; res = (SSMResource*)(req->target); conn = (SSMSSLDataConnection*)(req->target); if (res->m_buttonType == SSM_BUTTON_OK) { /* "OK" button was clicked */ rv = ssm_http_server_auth_handle_ok_button(req); goto done; } else if (res->m_buttonType == SSM_BUTTON_CANCEL) { /* "Cancel" button was clicked */ rv = ssm_http_server_auth_handle_cancel_button(req); goto done; } else { SSM_DEBUG("Don't know which button was clicked.\n"); rv = SSM_FAILURE; } SSM_LockResource(res); conn->m_UIInfo.UICompleted = PR_TRUE; /* the default course of action if something goes wrong is not to trust */ conn->m_UIInfo.trustBadServerCert = BSCA_NO; SSM_NotifyResource(res); SSM_UnlockResource(res);done: /* this actually includes the error cases returned from individual * button handlers */ return rv;}SSMStatus ssm_http_server_auth_handle_ok_button(HTTPRequest* req){ SSMStatus rv; SSMSSLDataConnection* conn; char* accept = NULL; conn = (SSMSSLDataConnection*)(req->target); SSM_LockResource(req->target); /* if the user wanted to go ahead, accept="session" */ rv = SSM_HTTPParamValue(req, "accept", &accept); if (rv != SSM_SUCCESS) { /* either the user did not want to continue or something went wrong */ conn->m_UIInfo.trustBadServerCert = BSCA_NO; goto loser; } PR_ASSERT(accept != NULL); if (PL_strcmp(accept, "session") == 0) { conn->m_UIInfo.trustBadServerCert = BSCA_SESSION; } else if (PL_strcmp(accept, "permanent") == 0) { conn->m_UIInfo.trustBadServerCert = BSCA_PERMANENT; } else { /* either something went wrong or the user did not want to continue */ conn->m_UIInfo.trustBadServerCert = BSCA_NO; }loser: /* close the window */ rv = SSM_HTTPCloseAndSleep(req); /* set the predicate to true and unblock the SSL thread */ conn->m_UIInfo.UICompleted = PR_TRUE; SSM_NotifyResource(req->target); SSM_UnlockResource(req->target); return rv;}SSMStatus ssm_http_server_auth_handle_cancel_button(HTTPRequest* req){ SSMStatus rv; SSMSSLDataConnection* conn; conn = (SSMSSLDataConnection*)(req->target);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -