📄 dbck.c
字号:
int i, ref; PRCList *elem; certDBEntryListNode *node; certDBEntryMap *map; certDBSubjectEntryMap *smap; certDBEntrySubject *subjectEntry; /* List certs */ for (elem = PR_LIST_HEAD(&dbArray->certs.link); elem != &dbArray->certs.link; elem = PR_NEXT_LINK(elem)) { node = LISTNODE_CAST(elem); map = (certDBEntryMap *)node->appData; dumpCertEntry((certDBEntryCert*)&node->entry, map->index, info->out); /* walk the cert handle to it's subject entry */ if (map_handle_is_ok(info, map->pSubject, -1)) { smap = (certDBSubjectEntryMap *)map->pSubject->appData; ref = smap->index; PR_fprintf(info->out, "-->(subject %d)\n\n\n", ref); } else { PR_fprintf(info->out, "-->(MISSING SUBJECT ENTRY)\n\n\n"); } } /* List subjects */ for (elem = PR_LIST_HEAD(&dbArray->subjects.link); elem != &dbArray->subjects.link; elem = PR_NEXT_LINK(elem)) { node = LISTNODE_CAST(elem); subjectEntry = (certDBEntrySubject *)&node->entry; smap = (certDBSubjectEntryMap *)node->appData; dumpSubjectEntry(subjectEntry, smap->index, info->out); /* iterate over subject's certs */ for (i=0; i<smap->numCerts; i++) { /* walk each subject handle to it's cert entries */ if (map_handle_is_ok(info, smap->pCerts[i], -1)) { ref = ((certDBEntryMap *)smap->pCerts[i]->appData)->index; PR_fprintf(info->out, "-->(%d. certificate %d)\n", i, ref); } else { PR_fprintf(info->out, "-->(%d. MISSING CERT ENTRY)\n", i); } } if (subjectEntry->nickname) { /* walk each subject handle to it's nickname entry */ if (map_handle_is_ok(info, smap->pNickname, -1)) { ref = ((certDBEntryMap *)smap->pNickname->appData)->index; PR_fprintf(info->out, "-->(nickname %d)\n", ref); } else { PR_fprintf(info->out, "-->(MISSING NICKNAME ENTRY)\n"); } } if (subjectEntry->emailAddr) { /* walk each subject handle to it's smime entry */ if (map_handle_is_ok(info, smap->pSMime, -1)) { ref = ((certDBEntryMap *)smap->pSMime->appData)->index; PR_fprintf(info->out, "-->(s/mime %d)\n", ref); } else { PR_fprintf(info->out, "-->(MISSING S/MIME ENTRY)\n"); } } PR_fprintf(info->out, "\n\n"); } for (elem = PR_LIST_HEAD(&dbArray->nicknames.link); elem != &dbArray->nicknames.link; elem = PR_NEXT_LINK(elem)) { node = LISTNODE_CAST(elem); map = (certDBEntryMap *)node->appData; dumpNicknameEntry((certDBEntryNickname*)&node->entry, map->index, info->out); if (map_handle_is_ok(info, map->pSubject, -1)) { ref = ((certDBEntryMap *)map->pSubject->appData)->index; PR_fprintf(info->out, "-->(subject %d)\n\n\n", ref); } else { PR_fprintf(info->out, "-->(MISSING SUBJECT ENTRY)\n\n\n"); } } for (elem = PR_LIST_HEAD(&dbArray->smime.link); elem != &dbArray->smime.link; elem = PR_NEXT_LINK(elem)) { node = LISTNODE_CAST(elem); map = (certDBEntryMap *)node->appData; dumpSMimeEntry((certDBEntrySMime*)&node->entry, map->index, info->out); if (map_handle_is_ok(info, map->pSubject, -1)) { ref = ((certDBEntryMap *)map->pSubject->appData)->index; PR_fprintf(info->out, "-->(subject %d)\n\n\n", ref); } else { PR_fprintf(info->out, "-->(MISSING SUBJECT ENTRY)\n\n\n"); } } PR_fprintf(info->out, "\n\n");}char *errResult[] = { "Certificate entries that had no subject entry.", "Certificate entries that had no key in their subject entry.", "Subject entries that had no nickname or email address.", "Redundant nicknames (subjects with the same nickname).", "Subject entries that had no nickname entry.", "Redundant email addresses (subjects with the same email address).", "Subject entries that had no S/MIME entry.", "Nickname entries that had no subject entry.", "S/MIME entries that had no subject entry.",};intfillDBEntryArray(CERTCertDBHandle *handle, certDBEntryType type, certDBEntryListNode *list){ PRCList *elem; certDBEntryListNode *node; certDBEntryMap *mnode; certDBSubjectEntryMap *smnode; PRArenaPool *arena; int count = 0; /* Initialize a dummy entry in the list. The list head will be the * next element, so this element is skipped by for loops. */ PR_INIT_CLIST((PRCList *)list); /* Collect all of the cert db entries for this type into a list. */ SEC_TraverseDBEntries(handle, type, SEC_GetCertDBEntryList, (PRCList *)list); for (elem = PR_LIST_HEAD(&list->link); elem != &list->link; elem = PR_NEXT_LINK(elem)) { /* Iterate over the entries and ... */ node = (certDBEntryListNode *)elem; if (type != certDBEntryTypeSubject) { arena = PORT_NewArena(sizeof(*mnode)); mnode = (certDBEntryMap *)PORT_ArenaZAlloc(arena, sizeof(*mnode)); mnode->arena = arena; /* ... assign a unique index number to each node, and ... */ mnode->index = count; /* ... set the map pointer for the node. */ node->appData = (void *)mnode; } else { /* allocate some room for the cert pointers also */ arena = PORT_NewArena(sizeof(*smnode) + 20*sizeof(void *)); smnode = (certDBSubjectEntryMap *) PORT_ArenaZAlloc(arena, sizeof(*smnode)); smnode->arena = arena; smnode->index = count; node->appData = (void *)smnode; } count++; } return count;}voidfreeDBEntryList(PRCList *list){ PRCList *next, *elem; certDBEntryListNode *node; certDBEntryMap *map; for (elem = PR_LIST_HEAD(list); elem != list;) { next = PR_NEXT_LINK(elem); node = (certDBEntryListNode *)elem; map = (certDBEntryMap *)node->appData; PR_REMOVE_LINK(&node->link); PORT_FreeArena(map->arena, PR_TRUE); PORT_FreeArena(node->entry.common.arena, PR_TRUE); elem = next; }}voidDBCK_DebugDB(CERTCertDBHandle *handle, PRFileDesc *out, PRFileDesc *mailfile){ int i, nCertsFound, nSubjFound, nErr; int nCerts, nSubjects, nSubjCerts, nNicknames, nSMime; PRCList *elem; char c; dbDebugInfo info; certDBArray dbArray; PORT_Memset(&dbArray, 0, sizeof(dbArray)); PORT_Memset(&info, 0, sizeof(info)); info.verbose = (out == NULL) ? PR_FALSE : PR_TRUE ; info.dograph = (mailfile == NULL) ? PR_FALSE : PR_TRUE ; info.out = (out) ? out : PR_STDOUT; info.graphfile = mailfile; /* Fill the array structure with cert/subject/nickname/smime entries. */ dbArray.numCerts = fillDBEntryArray(handle, certDBEntryTypeCert, &dbArray.certs); dbArray.numSubjects = fillDBEntryArray(handle, certDBEntryTypeSubject, &dbArray.subjects); dbArray.numNicknames = fillDBEntryArray(handle, certDBEntryTypeNickname, &dbArray.nicknames); dbArray.numSMime = fillDBEntryArray(handle, certDBEntryTypeSMimeProfile, &dbArray.smime); /* Compute the map between the database entries. */ mapSubjectEntries(&dbArray); mapCertEntries(&dbArray); computeDBGraph(&dbArray, &info); /* Store the totals for later reference. */ nCerts = dbArray.numCerts; nSubjects = dbArray.numSubjects; nNicknames = dbArray.numNicknames; nSMime = dbArray.numSMime; nSubjCerts = 0; for (elem = PR_LIST_HEAD(&dbArray.subjects.link); elem != &dbArray.subjects.link; elem = PR_NEXT_LINK(elem)) { certDBSubjectEntryMap *smap; smap = (certDBSubjectEntryMap *)LISTNODE_CAST(elem)->appData; nSubjCerts += smap->numCerts; } if (info.verbose) { /* Dump the database contents. */ verboseOutput(&dbArray, &info); } freeDBEntryList(&dbArray.certs.link); freeDBEntryList(&dbArray.subjects.link); freeDBEntryList(&dbArray.nicknames.link); freeDBEntryList(&dbArray.smime.link); PR_fprintf(info.out, "\n"); PR_fprintf(info.out, "Database statistics:\n"); PR_fprintf(info.out, "N0: Found %4d Certificate entries.\n", nCerts); PR_fprintf(info.out, "N1: Found %4d Subject entries (unique DN's).\n", nSubjects); PR_fprintf(info.out, "N2: Found %4d Cert keys within Subject entries.\n", nSubjCerts); PR_fprintf(info.out, "N3: Found %4d Nickname entries.\n", nNicknames); PR_fprintf(info.out, "N4: Found %4d S/MIME entries.\n", nSMime); PR_fprintf(info.out, "\n"); nErr = 0; for (i=0; i<sizeof(errResult)/sizeof(char*); i++) { PR_fprintf(info.out, "E%d: Found %4d %s\n", i, info.dbErrors[i], errResult[i]); nErr += info.dbErrors[i]; } PR_fprintf(info.out, "--------------\n Found %4d errors in database.\n", nErr); PR_fprintf(info.out, "\nCertificates:\n"); PR_fprintf(info.out, "N0 == N2 + E%d + E%d\n", NoSubjectForCert, SubjectHasNoKeyForCert); nCertsFound = nSubjCerts + info.dbErrors[NoSubjectForCert] + info.dbErrors[SubjectHasNoKeyForCert]; c = (nCertsFound == nCerts) ? '=' : '!'; PR_fprintf(info.out, "%d %c= %d + %d + %d\n", nCerts, c, nSubjCerts, info.dbErrors[NoSubjectForCert], info.dbErrors[SubjectHasNoKeyForCert]); PR_fprintf(info.out, "\nSubjects:\n"); PR_fprintf(info.out, "N1 == N3 + N4 + E%d + E%d + E%d + E%d + E%d - E%d - E%d\n", NoNicknameOrSMimeForSubject, WrongNicknameForSubject, NoNicknameEntry, WrongSMimeForSubject, NoSMimeEntry, NoSubjectForNickname, NoSubjectForSMime); PR_fprintf(info.out, " - #(subjects with both nickname and S/MIME entries)\n"); nSubjFound = nNicknames + nSMime + info.dbErrors[NoNicknameOrSMimeForSubject] + info.dbErrors[WrongNicknameForSubject] + info.dbErrors[NoNicknameEntry] + info.dbErrors[WrongSMimeForSubject] + info.dbErrors[NoSMimeEntry] - info.dbErrors[NoSubjectForNickname] - info.dbErrors[NoSubjectForSMime] - info.dbErrors[NicknameAndSMimeEntry]; c = (nSubjFound == nSubjects) ? '=' : '!'; PR_fprintf(info.out, "%d %c= %d + %d + %d + %d + %d + %d + %d - %d - %d - %d\n", nSubjects, c, nNicknames, nSMime, info.dbErrors[NoNicknameOrSMimeForSubject], info.dbErrors[WrongNicknameForSubject], info.dbErrors[NoNicknameEntry], info.dbErrors[WrongSMimeForSubject], info.dbErrors[NoSMimeEntry], info.dbErrors[NoSubjectForNickname], info.dbErrors[NoSubjectForSMime], info.dbErrors[NicknameAndSMimeEntry]); PR_fprintf(info.out, "\n");}#ifdef DORECOVERenum { dbInvalidCert = 0, dbNoSMimeProfile, dbOlderCert, dbBadCertificate, dbCertNotWrittenToDB};typedef struct dbRestoreInfoStr{ CERTCertDBHandle *handle; PRBool verbose; PRFileDesc *out; int nCerts; int nOldCerts; int dbErrors[5]; PRBool removeType[3]; PRBool promptUser[3];} dbRestoreInfo;char *IsEmailCert(CERTCertificate *cert){ char *email, *tmp1, *tmp2; PRBool isCA; int len; if (!cert->subjectName) { return NULL; } tmp1 = PORT_Strstr(cert->subjectName, "E="); tmp2 = PORT_Strstr(cert->subjectName, "MAIL="); /* XXX Nelson has cert for KTrilli which does not have either * of above but is email cert (has cert->emailAddr). */ if (!tmp1 && !tmp2 && !cert->emailAddr) { return NULL; } /* Server or CA cert, not personal email. */ isCA = CERT_IsCACert(cert, NULL); if (isCA) return NULL; /* XXX CERT_IsCACert advertises checking the key usage ext., but doesn't appear to. */ /* Check the key usage extension. */ if (cert->keyUsagePresent) { /* Must at least be able to sign or encrypt (not neccesarily * both if it is one of a dual cert). */ if (!((cert->rawKeyUsage & KU_DIGITAL_SIGNATURE) || (cert->rawKeyUsage & KU_KEY_ENCIPHERMENT))) return NULL; /* CA cert, not personal email. */ if (cert->rawKeyUsage & (KU_KEY_CERT_SIGN | KU_CRL_SIGN)) return NULL; } if (cert->emailAddr) { email = PORT_Strdup(cert->emailAddr); } else { if (tmp1) tmp1 += 2; /* "E=" */ else tmp1 = tmp2 + 5; /* "MAIL=" */ len = strcspn(tmp1, ", "); email = (char*)PORT_Alloc(len+1); PORT_Strncpy(email, tmp1, len); email[len] = '\0'; } return email;}SECStatusdeleteit(CERTCertificate *cert, void *arg){ return SEC_DeletePermCertificate(cert);}/* Different than DeleteCertificate - has the added bonus of removing * all certs with the same DN. */SECStatusdeleteAllEntriesForCert(CERTCertDBHandle *handle, CERTCertificate *cert, PRFileDesc *outfile){#if 0 certDBEntrySubject *subjectEntry; certDBEntryNickname *nicknameEntry; certDBEntrySMime *smimeEntry; int i;#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -