📄 certlist.c
字号:
certType[clAllMine] = 0x00000001; certType[clEmailRecipient] = 0x00000010; certType[clSSLServer] = 0x00000100; certType[clAllCA] = 0x00001000; certType[clEmailSigner] = 0x00010000; /* Check for parameter validity */ PR_ASSERT(cx); PR_ASSERT(cx->m_request); PR_ASSERT(cx->m_params); PR_ASSERT(cx->m_result); if (!cx || !cx->m_request || !cx->m_params || !cx->m_result) { rv = (SSMStatus) PR_INVALID_ARGUMENT_ERROR; goto real_loser; /* really bail here */ } state.cx = cx; state.fmt = NULL; state.efmt = NULL; state.datefmt = NULL; state.output = NULL; state.temp = NULL; state.db = cx->m_request->ctrlconn->m_certdb; if (!state.db) { SSM_HTTPReportSpecificError(state.cx->m_request, "_certlist: no cert db available"); goto user_loser; } if (SSM_Count(cx->m_params) != CERTLIST_PARAM_COUNT) { SSM_HTTPReportSpecificError(cx->m_request, "_certList: " "Incorrect number of parameters " "(%d supplied, %d needed).\n", SSM_Count(cx->m_params), CERTLIST_PARAM_COUNT); goto user_loser; } /* Convert parameters to something we can use in finding certs. */ rv = certlist_get_key_type(&state); if (rv != SSM_SUCCESS) goto user_loser; rv = certlist_get_usage(&state); if (rv != SSM_SUCCESS) goto user_loser; prefix = (char *) SSM_At(cx->m_params, CERTLIST_PARAM_PREFIX); suffix = (char *) SSM_At(cx->m_params, CERTLIST_PARAM_SUFFIX); PR_ASSERT(prefix); /* already did user check, so bomb here if null */ PR_ASSERT(suffix); /* check where we're called from */ target = SSMTextGen_GetTargetObject(cx); if (!target) goto real_loser; /* SecurityAdvisor context keeps hash around, otherwise create new one */ if (SSM_IsAKindOf(target, SSM_RESTYPE_SECADVISOR_CONTEXT)) { targetType = SSM_RESTYPE_SECADVISOR_CONTEXT; state.hash = &((SSMSecurityAdvisorContext *)target)->m_certhash; } else *state.hash = NULL; state.output = state.temp = NULL; /* Start with the prefix. */ rv = SSM_GetAndExpandTextKeyedByString(cx, prefix, &tempUStr); if (rv != SSM_SUCCESS) goto real_loser; /* error string set by the called function */ SSM_DebugUTF8String("Certlist prefix", tempUStr); rv = SSM_ConcatenateUTF8String(&cx->m_result, tempUStr); PR_Free(tempUStr); tempUStr = NULL; if (rv != SSM_SUCCESS) { goto real_loser; } /* initialize a hash if haven't already */ if ((*state.hash == NULL) || (SSM_IsAKindOf(target, SSM_RESTYPE_SECADVISOR_CONTEXT)) && (((SSMSecurityAdvisorContext *)target)->m_certsIncluded & certType[state.usage]) == 0) { ((SSMSecurityAdvisorContext *)target)->m_certsIncluded |= certType[state.usage]; rv = ssm_populate_key_hash(&state); if (rv != SSM_SUCCESS) goto user_loser; } /* Already have all certs info, output in a list in state.result */ SSMSortedList_Enumerate(*state.hash, certlist_display_cert, &state); if (state.output) { rv = SSM_ConcatenateUTF8String(&cx->m_result, state.output); /* Finally, add the suffix. */ rv = SSM_GetAndExpandTextKeyedByString(cx, suffix, &tempUStr); if (rv != SSM_SUCCESS) goto real_loser; /* error string set by the called function */ SSM_DebugUTF8String("certlist suffix", tempUStr); rv = SSM_ConcatenateUTF8String(&cx->m_result, tempUStr); if (rv != SSM_SUCCESS) { goto real_loser; } } else /* no certs found */ { char * tmpStr = NULL; /* release prefix */ PR_FREEIF(state.output); state.output = NULL; rv = SSM_GetAndExpandTextKeyedByString(cx, "list_empty", &tmpStr); if (rv != SSM_SUCCESS) SSM_DEBUG("SSM_CertListKeywordHandler: could not get filler for empty cert list!\n"); PR_FREEIF(cx->m_result); cx->m_result = NULL; rv = SSM_ConcatenateUTF8String(&cx->m_result, tmpStr); PR_FREEIF(tmpStr); tmpStr = NULL; } goto done;user_loser: /* If we reach this point, something in the input is wrong, but we can still send something back to the client to indicate that a problem has occurred. */ /* If we can't do what we're about to do, really bail. */ if (!cx->m_request || !cx->m_request->errormsg) goto real_loser; /* Clear the string we were accumulating. */ SSMTextGen_UTF8StringClear(&cx->m_result); rv = SSM_ConcatenateUTF8String(&cx->m_result, cx->m_request->errormsg); /* Clear the result string, since we're sending this inline */ SSMTextGen_UTF8StringClear(&cx->m_request->errormsg); goto done;real_loser: /* If we reach this point, then it is so bad that we cannot send anything vaguely normal back to the client. Bail. */ if (rv == SSM_SUCCESS) rv = SSM_FAILURE;done: if (targetType && targetType != SSM_RESTYPE_SECADVISOR_CONTEXT) if (*state.hash) SSMSortedList_Destroy(*state.hash); PR_FREEIF(state.fmt); PR_FREEIF(state.efmt); PR_FREEIF(state.output); PR_FREEIF(state.temp); if (state.datefmt) /* REMOVED CALL */; PR_FREEIF(tempUStr); return rv;}static int ssm_CertsOnSmartcards(SSMControlConnection* ctrl, char* name){ CERTCertList* list = NULL; int numCerts = 0; list = PK11_FindCertsFromNickname(name, (void*)ctrl); if (list == NULL) { return 0; } numCerts = SSM_CertListCount(list); CERT_DestroyCertList(list); return numCerts;}static PRBool ssm_OtherCertsByNicknameOrEmailAddr(SSMControlConnection* ctrl, char* name){ int numCerts = 0; /* first get the number of certs under the nickname */ numCerts = CERT_NumPermCertsForNickname(ctrl->m_certdb, name); if (numCerts == 0) { /* we may not see the cert because it's on external token: check it */ numCerts = ssm_CertsOnSmartcards(ctrl, name); } if (numCerts > 1) { /* note that the cert in question is still in the DB: it is just * marked for deletion, but not deleted yet */ return PR_TRUE; } else if (numCerts == 1) { /* it is the only cert */ return PR_FALSE; } else { /* nickname may be email address: try the email address */ CERTCertList* list = NULL; CERTCertListNode* node = NULL; int count = 0; list = CERT_CreateEmailAddrCertList(list, ctrl->m_certdb, name, PR_Now(), PR_FALSE); if (list == NULL) { /* this usually shouldn't happen */ return PR_FALSE; } count = SSM_CertListCount(list); if (list != NULL) { CERT_DestroyCertList(list); } if (count > 1) { return PR_TRUE; } else { return PR_FALSE; } }}SSMStatus SSM_ChangeCertSecAdvisorList(HTTPRequest * req, char * nickname, ssmCertHashAction action){ SSMStatus rv = SSM_SUCCESS; SSMControlConnection * ctrl = req->ctrlconn; CERTCertificate * dbCert = NULL; PRIntn i; SSMSecurityAdvisorContext * advisor = NULL; SSMResourceID resID; char * tmp; SSMSortedList * hash; PR_ASSERT(ctrl && SSM_IsAKindOf((SSMResource *)ctrl, SSM_RESTYPE_CONTROL_CONNECTION)); if (!ctrl->m_secAdvisorList || !ctrl->m_secAdvisorList->len) goto done; if (action == certHashRemove) /* check if need to delete */ { PR_ASSERT(nickname); /* find out if there are other certs under the same nickname than * the one marked for deletion */ if (ssm_OtherCertsByNicknameOrEmailAddr(ctrl, nickname)) { goto done; } } /* there might be multiple Security Advisor up */ for (i=0; i<ctrl->m_secAdvisorList->len; i++){ resID = ctrl->m_secAdvisorList->data[i]; rv = (SSMStatus) SSMControlConnection_GetResource(ctrl, resID, (SSMResource **)&advisor); if (rv != SSM_SUCCESS) continue; PR_ASSERT(advisor && SSM_IsAKindOf((SSMResource *)advisor, SSM_RESTYPE_SECADVISOR_CONTEXT)); if (!advisor->m_certhash) continue; hash = advisor->m_certhash; if (action == certHashRemove) SSMSortedList_Remove(hash, nickname, (void **)&tmp); else if (action == certHashAdd) { ssmCLState state; char * form; SSMTextGenContext *cx; state.key = clNick; state.hash = &advisor->m_certhash; state.db = ctrl->m_certdb; /* this assumes we're called from Restore certificate or * or some other place that includes form name in HTTP request */ rv = SSM_HTTPParamValue(req, "formName", &form); if (strstr(form, "mine")) state.usage = clAllMine; else if (strstr(form, "others")) state.usage = clEmailRecipient; else if (strstr(form, "websites")) state.usage = clSSLServer; else if (strstr(form, "authorities")) state.usage = clAllCA; rv = SSMTextGen_NewTopLevelContext(req, &cx); if (rv != SSM_SUCCESS) { SSM_DEBUG("ChangeCertSecAdvisorList: can't get TextGenContext\n"); goto done; } state.cx = cx; rv = ssm_populate_key_hash(&state); if (rv != SSM_SUCCESS) SSM_DEBUG("ChangeCertSecAdvisorList: error reading certs\n"); SSMTextGen_DestroyContext(cx); } else SSM_DEBUG("ChangeCertSecAdvisorList: bad change request %d\n", action); SSM_FreeResource((SSMResource *)advisor); advisor = NULL; }done: if (dbCert) CERT_DestroyCertificate(dbCert); return rv;}#if 0SSMStatusSSM_ReloadTextCommandHandler(HTTPRequest *req){ SSMStatus rv = SSM_SUCCESS; /* REMOVED CALL */ SSM_HTTPReportError(req, HTTP_NO_CONTENT); goto done; loser: if (rv == SSM_SUCCESS) rv = SSM_FAILURE; done: return rv;}/* Set Locale command handler */SSMStatusSSM_SetLocaleCommandHandler(HTTPRequest *req){ SSMStatus rv = SSM_SUCCESS; char lang[8], country[8], *locale_ch; char name[256], *type_ch = NULL, *baseRef = NULL; SSMTextGenContext *cx = NULL; /* Get the "locale" parameter. Should be the name of a locale, e.g. "en_US", "en_RN". */ rv = SSM_HTTPParamValue(req, "locale", &locale_ch); if (rv != SSM_SUCCESS) { req->httprv = HTTP_BAD_REQUEST; goto loser; } /* Break down the locale string into language and country. */ PR_ASSERT(strlen(locale_ch) >= 5); strncpy(lang, locale_ch, 2); strncpy(country, &(locale_ch[3]), 2); lang[2] = country[2] = '\0'; SSM_DEBUG("New language: %s / New country: %s\n", lang, country); /* REMOVED CALL */; /* if there's a baseRef, send it back. otherwise, no content. */ rv = SSM_HTTPParamValue(req, "baseRef", &baseRef); if (rv == SSM_SUCCESS) { /* send what was requested */ rv = SSM_HTTPDefaultCommandHandler(req); } else { rv = SSM_SUCCESS; SSM_HTTPReportError(req, HTTP_NO_CONTENT); } goto done; loser: if (rv == SSM_SUCCESS) rv = SSM_FAILURE; done: return rv;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -