pkcs11ui.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:26k
- /* -*- Mode: C; tab-width: 4; 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 "pkcs11ui.h"
- #include "pkcs11.h"
- #include "pk11func.h"
- #include "plstr.h"
- #include "secmod.h"
- #include "secmodti.h"
- #include "minihttp.h"
- #include "textgen.h"
- /* Utility */
- PK11SlotInfo *
- SSMPKCS11_FindSlotByID(SECMODModuleID modID,
- CK_SLOT_ID slotID)
- {
- SECMODModule *mod = NULL;
- PRIntn i;
- mod = SECMOD_FindModuleByID(modID);
- if (mod)
- {
- for(i=0;i<mod->slotCount;i++)
- {
- if (mod->slots[i]->slotID == slotID)
- return mod->slots[i];
- }
- }
- return NULL;
- }
- /*
- ---------------------------------------------------------
- PKCS11 module processing (list, add, delete)
- ---------------------------------------------------------
- */
- SSMStatus
- ssmpkcs11_convert_module(SSMTextGenContext *cx,
- PRInt32 modIndex,
- SECMODModule *mod,
- char *fmt)
- {
- char *dllName = NULL;
- char *tempStr = NULL;
- char *lib_ch = NULL;
- CK_INFO modInfo;
- SSMStatus rv = SSM_FAILURE;
- SECStatus srv;
- /* 65? Why 65??? It's what's was used in the original UI. */
- char buf[65];
- char buf2[65];
- srv = PK11_GetModInfo(mod, &modInfo);
- if (srv != SECSuccess)
- goto loser;
- /* we provide the space in (buf), so we don't deallocate lib_ch */
- lib_ch = PK11_MakeString(NULL,buf2,(char *)modInfo.libraryDescription,
- sizeof(modInfo.libraryDescription));
- if (mod->dllName)
- {
- char *cursor, *newString;
- int numSlashes = 0, newLen, i, j, oldLen;
- dllName = mod->dllName;
- /*
- * Now we need to escape the '' characters so the string shows
- * up correctly in the UI.
- */
- /* First count them to see if we even need to re-allocate*/
- cursor = dllName;
- while ((cursor = PL_strchr(cursor, '\')) != NULL) {
- numSlashes++;
- cursor++;
- }
- if (numSlashes > 0) {
- oldLen = PL_strlen(dllName);
- newLen = oldLen + numSlashes + 1;
- newString = SSM_NEW_ARRAY(char, newLen);
- /*
- * If we can't allocate a new buffer, then let's just display
- * the original string. That's better than not displaying
- * anything.
- */
- if (newString != NULL) {
- for (i=0, j=0; i<oldLen+1; i++,j++){
- newString[j] = dllName[i];
- if (newString[j] == '\'){
- newString[j+1] = '\';
- j++;
- }
- }
- dllName = newString;
- }
- }
- }
- else
- {
- rv = SSM_GetAndExpandText(cx, "text_pk11_no_dll", &dllName);
- if (rv != SSM_SUCCESS)
- goto loser;
- }
- PR_snprintf(buf, sizeof(buf), "%d.%d",
- modInfo.libraryVersion.major, modInfo.libraryVersion.minor);
- tempStr = PR_smprintf(fmt, modIndex, (long)mod->moduleID, lib_ch,
- mod->commonName, dllName, buf);
- if (tempStr == NULL) {
- rv = SSM_FAILURE;
- goto loser;
- }
- rv = SSM_ConcatenateUTF8String(&cx->m_result, tempStr);
- loser:
- if (dllName && dllName != mod->dllName)
- PR_Free(dllName);
- PR_FREEIF (tempStr);
- return rv;
- }
- /*
- PKCS11 module list keyword handler.
- Syntax: {_pk11modules <wrapper_key>}
- */
- SSMStatus
- SSM_PKCS11ModulesKeywordHandler(SSMTextGenContext *cx)
- {
- SSMStatus rv = SSM_SUCCESS;
- char *wrapperKey = NULL;
- char *wrapperStr = NULL;
- SECMODModuleList *modList = SECMOD_GetDefaultModuleList();
- SECMODModuleList *modWalk = NULL;
- SECMODListLock *modLock = SECMOD_GetDefaultModuleListLock();
- PRBool gotLock = PR_FALSE; /* indicates whether we should release at end */
- PRInt32 i=0;
- /* 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 = PR_INVALID_ARGUMENT_ERROR;
- goto real_loser; /* really bail here */
- }
- if (SSM_Count(cx->m_params) != 1)
- {
- SSM_HTTPReportSpecificError(cx->m_request, "_certList: "
- "Incorrect number of parameters "
- "(%d supplied, 1 needed).n",
- SSM_Count(cx->m_params));
- goto user_loser;
- }
- /* Convert parameters to something we can use in finding certs. */
- wrapperKey = (char *) SSM_At(cx->m_params, 0);
- PR_ASSERT(wrapperKey);
- /* Get the wrapper text. */
- rv = SSM_GetAndExpandTextKeyedByString(cx, wrapperKey, &wrapperStr);
- if (rv != SSM_SUCCESS)
- goto real_loser; /* error string set by the called function */
- /* Iterate over the PKCS11 modules. Put relevant info from each
- into its own copy of the wrapper text. */
- SECMOD_GetReadLock(modLock);
- gotLock = PR_TRUE;
- modWalk = modList;
- while (modWalk)
- {
- rv = ssmpkcs11_convert_module(cx, i++, modWalk->module, wrapperStr);
- modWalk = modWalk->next;
- }
- 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);
- /* Use the result string given to us to explain what happened. */
- 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 we are so screwed that we cannot
- send anything vaguely normal back to the client. Bail. */
- if (rv == SSM_SUCCESS) rv = SSM_FAILURE;
- done:
- PR_FREEIF(wrapperStr);
- if (modLock && gotLock)
- SECMOD_ReleaseReadLock(modLock);
- return rv;
- }
- /*
- ---------------------------------------------------------
- PKCS11 slot code
- ---------------------------------------------------------
- */
- enum
- {
- SSM_PK11STR_SLOT_LOGGED_IN = (long) 0,
- SSM_PK11STR_SLOT_NOT_LOGGED_IN,
- SSM_PK11STR_SLOT_NO_LOGIN_REQUIRED,
- SSM_PK11STR_SLOT_NOT_PRESENT,
- SSM_PK11STR_SLOT_UNINITIALIZED,
- SSM_PK11STR_SLOT_DISABLED,
- SSM_PK11STR_SLOT_READY,
- SSM_PK11STR_SLOT_STRING_COUNT
- };
- static char *slotStringKeys[] =
- {
- "text_pk11_slot_logged_in",
- "text_pk11_slot_not_logged_in",
- "text_pk11_slot_no_login_required",
- "text_pk11_slot_not_present",
- "text_pk11_slot_uninitialized",
- "text_pk11_slot_disabled",
- "text_pk11_slot_ready"
- };
- static char **slotStrings = NULL;
- void
- ssmpkcs11_initialize_slot_labels(SSMTextGenContext *cx)
- {
- SSMStatus rv = SSM_SUCCESS;
- PRIntn i;
- slotStrings = (char **) PR_Calloc(SSM_PK11STR_SLOT_STRING_COUNT + 1,
- sizeof(char**));
- PR_ASSERT(slotStrings);
- for(i=0;i<SSM_PK11STR_SLOT_STRING_COUNT;i++)
- {
- rv = SSM_FindUTF8StringInBundles(cx, slotStringKeys[i],
- &slotStrings[i]);
- PR_ASSERT(rv == SSM_SUCCESS);
- }
- }
- SSMStatus
- ssmpkcs11_convert_slot(SSMTextGenContext *cx,
- PRInt32 slotIndex,
- PK11SlotInfo *slot,
- char *fmt,
- PRBool accumulate) /* accumulate in cx->m_result? */
- {
- char *name = NULL;
- char *statusStr = NULL;
- char *serial = NULL;
- char *version = NULL;
- char *tempStr = NULL;
- long status, slotID = 0, moduleID = 0;
- CK_TOKEN_INFO tokenInfo;
- SSMStatus rv = SSM_FAILURE;
- SECStatus srv = SECSuccess;
- /* 65? Why 65??? It's what's was used in the original UI. */
- char buf[65];
- char empty[1] = { ' ' } ;
- if (!slotStrings)
- ssmpkcs11_initialize_slot_labels(cx);
- /* If we have a NULL slot, return blank information. */
- if (!slot)
- {
- name = empty;
- statusStr = empty;
- serial = empty;
- version = empty;
- slotID = 0;
- goto show_stuff;
- }
- /* Get the slot name. Either the default name or the name of the token
- in the slot will be used. */
- if (PK11_IsPresent(slot))
- name = PK11_GetTokenName(slot);
- else
- name = PK11_GetSlotName(slot);
- /* Report the status of the slot. */
- if (PK11_IsDisabled(slot))
- status = SSM_PK11STR_SLOT_DISABLED;
- else if (!PK11_IsPresent(slot))
- status = SSM_PK11STR_SLOT_NOT_PRESENT;
- else if (PK11_NeedLogin(slot) && PK11_NeedUserInit(slot))
- status = SSM_PK11STR_SLOT_UNINITIALIZED;
- else if (PK11_NeedLogin(slot) && !PK11_IsLoggedIn(slot, NULL))
- status = SSM_PK11STR_SLOT_NOT_LOGGED_IN;
- else if (PK11_NeedLogin(slot))
- status = SSM_PK11STR_SLOT_LOGGED_IN;
- else
- status = SSM_PK11STR_SLOT_READY;
- statusStr = slotStrings[status];
- /* Get the serial number and version. */
- /* This is how the old UI determines if there's a token in, so... */
- if (PK11_IsPresent(slot))
- srv = PK11_GetTokenInfo(slot, &tokenInfo);
-
- if (PK11_IsPresent(slot) && (srv == SECSuccess))
- {
- /* Get serial number and version from the token info. */
- serial = PK11_MakeString(NULL, NULL, (char*)tokenInfo.serialNumber,
- sizeof(tokenInfo.serialNumber));
- PR_snprintf(buf, sizeof(buf), "%d.%d",
- tokenInfo.firmwareVersion.major,
- tokenInfo.firmwareVersion.minor);
- version = buf;
- }
- else
- {
- /* Get serial number and version from the slot info. */
- CK_SLOT_INFO slotInfo;
- srv = PK11_GetSlotInfo(slot, &slotInfo);
- if (srv != SECSuccess)
- goto loser;
- serial = empty;
- PR_snprintf(buf, sizeof(buf), "%d.%d",
- slotInfo.firmwareVersion.major,
- slotInfo.firmwareVersion.minor);
- version = buf;
- }
- slotID = (long) (slot->slotID);
- moduleID = (long) (slot->module->moduleID);
- show_stuff:
- tempStr = PR_smprintf(fmt, slotIndex, slotID, moduleID, name,
- statusStr, serial, version);
- if (accumulate)
- {
- rv = SSM_ConcatenateUTF8String(&cx->m_result, tempStr);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- }
- else
- rv = SSM_HTTPSendUTF8String(cx->m_request, tempStr);
- loser:
- /* The data that isn't freed is either because it's a member of the
- * data in a structure of the PK11 libraries or its a static local
- * variable.
- */
- if (serial && serial != empty)
- PR_Free(serial);
- PR_FREEIF(tempStr);
- return rv;
- }
- /*
- PKCS11 slot list keyword handler.
- Syntax: {_pk11slots <moduleID>,<wrapper_key>}
- */
- SSMStatus
- SSM_PKCS11SlotsKeywordHandler(SSMTextGenContext *cx)
- {
- SSMStatus rv = SSM_SUCCESS;
- SECMODModule *module = NULL;
- char *wrapperKey = NULL;
- char *moduleIDStr = NULL;
- long moduleID;
- char *wrapperStr = NULL;
- PRInt32 i=0;
- /* 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 = PR_INVALID_ARGUMENT_ERROR;
- goto real_loser; /* really bail here */
- }
- if (SSM_Count(cx->m_params) != 2)
- {
- SSM_HTTPReportSpecificError(cx->m_request, "_certList: "
- "Incorrect number of parameters "
- "(%d supplied, 2 needed).n",
- SSM_Count(cx->m_params));
- goto user_loser;
- }
- /* Convert parameters to something we can use in finding certs. */
- moduleIDStr = (char *) SSM_At(cx->m_params, 0);
- PR_ASSERT(moduleIDStr);
- wrapperKey = (char *) SSM_At(cx->m_params, 1);
- PR_ASSERT(wrapperKey);
- /* Find the module we're looking for based on the module ID. */
- module = SECMOD_FindModuleByID((SECMODModuleID) moduleID);
- if (!module)
- goto user_loser;
- /* Get the wrapper text. */
- rv = SSM_GetAndExpandTextKeyedByString(cx, wrapperKey, &wrapperStr);
- if (rv != SSM_SUCCESS)
- goto real_loser; /* error string set by the called function */
- /* Iterate over the slots from this module. Put relevant info from each
- into its own copy of the wrapper text. */
- for(i=0;i<module->slotCount;i++)
- {
- rv = ssmpkcs11_convert_slot(cx, i, module->slots[i], wrapperStr,
- PR_TRUE);
- if (rv != SSM_SUCCESS)
- goto user_loser;
- }
- 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);
- /* Use the result string given to us to explain what happened. */
- 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 we are so screwed that we cannot
- send anything vaguely normal back to the client. Bail. */
- if (rv == SSM_SUCCESS) rv = SSM_FAILURE;
- done:
- PR_FREEIF(wrapperStr);
- if (module)
- SECMOD_DestroyModule(module);
- return rv;
- }
- SSMStatus
- ssm_pkcs11_chuck_property(SSMTextGenContext *cx, char *propName)
- {
- char *text = NULL;
- SSMStatus rv;
- rv = SSM_GetAndExpandText(cx, propName, &text);
- if (rv != SSM_SUCCESS)
- goto loser;
- rv = SSM_HTTPSendUTF8String(cx->m_request, text);
-
- loser:
- PR_FREEIF(text);
- SSMTextGen_UTF8StringClear(&cx->m_result);
- return rv;
- }
- /* PKCS11ShowSlots?module=<moduleID> */
- SSMStatus
- SSM_ShowSlotsCommandHandler(HTTPRequest *req)
- {
- SSMTextGenContext *cx = NULL;
- char *tmpl = NULL, *type = NULL;
- char *nomod_ch = NULL;
- char *modID_ch = NULL;
- long moduleID;
- SECMODModule *module = NULL;
- PRIntn i;
- SSMStatus rv;
- /* If we have a "no_module" parameter, then there
- is no module for which to load slots. */
- rv = SSM_HTTPParamValue(req, "no_module", &nomod_ch);
- if (rv == SSM_SUCCESS)
- goto display_stuff;
- rv = SSM_HTTPParamValue(req, "module", &modID_ch);
- if (rv != SSM_SUCCESS)
- goto display_stuff;
- if (modID_ch)
- {
- /* Convert the module ID into a real module ID. */
- PR_sscanf(modID_ch, "%ld", &moduleID);
-
- /* Find the module we're looking for based on the module ID. */
- module = SECMOD_FindModuleByID((SECMODModuleID) moduleID);
- if (!module)
- goto loser;
- }
- display_stuff:
- /* Make a new top-level text gen context to chuck text back. */
- rv = SSMTextGen_NewTopLevelContext(req, &cx);
- if (rv != SSM_SUCCESS)
- goto loser;
- rv = SSM_GetAndExpandText(cx, "adv_modules_slotlist_type", &type);
- if (rv != SSM_SUCCESS)
- goto loser;
- rv = SSM_HTTPSendOKHeader(req, NULL, type);
- if (rv != SSM_SUCCESS)
- goto loser;
- /* Chuck out part 1. */
- rv = ssm_pkcs11_chuck_property(cx, "adv_modules_slotlist_part1");
- if (rv != SSM_SUCCESS)
- goto loser;
- /* Get the template for the JS slot list. */
- rv = SSM_GetAndExpandText(cx, "adv_modules_slotlist_js_template", &tmpl);
- if (rv != SSM_SUCCESS)
- goto loser;
- /* Iterate over the slots from this module. Put relevant info from each
- into its own copy of the wrapper text. */
- if (module)
- {
- for(i=0;i<module->slotCount;i++)
- {
- rv = ssmpkcs11_convert_slot(cx, i, module->slots[i], tmpl,
- PR_FALSE);
- if (rv != SSM_SUCCESS)
- goto loser;
- }
- }
- PR_Free(tmpl);
- tmpl = NULL;
-
- /* Chuck out part 2. */
- rv = ssm_pkcs11_chuck_property(cx, "adv_modules_slotlist_part2");
- if (rv != SSM_SUCCESS)
- goto loser;
- /* Get the template for the selectable slot list. */
- rv = SSM_GetAndExpandText(cx, "adv_modules_slotlist_select_template", &tmpl);
- if (rv != SSM_SUCCESS)
- goto loser;
- /* Iterate over the slots from this module. Put relevant info from each
- into its own copy of the wrapper text. */
- if (module)
- {
- for(i=0;i<module->slotCount;i++)
- {
- rv = ssmpkcs11_convert_slot(cx, i, module->slots[i], tmpl,
- PR_FALSE);
- if (rv != SSM_SUCCESS)
- goto loser;
- }
- }
- /* Chuck out part 3. */
- rv = ssm_pkcs11_chuck_property(cx, "adv_modules_slotlist_part3");
- req->sentResponse = PR_TRUE;
- goto done;
- loser:
- if (rv == SSM_SUCCESS) rv = SSM_FAILURE;
- done:
- if (cx)
- SSMTextGen_DestroyContext(cx);
- PR_FREEIF(tmpl);
- return rv;
- }
- SSMStatus
- ssm_find_module_from_request(HTTPRequest *req, SECMODModule **mod)
- {
- char *modID_ch = NULL;
- PRInt32 moduleID;
- SSMStatus rv;
- rv = SSM_HTTPParamValue(req, "module", &modID_ch);
- if (rv != SSM_SUCCESS)
- goto done;
- if (modID_ch)
- {
- /* Convert the module ID into a real module ID. */
- PR_sscanf(modID_ch, "%ld", &moduleID);
-
- /* Find the module we're looking for based on the module ID. */
- *mod = SECMOD_FindModuleByID((SECMODModuleID) moduleID);
- }
- done:
- if ((!*mod) && (rv == SSM_SUCCESS))
- rv = SSM_FAILURE;
- return rv;
- }
- PK11SlotInfo *
- find_slot_by_ID(SECMODModule *mod, CK_SLOT_ID slotID)
- {
- int i;
- PK11SlotInfo *slot;
- for (i=0; i < mod->slotCount; i++) {
- slot = mod->slots[i];
- if (slot->slotID == (CK_SLOT_ID) slotID)
- return PK11_ReferenceSlot(slot);
- }
- return NULL;
- }
- SSMStatus
- ssm_find_slot_from_request(HTTPRequest *req, PK11SlotInfo **slot)
- {
- char *slotID_ch = NULL;
- PRInt32 slotID;
- SECMODModule *mod;
- SSMStatus rv = SSM_SUCCESS;
- rv = ssm_find_module_from_request(req, &mod);
- if (rv != SSM_SUCCESS)
- goto done;
- rv = SSM_HTTPParamValue(req, "slot", &slotID_ch);
- if (rv != SSM_SUCCESS)
- goto done;
- if (slotID_ch)
- {
- /* Convert the module ID into a real module ID. */
- PR_sscanf(slotID_ch, "%ld", &slotID);
- /* Find the module we're looking for based on the module ID. */
- *slot = find_slot_by_ID(mod, (CK_SLOT_ID) slotID);
- }
- done:
- if ((!*slot) && (rv == SSM_SUCCESS))
- rv = SSM_FAILURE;
- return rv;
- }
- SSMStatus
- ssmpkcs11_show_slot_info(HTTPRequest *req, PK11SlotInfo *slot)
- {
- char *wrapperStr = NULL;
- char *tmpl = NULL;
- char *type = NULL;
- SSMTextGenContext *cx;
- SSMStatus rv;
- /* Make a new top-level text gen context to chuck text back. */
- rv = SSMTextGen_NewTopLevelContext(req, &cx);
- if (rv != SSM_SUCCESS)
- goto loser;
- rv = SSM_GetAndExpandText(cx, "adv_modules_slot_info_type", &type);
- if (rv != SSM_SUCCESS)
- goto loser;
- rv = SSM_HTTPSendOKHeader(req, NULL, type);
- if (rv != SSM_SUCCESS)
- goto loser;
- rv = SSM_GetAndExpandText(cx, "adv_modules_slot_info_content", &wrapperStr);
- if (rv != SSM_SUCCESS)
- goto loser; /* error string set by the called function */
- rv = ssmpkcs11_convert_slot(cx, 0, slot, wrapperStr, PR_FALSE);
- goto done;
- loser:
- if (rv == SSM_SUCCESS) rv = SSM_FAILURE;
- done:
- if (cx)
- SSMTextGen_DestroyContext(cx);
- PR_FREEIF(tmpl);
- PR_FREEIF(type);
- PR_FREEIF(wrapperStr);
- return rv;
- }
- SSMStatus
- SSM_ShowSlotCommandHandler(HTTPRequest *req)
- {
- SSMStatus rv;
- PK11SlotInfo *slot;
- /* Find the slot. */
- rv = ssm_find_slot_from_request(req, &slot);
- if (rv != SSM_SUCCESS)
- goto loser;
- /* Display the slot info. */
- rv = ssmpkcs11_show_slot_info(req, slot);
- req->sentResponse = PR_TRUE;
- loser:
- if (slot)
- PK11_FreeSlot(slot);
- return rv;
- }
- SSMStatus
- SSM_LoginSlotCommandHandler(HTTPRequest *req)
- {
- SSMStatus rv;
- PK11SlotInfo *slot;
- /* Find the slot. */
- rv = ssm_find_slot_from_request(req, &slot);
- if (rv != SSM_SUCCESS)
- goto loser;
- /* Log into the slot. */
- PK11_Authenticate(slot, PR_TRUE, req->ctrlconn);
- /* Display the slot info. */
- rv = ssmpkcs11_show_slot_info(req, slot);
- req->sentResponse = PR_TRUE;
- loser:
- if (slot)
- PK11_FreeSlot(slot);
- return rv;
- }
- SSMStatus
- SSM_LogoutSlotCommandHandler(HTTPRequest *req)
- {
- SSMStatus rv;
- PK11SlotInfo *slot;
- /* Find the slot. */
- rv = ssm_find_slot_from_request(req, &slot);
- if (rv != SSM_SUCCESS)
- goto loser;
- /* Log out of the slot. */
- PK11_Logout(slot);
- /* Display the slot info. */
- rv = ssmpkcs11_show_slot_info(req, slot);
- req->sentResponse = PR_TRUE;
- loser:
- if (slot)
- PK11_FreeSlot(slot);
- return rv;
- }
- SSMStatus
- SSM_LogoutAllSlotsCommandHandler(HTTPRequest *req)
- {
- SSMStatus rv;
- PK11SlotInfo *slot;
- /* Find the slot. */
- rv = ssm_find_slot_from_request(req, &slot);
- /* Not relevant if we find the slot here,
- just remember to display (or not) whatever slot we have */
- if (rv != SSM_SUCCESS)
- slot = NULL;
- /* Log out of all slots. */
- PK11_LogoutAll();
- /* Display the slot info (if any). */
- rv = ssmpkcs11_show_slot_info(req, slot);
- req->sentResponse = PR_TRUE;
- if (slot)
- PK11_FreeSlot(slot);
- return rv;
- }
- /*
- ---------------------------------------------------------
- FIPS mode code
- ---------------------------------------------------------
- */
- /*
- FIPS mode keyword handler.
- Syntax: {_fipsmode <true_text>,<false_text>}
- where <true_text> is displayed if FIPS mode is on, <false_text> otherwise.
- */
- SSMStatus
- SSM_PKCS11FIPSModeKeywordHandler(SSMTextGenContext *cx)
- {
- SSMStatus rv = SSM_SUCCESS;
- char *param = NULL;
- char *tempStr = NULL;
- PR_ASSERT(cx);
- PR_ASSERT(cx->m_params);
- PR_ASSERT(cx->m_result);
- if (!cx || !cx->m_params || !cx->m_result)
- {
- rv = PR_INVALID_ARGUMENT_ERROR;
- goto loser;
- }
-
- /* Figure out if we're in FIPS mode. */
- if (PK11_IsFIPS())
- param = (char *) SSM_At(cx->m_params, 0);
- else
- param = (char *) SSM_At(cx->m_params, 1);
- /* Display the appropriate string. */
- rv = SSMTextGen_SubstituteString(cx, param, &tempStr);
- if (rv != SSM_SUCCESS)
- goto loser; /* error string set by the called function */
- rv = SSM_ConcatenateUTF8String(&cx->m_result, tempStr);
- if (rv == SSM_SUCCESS)
- goto done;
- loser:
- if (rv == SSM_SUCCESS) rv = SSM_FAILURE;
- done:
- PR_FREEIF(tempStr);
- return rv;
- }
- void
- SSM_TrimTrailingWhitespace(char *str)
- {
- char *end = &(str[strlen(str)]);
- char *start = str;
- do
- {
- end--;
- }
- while ((end >= start) &&
- ((*end == ' ') || (*end == ' ')));
- *(++end) = ' ';
- }
- /*
- Command handler to set FIPS mode.
- Syntax: setFIPSMode?fips={on|off}&baseRef=<baseRef>&target=<ctrlconn>
- */
- SSMStatus
- SSM_SetFIPSModeCommandHandler(HTTPRequest *req)
- {
- char *fips_ch = NULL, *baseRef_ch = NULL;
- SECStatus srv = SECSuccess;
- PRBool oldFIPS, newFIPS;
- SSMStatus rv = SSM_SUCCESS;
- rv = SSM_HTTPParamValue(req, "fips", &fips_ch);
- if (rv != SSM_SUCCESS)
- goto loser;
- newFIPS = !PL_strncmp(fips_ch, "on", 2);
- oldFIPS = PK11_IsFIPS();
- if (newFIPS != oldFIPS)
- {
- /*
- Turning FIPS mode on/off requires the exact same operation:
- deleting the built-in PKCS11 module.
-
- ### mwelch We need these calls to differentiate between
- secmod dbs!
- */
- SECMODModule *internal;
- CK_INFO modInfo;
- internal = SECMOD_GetInternalModule();
- if (!internal)
- goto loser;
- srv = PK11_GetModInfo(internal, &modInfo);
- if (srv != SECSuccess)
- goto loser;
- SSM_TrimTrailingWhitespace((char*) modInfo.libraryDescription);
- /* Delete the {FIPS,non-FIPS} internal module, so that
- it will be replaced by the {non-FIPS,FIPS} counterpart. */
- srv = SECMOD_DeleteInternalModule(internal->commonName);
- if (srv != SECSuccess)
- goto loser;
- }
- /* if there's a baseRef, send it back. otherwise, no content. */
- rv = SSM_HTTPParamValue(req, "baseRef", &baseRef_ch);
- if (rv == SSM_SUCCESS)
- {
- /* send what was requested */
- rv = SSM_HTTPCloseAndSleep(req);
- }
- goto done;
- loser:
- if (rv == SSM_SUCCESS) rv = SSM_FAILURE;
- SSM_HTTPReportSpecificError(req, "SetFIPSModeCommandHandler: Error %d "
- "attempting to change FIPS mode.",
- srv != SECSuccess ? srv : rv);
- done:
- return rv;
- }