📄 multitoken.c
字号:
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- *//* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape security libraries. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1994-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include "resource.h"#include "kgenctxt.h"#include "nlsutil.h"#include "base64.h"#include "textgen.h"#include "minihttp.h"#include "connect.h"#include "messages.h"/* lock to wait for UI */typedef struct { PRMonitor * lock; PRBool UIComplete;} SSMTokenUI_Monitor;#define SSM_PARENT_CONN(x) &((x)->m_parent->super)static SSMTokenUI_Monitor UIlock;PK11SlotListElement * PK11_GetNextSafe(PK11SlotList *list, PK11SlotListElement *le, PRBool restart);SSMStatus SSMTokenUI_GetNames(SSMResource * res, PRBool start, char ** name);SSMStatus SSM_SetUserPasswordClient(PK11SlotInfo * slot, SSMKeyGenContext *ct);CK_MECHANISM_TYPESSMKeyGenContext_GenMechToAlgMech(CK_MECHANISM_TYPE mechanism){ CK_MECHANISM_TYPE searchMech; /* We are interested in slots based on the ability to perform a given algorithm, not on their ability to generate keys usable by that algorithm. Therefore, map keygen-specific mechanism tags to tags for the corresponding crypto algorthm. */ switch(mechanism) { case CKM_RSA_PKCS_KEY_PAIR_GEN: searchMech = CKM_RSA_PKCS; break; case CKM_DSA_KEY_PAIR_GEN: searchMech = CKM_DSA; break; case CKM_RC4_KEY_GEN: searchMech = CKM_RC4; break; case CKM_DH_PKCS_KEY_PAIR_GEN: searchMech = CKM_DH_PKCS_DERIVE; /* ### mwelch is this right? */ break; case CKM_DES_KEY_GEN: /* What do we do about DES keygen? Right now, we're just using DES_KEY_GEN to look for tokens, because otherwise we'll have to search the token list three times. */ default: searchMech = mechanism; break; } return searchMech;}SSMStatus SSMKeyGenContext_GetSlot(SSMKeyGenContext * keyctxt, CK_MECHANISM_TYPE mechanism){ SSMStatus rv = SSM_SUCCESS; SSMConnection *parentConn = NULL; PK11SlotList * slotList; CK_MECHANISM_TYPE searchMech; char *pwd; PRBool reLock; searchMech = SSMKeyGenContext_GenMechToAlgMech(mechanism); slotList = PK11_GetAllTokens(searchMech, PR_TRUE, PR_TRUE, keyctxt->super.m_connection); if (!keyctxt) goto loser; if (!slotList || !slotList->head) goto loser; if (!slotList->head->next) { /* only one slot available, just return it */ keyctxt->slot = slotList->head->slot; } else { char * mech = PR_smprintf("mech=%d", searchMech); if (keyctxt->m_ctxtype == SSM_OLD_STYLE_KEYGEN) { CMTItem msg; GenKeyOldStyleTokenRequest request; char ** tokenNames = NULL; int numtokens = 0; PK11SlotListElement * slotElement; slotElement = PK11_GetFirstSafe(slotList); while(slotElement) { numtokens++; tokenNames = (char **) PR_REALLOC(tokenNames, numtokens*sizeof(*tokenNames)); tokenNames[numtokens - 1] = strdup(PK11_GetTokenName(slotElement->slot)); slotElement = PK11_GetNextSafe(slotList, slotElement, PR_FALSE); } /* send message to plugin: use native UI for select token dialog */ SSM_LockUIEvent(&keyctxt->super); request.rid = keyctxt->super.m_id; request.numtokens = numtokens; request.tokenNames = tokenNames; msg.type = SSM_REPLY_OK_MESSAGE | SSM_KEYGEN_TAG | SSM_KEYGEN_TOKEN; if (CMT_EncodeMessage(GenKeyOldStyleTokenRequestTemplate, &msg, &request) != CMTSuccess) goto loser; SSM_SendQMessage(keyctxt->super.m_connection->m_controlOutQ, SSM_PRIORITY_NORMAL, msg.type, msg.len, (char *)msg.data, PR_TRUE); SSM_WaitUIEvent(&keyctxt->super, PR_INTERVAL_NO_TIMEOUT); SSM_UnlockUIEvent(&keyctxt->super); keyctxt->slot = (PK11SlotInfo*)keyctxt->super.m_uiData; } else /* post UI event */ { /* post a UI event to ask user for the slot */ SSM_LockUIEvent(&keyctxt->super); /* Release the lock on the resource temporarily while * the UI happens. */ rv = SSM_UnlockResource(&keyctxt->super); reLock = (rv == PR_SUCCESS) ? PR_TRUE : PR_FALSE; rv = SSMControlConnection_SendUIEvent(keyctxt->super.m_connection, "get", "select_token", (SSMResource *)keyctxt, mech, &((SSMResource*)keyctxt)->m_clientContext); if (rv != SSM_SUCCESS) { if (keyctxt->super.m_UILock != NULL) { PR_ExitMonitor(keyctxt->super.m_UILock); } goto loser; } /* wait until the UI dialog box is done */ SSM_WaitUIEvent(&keyctxt->super, PR_INTERVAL_NO_TIMEOUT); if (reLock) { /* Get the lock back. */ SSM_LockResource(&keyctxt->super); } SSM_UnlockUIEvent(&keyctxt->super); PR_Free(mech); /* ok, the return from UI is processed in command handler */ /* Make sure password prompt doesn't get sucked away by * the disappearing dialog */ PR_Sleep(PR_TicksPerSecond()); keyctxt->slot = (PK11SlotInfo*)keyctxt->super.m_uiData; } /* end of post UI event */ } /* end of multiple tokens available */ /* we should have a slot now */ if (keyctxt->slot == NULL) goto loser; /* Get a slot reference so it doesn't disappear */ keyctxt->slot = PK11_ReferenceSlot(keyctxt->slot); /* Before we authenticate, make sure the user initialized the DB. */ if (PK11_NeedUserInit(keyctxt->slot)) rv = SSM_SetUserPasswordClient(keyctxt->slot, keyctxt); rv = PK11_Authenticate(keyctxt->slot, PR_FALSE, keyctxt); if (rv != SECSuccess) { goto loser; } goto done;loser: if (rv == SSM_SUCCESS) rv = SSM_FAILURE; keyctxt->slot = NULL; done: if (slotList) PK11_FreeSlotList(slotList); return rv;}/* send a message to the client to display UI for setting slot password */SSMStatusSSM_SetUserPasswordClient(PK11SlotInfo * slot, SSMKeyGenContext *ct){ CMTItem msg; GenKeyOldStylePasswordRequest passwdmsg; SSMStatus rv = SSM_FAILURE; PRBool reLock = PR_FALSE; PR_ASSERT(SSM_IsAKindOf(&ct->super, SSM_RESTYPE_KEYGEN_CONTEXT)); switch (ct->m_ctxtype) { case (SSM_CRMF_KEYGEN): rv = SSM_UnlockResource(&ct->super); reLock = (rv == PR_SUCCESS) ? PR_TRUE : PR_FALSE; rv = SSM_SetUserPassword(slot, &ct->super); break; case (SSM_OLD_STYLE_KEYGEN): SSM_LockUIEvent(&ct->super); passwdmsg.rid = ct->super.m_id; passwdmsg.tokenName = PK11_GetTokenName(slot); passwdmsg.internal = (CMBool) PK11_IsInternal(slot); passwdmsg.minpwdlen = PR_MAX(SSM_MIN_PWD_LEN,PK11_GetMinimumPwdLength(slot)); passwdmsg.maxpwdlen = slot->maxPassword; msg.type = SSM_REPLY_OK_MESSAGE | SSM_KEYGEN_TAG | SSM_KEYGEN_PASSWORD; if (CMT_EncodeMessage(GenKeyOldStylePasswordRequestTemplate, &msg, &passwdmsg) != CMTSuccess) goto loser; rv = SSM_SendQMessage(ct->super.m_connection->m_controlOutQ, SSM_PRIORITY_NORMAL, msg.type, msg.len, (char *)msg.data, PR_TRUE); if (rv != SSM_SUCCESS) SSM_UnlockUIEvent(&ct->super); else SSM_WaitUIEvent(&ct->super, PR_INTERVAL_NO_TIMEOUT); break; default: SSM_DEBUG("Unknown keygen type!\n"); goto loser; } loser: if (rv != SSM_SUCCESS) SSM_DEBUG("SetUserPasswordComm: can't send password request msg!\n");done: if (reLock) SSM_LockResource(&ct->super); return rv;}SSMStatusssmpkcs11_convert_slot(SSMTextGenContext *cx, PRInt32 slotIndex, PK11SlotInfo *slot, char *fmt, PRBool accumulate);SSMStatus SSMTokenUI_KeywordHandler(SSMTextGenContext * cx){ SSMResource *ctxt = NULL; SSMStatus rv; char * tempUStr = NULL; char * wrapper = NULL; char * key = NULL; PRBool start = PR_TRUE; CK_MECHANISM_TYPE searchMech; char *searchMechStr; static PK11SlotList * slotList; static PK11SlotListElement * slotElement; PRIntn i = 0; if (!cx || !cx->m_request || !cx->m_params || !cx->m_result) goto loser; ctxt = SSMTextGen_GetTargetObject(cx); /* Get the wrapper string from the properties file. */ wrapper = (char *) SSM_At(cx->m_params, 0); rv = SSM_GetAndExpandTextKeyedByString(cx, wrapper, &tempUStr); if (rv != PR_SUCCESS) goto loser; rv = SSM_HTTPParamValue(cx->m_request, "action", &searchMechStr); if (rv != SSM_SUCCESS) goto loser; searchMech = atoi(searchMechStr); slotList = PK11_GetAllTokens(searchMech, PR_TRUE, PR_TRUE, ctxt->m_connection); if (!slotList) goto loser; slotElement = PK11_GetFirstSafe(slotList); while(slotElement) { rv = ssmpkcs11_convert_slot(cx, i++, slotElement->slot, tempUStr, PR_TRUE); if (rv != SSM_SUCCESS) goto loser; slotElement = PK11_GetNextSafe(slotList, slotElement, PR_FALSE); } rv = SSM_SUCCESS; goto done;loser: SSM_DEBUG("Errors creating token list!\n"); SSMTextGen_UTF8StringClear(&cx->m_result); if (rv==SSM_SUCCESS) rv = SSM_FAILURE;done: PR_FREEIF(tempUStr); return rv;}PK11SlotInfo *SSMPKCS11_FindSlotByID(SECMODModuleID modID, CK_SLOT_ID slotID);SSMStatusfigure_out_token_selection(char *str, SECMODModuleID *modID, CK_SLOT_ID *slotID){ char *walk; walk = PL_strchr(str, '+'); if (!walk) return SSM_FAILURE; *walk++ = '\0'; *modID = atoi(str); *slotID = atoi(walk); return SSM_SUCCESS;}SSMStatus SSMTokenUI_CommandHandler(HTTPRequest * req){ SSMStatus rv; char * buttonValue, * tokenName = NULL; SSMResource *res; SECMODModuleID modID; CK_SLOT_ID slotID; PK11SlotInfo *slot; PRBool locked = PR_FALSE; if (!req->target) goto loser; res = req->target; res->m_uiData = NULL; /* check the parameter values */ if (res->m_buttonType == SSM_BUTTON_CANCEL) { slot = NULL; goto done; /* return the closing javascript */ } /* Determine what token the user selected. */ rv = SSM_HTTPParamValue(req, "token", &tokenName); if (rv != SSM_SUCCESS) { req->httprv = HTTP_BAD_REQUEST; goto loser; } rv = figure_out_token_selection(tokenName, &modID, &slotID); if (rv != SSM_SUCCESS) goto loser; slot = SSMPKCS11_FindSlotByID(modID, slotID); if (!slot) goto loser;done: /* Tell the keygen context what token was selected. */ res->m_uiData = slot; SSM_NotifyUIEvent(res); /* Done with our part, so pass back whatever the dialog wants in order to close the window. */ return SSM_HTTPCloseAndSleep(req);loser: res->m_uiData = NULL; SSM_NotifyUIEvent(res); SSM_DEBUG("Can't get input from token_select dialog!\n"); return SSM_FAILURE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -