advisor.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:102k
- /* -*- 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.
- */
- #ifdef XP_MAC
- #include "platform.h"
- #endif
- #include "advisor.h"
- #include "nlsutil.h"
- #include "minihttp.h"
- #include "p12res.h"
- #include "textgen.h"
- #include "sslskst.h"
- #include "certlist.h"
- #include "ocsp.h"
- #include "secoid.h"
- #include "prefs.h"
- #include "messages.h"
- #include "secerr.h"
- #include "sslerr.h"
- #include "base64.h"
- /*
- * This is the structure used to gather all of the CA's that can be used
- * for OCSP responders.
- */
- typedef struct SSMDefaultOCSPRespondersListStr{
- SSMSortedList *respondersWithAIA;
- SSMSortedList *respondersWithoutAIA;
- SSMTextGenContext *cx;
- char *wrapper, *defaultSigner;
- } SSMDefaultOCSPRespondersList;
- SSMStatus SSM_SetSelectedItemInfo(SSMSecurityAdvisorContext* cx);
- #define SSMRESOURCE(object) (&object->super)
- #define SSM_NO_INFO "sa_no_info"
- #define SSM_NAVIGATOR_NO_SEC "sa_navigator_no_sec"
- #define SSM_NAVIGATOR_SSL "sa_navigator_ssl"
- #define SSM_NAVIGATOR_BAD_SSL "sa_navigator_bad_ssl"
- #define SSM_MESSAGE "sa_message"
- #define SSM_MESSAGE_NOT_SIGNED "sa_message_not_signed"
- #define SSM_MESSAGE_NOT_ENCRYPTED "sa_message_not_encrypted"
- #define SSM_MESSAGE_SIGNED "sa_message_signed"
- #define SSM_MESSAGE_ENCRYPTED "sa_message_encrypted"
- #define SSM_MESSAGE_BAD_SIGNED "sa_message_bad_signed"
- #define SSM_MESSAGE_BAD_ENCRYPTED "sa_message_bad_encrypted"
- /* A list of User agent strings that we know can do S/MIME
- * and want the Java tab as well.
- */
- #define COMMON_TO_SMIME_AND_JAVA "Mozilla/4.7"
- const char *kSMimeApps[] = {COMMON_TO_SMIME_AND_JAVA, NULL};
- const char *kJavaJSApps[] = {COMMON_TO_SMIME_AND_JAVA, NULL};
- char * SSM_ConvertStringToHTMLString(char * string);
- char * SSMUI_GetPKCS12Error(PRIntn error, PRBool isBackup);
- PRBool
- SSM_IsCRLPresent(SSMControlConnection *ctrl)
- {
- SECStatus rv = SECFailure;
- CERTCrlHeadNode *head = NULL;
- PRBool retVal = PR_FALSE;
-
- rv = SEC_LookupCrls(ctrl->m_certdb, &head, -1);
- if (rv != SECSuccess) {
- goto done;
- }
- if (head == NULL) {
- goto done;
- }
- retVal = (head->first == NULL) ? PR_FALSE : PR_TRUE;
- PORT_FreeArena(head->arena, PR_FALSE);
- done:
- return retVal;
- }
- SSMStatus
- SSMSecurityAdvisorContext_Create(SSMControlConnection *ctrl,
- InfoSecAdvisor *info,
- SSMResource **res)
- {
- SSMStatus rv = PR_SUCCESS;
- SSMSecurityAdvisorContext *ct;
- int i;
- *res = NULL; /* in case we fail */
-
- ct = (SSMSecurityAdvisorContext *)
- PR_CALLOC(sizeof(SSMSecurityAdvisorContext));
- if (!ct)
- goto loser;
- rv = SSMResource_Init(ctrl, &ct->super, SSM_RESTYPE_SECADVISOR_CONTEXT);
- if (rv != PR_SUCCESS)
- goto loser;
-
- /* this hash will contail list of formatted certs nickname to display */
- ct->m_certhash = NULL;
- ct->m_certsIncluded = 0;
-
- /* register us with ControlConection */
- if (!ctrl->m_secAdvisorList) {
- ctrl->m_secAdvisorList = (SECItem *) PR_Malloc(sizeof(SECItem));
- ctrl->m_secAdvisorList->len = 0;
- ctrl->m_secAdvisorList->data = NULL;
- }
- ctrl->m_secAdvisorList->len++;
- ctrl->m_secAdvisorList->data = (unsigned char *) PR_REALLOC(ctrl->m_secAdvisorList->data,
- ctrl->m_secAdvisorList->len);
- ctrl->m_secAdvisorList->data[ ctrl->m_secAdvisorList->len - 1 ] =
- ((SSMResource *)ct)->m_id;
- if (info) {
- ct->infoContext = info->infoContext;
- ct->resID = info->resID;
- ct->hostname = info->hostname ? PL_strdup(info->hostname) : NULL;
- ct->senderAddr = info->senderAddr ? PL_strdup(info->senderAddr) : NULL;
- ct->encryptedP7CInfo = info->encryptedP7CInfo;
- ct->signedP7CInfo = info->signedP7CInfo;
- ct->decodeError = info->decodeError;
- ct->verifyError = info->verifyError;
- ct->encryptthis = info->encryptthis;
- ct->signthis = info->signthis;
- ct->numRecipients = info->numRecipients;
- if (info->numRecipients > 0) {
- ct->recipients = (char **) PR_CALLOC(sizeof(char*)*(info->numRecipients));
- if (!ct->recipients) {
- goto loser;
- }
- for (i=0;i<info->numRecipients;i++) {
- ct->recipients[i] = PL_strdup(info->recipients[i]);
- }
- }
- SSM_SetSelectedItemInfo(ct);
- }
- /* Create a URL for the security advisor window. */
- rv = (SSMStatus) SSM_GenerateURL(ctrl, "get", "secadvisor",
- &ct->super, NULL,
- &ct->m_width, &ct->m_height,
- &ct->m_url);
- if (rv != SSM_SUCCESS)
- goto loser;
- SSMSecurityAdvisorContext_Invariant(ct);
- *res = &ct->super;
- return PR_SUCCESS;
- loser:
- if (rv == PR_SUCCESS) rv = PR_FAILURE;
- if (ct)
- {
- ct->super.m_refCount = 1; /* force destroy */
- SSM_FreeResource(&ct->super);
- }
-
- return rv;
- }
- char * SSMUI_GetPKCS12Error(PRIntn error, PRBool isBackup)
- {
- char * responseKey;
-
- switch (error) {
- case SSM_ERR_NO_PASSWORD:
- responseKey = "pkcs12_bad_portable_password_restore";
- break;
- case SSM_ERR_BAD_DB_PASSWORD:
- responseKey = "pkcs12_bad_db_password";
- break;
- case SSM_ERR_BAD_FILENAME:
- responseKey = "pkcs12_bad_filepath";
- break;
- case SSM_ERR_NEED_USER_INIT_DB:
- responseKey = "pkcs12_need_db_init";
- break;
- case SSM_ERR_CANNOT_DECODE:
- responseKey="pkcs12_cannot_decode";
- break;
- case SSM_PKCS12_CERT_ALREADY_EXISTS:
- responseKey="pkcs12_cert_already_exists";
- break;
- case SSM_ERR_BAD_REQUEST:
- default:
- responseKey = (isBackup) ? "pkcs12_backup_failure" :
- "pkcs12_restore_failure";
- }
- return responseKey;
- }
- SSMStatus
- SSMSecurityAdvisorContext_Destroy(SSMResource *res, PRBool doFree)
- {
- SSMSecurityAdvisorContext *ct = (SSMSecurityAdvisorContext *) res;
- PRIntn i = 0, others = 0;
- if (ct)
- {
- PR_ASSERT(SSM_IsAKindOf(res, SSM_RESTYPE_SECADVISOR_CONTEXT));
- SSMResource_Destroy(res, PR_FALSE);
-
- /* Dereference the security info object */
- if (ct->m_infoSource)
- {
- SSM_FreeResource(ct->m_infoSource);
- ct->m_infoSource = NULL;
- }
- /* Free the URL */
- PR_FREEIF(ct->m_url);
- if (ct->m_certhash)
- SSMSortedList_Destroy(ct->m_certhash);
-
- /* deregister with control connection */
- while (i < res->m_connection->m_secAdvisorList->len) {
- if (res->m_connection->m_secAdvisorList->data[i] == res->m_id)
- res->m_connection->m_secAdvisorList->data[i] = 0;
- if (res->m_connection->m_secAdvisorList->data[i])
- others ++;
- i++;
- }
- if (!others) {
- SECITEM_ZfreeItem(res->m_connection->m_secAdvisorList, PR_TRUE);
- res->m_connection->m_secAdvisorList = NULL;
- }
- if (ct->socketStatus) {
- SSM_FreeResource(&ct->socketStatus->super);
- }
- PR_FREEIF(ct->hostname);
- PR_FREEIF(ct->senderAddr);
- if (ct->recipients) {
- for (i=0; i<ct->numRecipients; i++) {
- PR_FREEIF(ct->recipients[i]);
- }
- PR_FREEIF(ct->recipients);
- }
- /* Free if asked */
- if (doFree)
- PR_Free(ct);
- }
- return PR_SUCCESS; /* no way to fail, really */
- }
- void
- SSMSecurityAdvisorContext_Invariant(SSMSecurityAdvisorContext *ct)
- {
- /* Check superclass. */
- SSMResource_Invariant(&ct->super);
- /* Make sure we always have a URL. */
- PR_ASSERT(ct->m_url != NULL);
- }
- SSMStatus
- SSMSecurityAdvisorContext_GetAttrIDs(SSMResource *res,
- SSMAttributeID **ids,
- PRIntn *count)
- {
- SSMStatus rv;
- rv = SSMResource_GetAttrIDs(res, ids, count);
- if (rv != PR_SUCCESS)
- goto loser;
- *ids = (SSMAttributeID *) PR_REALLOC(*ids, (*count + 4) * sizeof(SSMAttributeID));
- if (! *ids) goto loser;
- (*ids)[*count++] = SSM_FID_SECADVISOR_URL;
- (*ids)[*count++] = SSM_FID_SECADVISOR_WIDTH;
- (*ids)[*count++] = SSM_FID_SECADVISOR_HEIGHT;
- (*ids)[*count++] = SSM_FID_CLIENT_CONTEXT;
- goto done;
- loser:
- if (rv == PR_SUCCESS) rv = PR_FAILURE;
- done:
- return rv;
- }
- SSMStatus
- SSMSecurityAdvisorContext_GetAttr(SSMResource *res,
- SSMAttributeID attrID,
- SSMResourceAttrType attrType,
- SSMAttributeValue *value)
- {
- SSMStatus rv = PR_SUCCESS;
- SSMSecurityAdvisorContext *ct = (SSMSecurityAdvisorContext *) res;
- SSMSecurityAdvisorContext_Invariant(ct);
- switch(attrID)
- {
- case SSM_FID_SECADVISOR_URL:
- /* Duplicate and return the string. */
- value->type = SSM_STRING_ATTRIBUTE;
- value->u.string.len = PL_strlen(ct->m_url);
- value->u.string.data = (unsigned char *) PL_strdup(ct->m_url);
- break;
- case SSM_FID_SECADVISOR_WIDTH:
- case SSM_FID_SECADVISOR_HEIGHT:
- value->type = SSM_NUMERIC_ATTRIBUTE;
- value->u.numeric = (attrID == SSM_FID_SECADVISOR_WIDTH) ?
- ct->m_width : ct->m_height;
- break;
- case SSM_FID_CLIENT_CONTEXT:
- SSM_DEBUG("Getting security advisor client context");
- value->type = SSM_STRING_ATTRIBUTE;
- if (!(value->u.string.data = (unsigned char *) PR_Malloc(res->m_clientContext.len))) {
- goto loser;
- }
- memcpy(value->u.string.data, res->m_clientContext.data, res->m_clientContext.len);
- value->u.string.len = res->m_clientContext.len;
- break;
- default:
- rv = SSMResource_GetAttr(res,attrID,attrType,value);
- if (rv != PR_SUCCESS)
- goto loser;
- }
- goto done;
- loser:
- value->type = SSM_NO_ATTRIBUTE;
- if (rv == PR_SUCCESS)
- rv = PR_FAILURE;
- done:
- return rv;
- }
- SSMStatus SSMSecurityAdvisorContext_SetAttr(SSMResource *res,
- SSMAttributeID attrID,
- SSMAttributeValue *value)
- {
- switch(attrID) {
- case SSM_FID_CLIENT_CONTEXT:
- SSM_DEBUG("Setting security advisor client contextn");
- if (value->type != SSM_STRING_ATTRIBUTE) {
- goto loser;
- }
- if (!(res->m_clientContext.data = (unsigned char *) PR_Malloc(value->u.string.len))) {
- goto loser;
- }
- memcpy(res->m_clientContext.data, value->u.string.data, value->u.string.len);
- res->m_clientContext.len = value->u.string.len;
- break;
- default:
- SSM_DEBUG("Got unknown security advisor Set Attribute Request %dn", attrID);
- goto loser;
- break;
- }
- return PR_SUCCESS;
- loser:
- return PR_FAILURE;
- }
- /* Preference keys used in Security Advisor JavaScript.
- * They are used to cache temporary changes the user has made.
- */
- #define SSL2_SPK "enable_ssl2"
- #define SSL3_SPK "enable_ssl3"
- #define CLIENT_AUTH_SPK "client_auth_auto_select"
- #define EMAIL_CERT_SPK "default_email_cert"
- #define WARN_ENTER_SECURE_SPK "warn_entering_secure"
- #define WARN_LEAVE_SECURE_SPK "warn_leaving_secure"
- #define WARN_VIEW_MIXED_SPK "warn_viewing_mixed"
- #define WARN_SUBMIT_INSECURE_SPK "warn_submit_insecure"
- #define ENCRYPT_MAIL_SPK "mail_encrypt_outgoing_mail"
- #define SIGN_MAIL_SPK "mail_crypto_sign_outgoing_mail"
- #define SIGN_NEWS_SPK "mail_crypto_sign_outgoing_news"
- /* maximum number of pref items that will be sent back to the client */
- #define ITEMS_MAX 11
- static SSMStatus SSMSecurityAdvisor_get_bool_value(HTTPRequest* req,
- char* key, PRBool* value)
- {
- SSMStatus rv;
- char* tmpStr = NULL;
- rv = SSM_HTTPParamValue(req, key, &tmpStr);
- if (rv != SSM_SUCCESS) {
- return rv;
- }
- if (PL_strcmp(tmpStr, "true") == 0) {
- *value = PR_TRUE;
- }
- else if (PL_strcmp(tmpStr, "false") == 0) {
- *value = PR_FALSE;
- }
- else {
- SSM_DEBUG("I don't understand the value.n");
- return SSM_FAILURE;
- }
- return rv;
- }
- static SSMStatus ssm_set_pack_bool_pref(PrefSet* prefs, char* key,
- PRBool value, SetPrefElement* list,
- PRIntn* n)
- {
- SSMStatus rv;
- /* set the change to memory */
- rv = PREF_SetBoolPref(prefs, key, value);
- if (rv != PR_SUCCESS) {
- return rv;
- }
- /* pack the change */
- list[*n].key = PL_strdup(key);
- list[*n].type = BOOL_PREF;
- if (value == PR_TRUE) {
- list[*n].value = PL_strdup("true");
- }
- else {
- list[*n].value = PL_strdup("false");
- }
- (*n)++;
- return rv;
- }
- static SSMStatus
- SSMSecurityAdvisorContext_SavePrefs(SSMSecurityAdvisorContext* cx,
- HTTPRequest* req)
- {
- SSMStatus rv;
- SSMControlConnection* ctrl = NULL;
- PrefSet* prefs = NULL;
- PRBool ssl2on;
- PRBool ssl3on;
- PRBool autoSelect;
- PRBool warnEnterSecure;
- PRBool warnLeaveSecure;
- PRBool warnViewMixed;
- PRBool warnSubmitInsecure;
- PRBool encryptMail;
- PRBool signMail;
- PRBool signNews;
- char* autoStr = NULL;
- char* defaultCert = NULL;
- SetPrefElement list[ITEMS_MAX];
- SetPrefListMessage request;
- PRIntn n = 0; /* counter */
- int i;
- CMTItem message;
- PR_ASSERT(cx != NULL && cx->super.m_connection != NULL &&
- cx->super.m_connection->m_prefs != NULL);
- ctrl = cx->super.m_connection;
- prefs = ctrl->m_prefs;
- /* retrieve pref values */
- rv = SSMSecurityAdvisor_get_bool_value(req, SSL2_SPK, &ssl2on);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- rv = SSMSecurityAdvisor_get_bool_value(req, SSL3_SPK, &ssl3on);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- rv = SSMSecurityAdvisor_get_bool_value(req, CLIENT_AUTH_SPK, &autoSelect);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- if (autoSelect == PR_TRUE) {
- autoStr = "Select Automatically";
- }
- else {
- autoStr = "Ask Every Time";
- }
- rv = SSM_HTTPParamValue(req, EMAIL_CERT_SPK, &defaultCert);
- if (defaultCert[0] == ' ') {
- defaultCert = NULL;
- rv = SSM_SUCCESS;
- }
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- rv = SSMSecurityAdvisor_get_bool_value(req, WARN_ENTER_SECURE_SPK,
- &warnEnterSecure);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- rv = SSMSecurityAdvisor_get_bool_value(req, WARN_LEAVE_SECURE_SPK,
- &warnLeaveSecure);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- rv = SSMSecurityAdvisor_get_bool_value(req, WARN_VIEW_MIXED_SPK,
- &warnViewMixed);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- rv = SSMSecurityAdvisor_get_bool_value(req, WARN_SUBMIT_INSECURE_SPK,
- &warnSubmitInsecure);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- rv = SSMSecurityAdvisor_get_bool_value(req, ENCRYPT_MAIL_SPK,
- &encryptMail);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- rv = SSMSecurityAdvisor_get_bool_value(req, SIGN_MAIL_SPK, &signMail);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- rv = SSMSecurityAdvisor_get_bool_value(req, SIGN_NEWS_SPK, &signNews);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- /* commit the changes */
- if (PREF_BoolPrefChanged(prefs, "security.enable_ssl2", ssl2on)) {
- /* value has changed */
- rv = ssm_set_pack_bool_pref(prefs, "security.enable_ssl2", ssl2on,
- (SetPrefElement*)list, &n);
- SSL_EnableDefault(SSL_ENABLE_SSL2, ssl2on);
- }
- if (PREF_BoolPrefChanged(prefs, "security.enable_ssl3", ssl3on)) {
- rv = ssm_set_pack_bool_pref(prefs, "security.enable_ssl3", ssl3on,
- (SetPrefElement*)list, &n);
- SSL_EnableDefault(SSL_ENABLE_SSL3, ssl3on);
- }
- if (PREF_StringPrefChanged(prefs, "security.default_personal_cert",
- autoStr)) {
- rv = PREF_SetStringPref(prefs, "security.default_personal_cert",
- autoStr);
-
- list[n].key = PL_strdup("security.default_personal_cert");
- list[n].type = STRING_PREF;
- list[n].value = PL_strdup(autoStr);
- n++;
- }
-
- if (PREF_StringPrefChanged(prefs, "security.default_mail_cert",
- defaultCert)) {
- rv = PREF_SetStringPref(prefs, "security.default_mail_cert",
- defaultCert);
- list[n].key = PL_strdup("security.default_mail_cert");
- list[n].type = STRING_PREF;
- list[n].value = PL_strdup(defaultCert);
- n++;
- }
- if (PREF_BoolPrefChanged(prefs, "security.warn_entering_secure",
- warnEnterSecure)) {
- rv = ssm_set_pack_bool_pref(prefs, "security.warn_entering_secure",
- warnEnterSecure, (SetPrefElement*)list,
- &n);
- }
- if (PREF_BoolPrefChanged(prefs, "security.warn_leaving_secure",
- warnLeaveSecure)) {
- rv = ssm_set_pack_bool_pref(prefs, "security.warn_leaving_secure",
- warnLeaveSecure, (SetPrefElement*)list,
- &n);
- }
- if (PREF_BoolPrefChanged(prefs, "security.warn_viewing_mixed",
- warnViewMixed)) {
- rv = ssm_set_pack_bool_pref(prefs, "security.warn_viewing_mixed",
- warnViewMixed, (SetPrefElement*)list, &n);
- }
- if (PREF_BoolPrefChanged(prefs, "security.warn_submit_insecure",
- warnSubmitInsecure)) {
- rv = ssm_set_pack_bool_pref(prefs, "security.warn_submit_insecure",
- warnSubmitInsecure, (SetPrefElement*)list,
- &n);
- }
- if (PREF_BoolPrefChanged(prefs, "mail.encrypt_outgoing_mail",
- encryptMail)) {
- rv = ssm_set_pack_bool_pref(prefs, "mail.encrypt_outgoing_mail",
- encryptMail, (SetPrefElement*)list, &n);
- }
- if (PREF_BoolPrefChanged(prefs, "mail.crypto_sign_outgoing_mail",
- signMail)) {
- rv = ssm_set_pack_bool_pref(prefs, "mail.crypto_sign_outgoing_mail",
- signMail, (SetPrefElement*)list, &n);
- }
- if (PREF_BoolPrefChanged(prefs, "mail.crypto_sign_outgoing_news",
- signNews)) {
- rv = ssm_set_pack_bool_pref(prefs, "mail.crypto_sign_outgoing_news",
- signNews, (SetPrefElement*)list, &n);
- }
- rv = SSM_HTTPDefaultCommandHandler(req);
- if (rv != PR_SUCCESS) {
- goto loser;
- }
- /* finally, send the changes to the plugin so that it can save the
- * changes
- */
- if (n > 0) {
- /* we need to send this event only if prefs changed */
- request.length = n;
- request.list = list;
- message.type = SSM_EVENT_MESSAGE | SSM_SAVE_PREF_EVENT;
- if (CMT_EncodeMessage(SetPrefListMessageTemplate, &message,
- &request) != CMTSuccess) {
- goto loser;
- }
- /* send the message through the control out queue */
- SSM_SendQMessage(ctrl->m_controlOutQ, SSM_PRIORITY_NORMAL,
- message.type, message.len, (char*)message.data,
- PR_TRUE);
- }
- loser:
- /* clean out list */
- for (i = 0; i < n; i++) {
- if (list[i].key != NULL) {
- PR_Free(list[i].key);
- }
- if (list[i].value != NULL) {
- PR_Free(list[i].value);
- }
- }
- return rv;
- }
- SSMStatus
- SSMSecurityAdvisorContext_DoPKCS12Response(SSMSecurityAdvisorContext *advisor,
- HTTPRequest *req,
- const char *responseKey)
- {
- SSMTextGenContext *cx = NULL;
- SSMStatus rv = SSM_FAILURE;
- char name[256];
- char *page = "pkcs12_action_followup";
- char *type = NULL, *hdrs = NULL, *content = NULL;
- char *alertMessage = NULL, *out = NULL;
- rv = SSMTextGen_NewTopLevelContext(req, &cx);
- if (rv != SSM_SUCCESS) {
- SSM_HTTPReportSpecificError(req, "DoPKCS12Response: Error%d "
- "attempting to create textgen context.",
- rv);
- goto loser;
- }
- PR_snprintf(name, 256, "%s_type", page);
- rv = SSM_GetUTF8Text(cx, name, &type);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- PR_snprintf(name, 256, "%s_content", page);
- rv = SSM_GetAndExpandText(cx, name, &content);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- rv = SSM_GetUTF8Text(cx, responseKey, &alertMessage);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- out = PR_smprintf(content, alertMessage, advisor->super.m_id);
- rv = SSM_HTTPSendOKHeader(req, hdrs, type);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- rv = SSM_HTTPSendUTF8String(req, out);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- req->sentResponse = PR_TRUE;
- goto done;
- loser:
- if (rv == SSM_SUCCESS) rv = SSM_FAILURE;
- done:
- if (cx != NULL) {
- SSMTextGen_DestroyContext(cx);
- }
- PR_FREEIF(type);
- PR_FREEIF(hdrs);
- PR_FREEIF(content);
- PR_FREEIF(out);
- PR_FREEIF(alertMessage);
- return rv;
- }
- static SSMStatus
- SSMSecurityAdvisorContext_DoNewDefMailReponse(SSMPKCS12Context *p12Cxt,
- HTTPRequest *req)
- {
- SSMTextGenContext *cx = NULL;
- char *fmt=NULL, *content=NULL, *defEmailCert=NULL, *expContent=NULL;
- SSMStatus rv;
- rv = SSMTextGen_NewTopLevelContext(req, &cx);
- if (rv != SSM_SUCCESS) {
- SSM_HTTPReportSpecificError(req, "DoNewDefMailReponse: Failed to "
- "create new TextGenContext.");
- goto loser;
- }
- rv = SSM_FindUTF8StringInBundles(cx, "pkcs12_restore_success_new_mail",
- &fmt);
- if (rv != SSM_SUCCESS || fmt == NULL) {
- goto loser;
- }
-
- rv = PREF_GetStringPref(req->ctrlconn->m_prefs,
- "security.default_mail_cert", &defEmailCert);
- if (rv != SSM_SUCCESS || defEmailCert == NULL) {
- goto loser;
- }
- content = PR_smprintf(fmt, defEmailCert);
- if (content == NULL) {
- goto loser;
- }
- rv = SSMTextGen_SubstituteString(cx, content, &expContent);
- if (rv != SSM_SUCCESS || expContent == NULL) {
- goto loser;
- }
- rv = SSM_HTTPSendOKHeader(req, "", "text/html");
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- rv = SSM_HTTPSendUTF8String(req, expContent);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- PR_Free(expContent);
- PR_Free(content);
- PR_Free(fmt);
- req->sentResponse = PR_TRUE;
- return SSM_SUCCESS;
- loser:
- if (cx != NULL) {
- SSMTextGen_DestroyContext(cx);
- }
- PR_FREEIF(fmt);
- PR_FREEIF(content);
- PR_FREEIF(expContent);
- return SSM_FAILURE;
- }
- SSMStatus SSMSecurityAdvisorContext_DoPKCS12Restore(
- SSMSecurityAdvisorContext *res,
- HTTPRequest *req)
- {
- SSMStatus rv;
- SSMPKCS12CreateArg p12Create;
- SSMPKCS12Context *p12Cxt=NULL;
- SSMResourceID rid;
- const char *responseKey;
- p12Create.isExportContext = PR_FALSE;
- rv = (SSMStatus) SSM_CreateResource(SSM_RESTYPE_PKCS12_CONTEXT,
- (void*)&p12Create,
- SSMRESOURCE(res)->m_connection,
- &rid, (SSMResource **)(&p12Cxt));
- if (rv != PR_SUCCESS) {
- goto done;
- }
- /* pass along Advisor's client context for window management */
- /* pass along Advisor's client context for window management */
- SSM_CopyCMTItem(&((SSMResource *)p12Cxt)->m_clientContext,
- &((SSMResource *)res)->m_clientContext);
-
- rv = SSMPKCS12Context_RestoreCertFromPKCS12File(p12Cxt);
- if (rv == SSM_ERR_NEW_DEF_MAIL_CERT) {
- SSM_ChangeCertSecAdvisorList(req, NULL, certHashAdd);
- rv = SSMSecurityAdvisorContext_DoNewDefMailReponse(p12Cxt,req);
- } else {
- if (p12Cxt->super.m_buttonType == SSM_BUTTON_CANCEL){
- rv = SSM_SUCCESS;
- SSM_HTTPReportError(req, HTTP_NO_CONTENT);
- } else if (rv != SSM_SUCCESS) {
- responseKey = SSMUI_GetPKCS12Error(rv, PR_FALSE);
- } else {
- responseKey = "pkcs12_restore_success";
- SSM_ChangeCertSecAdvisorList(req, NULL, certHashAdd);
- }
- rv = SSMSecurityAdvisorContext_DoPKCS12Response(res, req, responseKey);
- }
- done:
- if (p12Cxt != NULL) {
- SSM_FreeResource(SSMRESOURCE(p12Cxt));
- }
- return rv;
- }
- static CERTCertificate*
- SSMSecurityAdvisorContext_FindCertByNickname(SSMSecurityAdvisorContext *cx,
- HTTPRequest *req,
- char *certNickname)
- {
- CERTCertList *certList = NULL;
- CERTCertificate *cert = NULL;
- CERTCertListNode *certListNode = NULL;
- PRInt32 numcerts = 0;
- SSMTextGenContext *textGenCx = NULL;
- SSMStatus rv;
- char *htmlTemplate = NULL;
- certList = CERT_NewCertList();
- certList = CERT_CreateNicknameCertList(certList,
- cx->super.m_connection->m_certdb,
- certNickname, PR_Now(), PR_FALSE);
- if (certList == NULL) {
- certList = PK11_FindCertsFromNickname(certNickname, &cx->super);
- if (certList == NULL) {
- SSM_DEBUG("Could not find a certificate with nick '%s' "
- "in cert databasen", certNickname);
- goto loser;
- }
- }
- certListNode = CERT_LIST_HEAD(certList);
- while (!CERT_LIST_END(certListNode, certList)) {
- numcerts++;
- certListNode = CERT_LIST_NEXT(certListNode);
- }
- if (numcerts > 1) {
- char * formName = NULL, *params = NULL;
- rv = SSM_HTTPParamValue(req, "formName", &formName);
- if (rv != SSM_SUCCESS || !formName)
- SSM_DEBUG("AdvisorContext_FindCertByNickname:Can't get original formn");
- params = PR_smprintf("origin=%s",formName);
- cx->m_nickname = PL_strdup(certNickname);
- rv = SSMControlConnection_SendUIEvent(cx->super.m_connection,
- "get",
- "choose_cert",
- &cx->super,
- params,
- &cx->super.m_clientContext,
- PR_TRUE);
- /* Now wait until we are notified by the handler that the user
- * has selected a cert.
- */
- SSM_LockUIEvent(&cx->super);
- SSM_WaitUIEvent(&cx->super, PR_INTERVAL_NO_TIMEOUT);
- cert = (CERTCertificate*)cx->super.m_connection->super.super.m_uiData;
- if (cx->super.m_buttonType != SSM_BUTTON_CANCEL) {
- /*
- * If we don't sleep for a bit here, we cause Communicator to crash
- * because it tries to re-use a Window that gets killed. Guess
- * we're just too fast for Communicator.
- */
- PR_Sleep(PR_TicksPerSecond()*1);
- }
- PR_FREEIF(cx->m_nickname);
- cx->m_nickname = NULL;
- PR_FREEIF(params);
- } else {
- cert = CERT_FindCertByNickname(cx->super.m_connection->m_certdb,
- certNickname);
- cx->super.m_buttonType = SSM_BUTTON_OK;
- }
- CERT_DestroyCertList(certList);
- return cert;
- loser:
- PR_FREEIF(htmlTemplate);
- if (certList != NULL) {
- CERT_DestroyCertList(certList);
- }
- if (cert != NULL) {
- CERT_DestroyCertificate(cert);
- }
- if (textGenCx != NULL) {
- SSMTextGen_DestroyContext(textGenCx);
- }
- return NULL;
- }
- typedef struct SSMFindMineArgStr {
- CERTCertList *certList;
- SSMControlConnection *ctrl;
- } SSMFindMineArg;
- static SSMStatus
- ssm_find_all_mine(PRIntn index, void *arg, void *key, void *itemdata)
- {
- ssmCertData * data = (ssmCertData*)itemdata;
- SSMFindMineArg *findArg = (SSMFindMineArg*) arg;
- char *nick = (char*)key;
- SSMStatus rv = SSM_FAILURE;
- if (data->usage == clAllMine) {
- CERTCertList *tmpList;
- tmpList = CERT_CreateNicknameCertList(findArg->certList,
- findArg->ctrl->m_certdb,
- nick, PR_Now(), PR_FALSE);
- if (tmpList != NULL) {
- rv = SSM_SUCCESS;
- }
- }
- return rv;
- }
- SSMStatus
- SSMSecurityAdvisorContext_BackupAllMineCerts(SSMSecurityAdvisorContext *cx,
- HTTPRequest *req)
- {
- SSMFindMineArg arg;
- CERTCertList *certList=NULL;
- SSMPKCS12Context *p12Cxt=NULL;
- SSMPKCS12CreateArg p12Create;
- SSMResourceID rid;
- SSMStatus rv;
- CERTCertificate **certArr = NULL;
- int numCerts,i, finalCerts, currIndex;
- CERTCertListNode *node;
- PRIntn numNicks;
- const char *responseKey;
- certList = CERT_NewCertList();
- if (certList == NULL) {
- goto loser;
- }
- arg.certList = certList;
- arg.ctrl = req->ctrlconn;
- numNicks = SSMSortedList_Enumerate(cx->m_certhash, ssm_find_all_mine,
- &arg);
- if (numNicks <= 0){
- /* No certs to backup */
- SSM_HTTPReportError(req, HTTP_NO_CONTENT);
- goto loser;
- }
- certList = arg.certList;
- p12Create.isExportContext = PR_TRUE;
- rv = (SSMStatus) SSM_CreateResource(SSM_RESTYPE_PKCS12_CONTEXT,
- (void*)&p12Create, req->ctrlconn,
- &rid, (SSMResource**)(&p12Cxt));
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- SSM_CopyCMTItem(&p12Cxt->super.m_clientContext,
- &cx->super.m_clientContext);
-
- numCerts = SSM_CertListCount(certList);
- certArr = SSM_NEW_ARRAY(CERTCertificate*,numCerts);
- if (certArr == NULL) {
- goto loser;
- }
- node = CERT_LIST_HEAD(certList);
- for (i=0, currIndex=0, finalCerts=numCerts; i<numCerts; i++) {
- if (node->cert->slot == NULL ||
- PK11_IsInternal(node->cert->slot)) {
- certArr[currIndex] = node->cert;
- currIndex++;
- } else {
- finalCerts--;
- }
- node = CERT_LIST_NEXT(node);
- }
- rv = SSMPKCS12Context_CreatePKCS12FileForMultipleCerts(p12Cxt,
- PR_TRUE,
- certArr,
- finalCerts);
- PR_Free(certArr);
- certArr = NULL;
- CERT_DestroyCertList(certList);
- certList = NULL;
- if (rv == SSM_SUCCESS) {
- responseKey = (finalCerts > 1) ? "pkcs12_backup_multiple_success" :
- "pkcs12_backup_success";
- } else {
- if (p12Cxt->super.m_buttonType == SSM_BUTTON_CANCEL) {
- goto loser;
- } else {
- responseKey = SSMUI_GetPKCS12Error(rv, PR_TRUE);
- }
- }
- SSM_FreeResource(&p12Cxt->super);
- p12Cxt = NULL;
- if (SSMSecurityAdvisorContext_DoPKCS12Response(cx, req, responseKey)
- != SSM_SUCCESS) {
- goto loser;
- }
- return SSM_SUCCESS;
- loser:
- PR_FREEIF(certArr);
- if (certList != NULL) {
- CERT_DestroyCertList(certList);
- }
- if (p12Cxt != NULL) {
- SSM_FreeResource(&p12Cxt->super);
- }
- SSM_HTTPReportError(req, HTTP_NO_CONTENT);
- return SSM_FAILURE;
- }
- SSMStatus SSMSecurityAdvisorContext_DoPKCS12Backup(
- SSMSecurityAdvisorContext *cx,
- HTTPRequest *req)
- {
- SSMStatus rv;
- char *certNickname;
- const char *responseKey;
- SSMPKCS12CreateArg p12Create;
- SSMResourceID rid;
- SSMPKCS12Context *p12Cxt;
- p12Create.isExportContext = PR_TRUE;
- rv = (SSMStatus) SSM_CreateResource(SSM_RESTYPE_PKCS12_CONTEXT,
- (void*)&p12Create,
- SSMRESOURCE(cx)->m_connection,
- &rid, (SSMResource **)(&p12Cxt));
- if (rv != PR_SUCCESS) {
- goto loser;
- }
- /* pass along Advisor's client context for window management */
- SSM_CopyCMTItem(&((SSMResource *)p12Cxt)->m_clientContext,
- &((SSMResource *)cx)->m_clientContext);
- rv = SSM_HTTPParamValue(req, "selectCert", &certNickname);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
-
- p12Cxt->m_cert =
- SSMSecurityAdvisorContext_FindCertByNickname(cx, req, certNickname);
- if (cx->super.m_buttonType == SSM_BUTTON_CANCEL) {
- goto loser;
- }
- if (p12Cxt->m_cert == NULL) {
- goto loser;
- }
- /* p12Cxt->super.m_clientContext = cx->super.m_clientContext; */
- rv = SSMPKCS12Context_CreatePKCS12File(p12Cxt, PR_TRUE);
- if (rv == SSM_SUCCESS) {
- responseKey = "pkcs12_backup_success";
- } else {
- if (p12Cxt->super.m_buttonType == SSM_BUTTON_CANCEL) {
- goto loser;
- } else {
- responseKey = SSMUI_GetPKCS12Error(rv, PR_TRUE);
- }
- }
- if (SSMSecurityAdvisorContext_DoPKCS12Response(cx, req, responseKey)
- != SSM_SUCCESS) {
- goto loser;
- }
- SSM_FreeResource(&p12Cxt->super);
- return SSM_SUCCESS;
- loser:
- if (p12Cxt != NULL) {
- SSM_FreeResource(&p12Cxt->super);
- }
- SSM_HTTPReportError(req, HTTP_NO_CONTENT);
- return SSM_FAILURE;
- }
- char *
- ssm_packb64_name(char *b64Name)
- {
- char *htmlString = NULL;
- int numPercentSigns = 0;
- char *cursor, *retString;
- int i, newLen, origHTMLStrLen;
- htmlString = SSM_ConvertStringToHTMLString(b64Name);
- /*
- * Now let's see if there are any '%' characters that need
- * to be escaped so that printf statements succeed.
- */
- cursor = htmlString;
- while ((cursor = PL_strchr(cursor, '%')) != NULL) {
- numPercentSigns++;
- cursor++;
- }
- if (numPercentSigns == 0) {
- htmlString;
- }
- origHTMLStrLen = PL_strlen(htmlString);
- newLen = origHTMLStrLen + numPercentSigns + 1;
- retString = SSM_NEW_ARRAY(char, newLen);
- for (i=0,cursor=retString; i<origHTMLStrLen+1; i++,cursor++) {
- if (htmlString[i] == '%') {
- char *dollarSign, *placeHolder;
- /*
- * Let's see if this a urlencoded escape or a printf parameter.
- */
- placeHolder = &htmlString[i];
- dollarSign = PL_strchr(placeHolder, '$');
- if (dollarSign && ((dollarSign - placeHolder) < 2)) {
- /*
- * OK, this is a numbered parameter for printf
- */
- *cursor = htmlString[i];
- } else {
- /*
- * This is an escape for url encoding. Escape it so printf
- * doesn't blow up.
- */
- *cursor = '%';
- cursor++;
- *cursor = '%';
- }
- } else {
- *cursor = htmlString[i];
- }
- }
- PR_Free(htmlString);
- return retString;
- }
- SSMStatus
- SSMSecurityAdvisorContext_ProcessCRLDialog (HTTPRequest *req)
- {
- SSMHTTPParamMultValues crlNames={NULL, NULL, 0};
- CERTSignedCrl *realCrl;
- SECItem crlDERName;
- PRBool flushSSLCache = PR_FALSE;
- SSMStatus rv;
- SECStatus srv;
- int i, type;
- rv = SSM_HTTPParamValueMultiple(req, "crlNames", &crlNames);
- if (rv != SSM_SUCCESS || crlNames.numValues == 0) {
- goto loser;
- }
- memset (&crlDERName, 0, sizeof(SECItem));
- for (i=0; i<crlNames.numValues; i++) {
- /*
- * The first character in the value string represents the type,
- * either 1 (SEC_CRL_TYPE) or 0 (SEC_KRL_TYPE)
- */
- srv = ATOB_ConvertAsciiToItem(&crlDERName, crlNames.values[i]+1);
- if (srv != SECSuccess) {
- goto loser;
- }
- type = (crlNames.values[i][0] == '1') ? SEC_CRL_TYPE : SEC_KRL_TYPE;
- realCrl = SEC_FindCrlByName(req->ctrlconn->m_certdb,
- &crlDERName, type);
- SECITEM_FreeItem(&crlDERName, PR_FALSE);
- if (realCrl) {
- SEC_DeletePermCRL(realCrl);
- SEC_DestroyCrl(realCrl);
- flushSSLCache = PR_TRUE;
- }
- }
- if (flushSSLCache) {
- SSL_ClearSessionCache();
- }
- if (!SSM_IsCRLPresent(req->ctrlconn)) {
- /*
- * In this case, there are no more CRLs in the database,
- * so we'll replace the baseRef with one that will cause
- * the security advisor to refresh itself and elminate the
- * "Delete CRLs" button.
- */
- for (i=0; i<req->numParams; i++) {
- char *crlCloseKey = "crlclose_doclose_js";
- if (PL_strcmp(req->paramNames[i], "baseRef") == 0) {
- memcpy (req->paramValues[i], crlCloseKey,
- PL_strlen(crlCloseKey)+1);
- break;
- }
- }
- }
- if (SSM_HTTPDefaultCommandHandler(req) != SSM_SUCCESS) {
- goto loser;
- }
- PR_FREEIF(crlNames.values);
- return SSM_SUCCESS;
- loser:
- PR_FREEIF(crlNames.values);
- return SSM_FAILURE;
- }
- SSMStatus SSMSecurityAdvisorContext_Process_cert_mine_form(
- SSMSecurityAdvisorContext *res,
- HTTPRequest *req)
- {
- SSMStatus rv= SSM_FAILURE;
- char *button;
-
- /* Figure out which one of the buttons on the form was pressed. */
- if (SSM_HTTPParamValue(req, "backup", &button) == SSM_SUCCESS) {
- if (button != NULL) {
- rv = SSMSecurityAdvisorContext_DoPKCS12Backup(res, req);
- }
- } else if (SSM_HTTPParamValue(req, "restore", &button) == SSM_SUCCESS) {
- if (button != NULL) {
- rv = SSMSecurityAdvisorContext_DoPKCS12Restore(res, req);
- }
- } else if (SSM_HTTPParamValue(req, "delete", &button) == SSM_SUCCESS) {
- if (button != NULL) {
- rv = SSM_ProcessCertDeleteButton(req);
- }
- } else if (SSM_HTTPParamValue(req, "password", &button) == SSM_SUCCESS) {
- if (button != NULL) {
- rv = SSM_ProcessPasswordWindow(req);
- }
- } else if (SSM_HTTPParamValue(req, "ldap", &button) == SSM_SUCCESS) {
- if (button != NULL) {
- rv = SSM_ProcessLDAPWindow(req);
- }
- } else if (SSM_HTTPParamValue(req, "backup_all", &button) == SSM_SUCCESS) {
- if (button != NULL) {
- rv = SSMSecurityAdvisorContext_BackupAllMineCerts(res, req);
- }
- } else if (SSM_HTTPParamValue(req, "crlButton", &button) == SSM_SUCCESS) {
- if (button != NULL) {
- rv = SSM_HTTPReportError(req, HTTP_NO_CONTENT);
- }
- }
- return rv;
- }
- static SSMStatus
- SSMSecurityAdvisorContext_SetConfigOCSP(SSMSecurityAdvisorContext *cx,
- HTTPRequest *req)
- {
- char *responderURL = NULL, *caNickname = NULL;
- char *enableOCSP = NULL;
- CERTCertDBHandle *db;
- SSMStatus rv;
- SECStatus srv;
- db = cx->super.m_connection->m_certdb;
- rv = SSM_HTTPParamValue(req, "enableOCSP", &enableOCSP);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- if (!strcmp(enableOCSP,"noOCSP")) {
- CERT_DisableOCSPChecking(db);
- SSMControlConnection_SaveBoolPref(req->ctrlconn,
- "security.OCSP.enabled",
- PR_FALSE);
- SSMControlConnection_SaveBoolPref(req->ctrlconn,
- "security.OCSP.useDefaultResponder",
- PR_FALSE);
- CERT_DisableOCSPChecking(db);
- CERT_DisableOCSPDefaultResponder(db);
- } else if (!strcmp(enableOCSP,"noDefaultResponder")) {
- srv = CERT_EnableOCSPChecking(db);
- SSMControlConnection_SaveBoolPref(req->ctrlconn,
- "security.OCSP.enabled",
- PR_TRUE);
- SSMControlConnection_SaveBoolPref(req->ctrlconn,
- "security.OCSP.useDefaultResponder",
- PR_FALSE);
- if (srv != SECSuccess) {
- goto loser;
- }
- CERT_DisableOCSPDefaultResponder(db);
- } else if (!strcmp(enableOCSP,"useDefaultResponder")) {
- srv = CERT_EnableOCSPChecking(db);
- SSMControlConnection_SaveBoolPref(req->ctrlconn,
- "security.OCSP.enabled",
- PR_TRUE);
- SSMControlConnection_SaveBoolPref(req->ctrlconn,
- "security.OCSP.useDefaultResponder",
- PR_TRUE);
- if (srv != SECSuccess) {
- goto loser;
- }
- rv = SSM_HTTPParamValue(req, "ocspURL", &responderURL);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- SSMControlConnection_SaveStringPref(req->ctrlconn,
- "security.OCSP.URL",
- responderURL);
- rv = SSM_HTTPParamValue(req, "selectCert", &caNickname);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- SSMControlConnection_SaveStringPref(req->ctrlconn,
- "security.OCSP.signingCA",
- caNickname);
- srv = CERT_SetOCSPDefaultResponder(db, responderURL, caNickname);
- if (srv != SECSuccess) {
- goto loser;
- }
- srv = CERT_EnableOCSPDefaultResponder(db);
- if (srv != SECSuccess) {
- goto loser;
- }
- } else {
- goto loser;
- }
- return SSM_SUCCESS;
- loser:
- return SSM_FAILURE;
- }
- static SSMStatus
- SSMSecurityAdvisorContext_ProcessOCSPForm(SSMSecurityAdvisorContext *cx,
- HTTPRequest *req)
- {
- SSMStatus rv = SSM_SUCCESS;
- /*
- * First, if the Cancel button was pressed, then don't
- * process the form.
- */
- if (cx->super.m_buttonType == SSM_BUTTON_OK) {
- rv = SSMSecurityAdvisorContext_SetConfigOCSP(cx, req);
- }
- SSM_HTTPDefaultCommandHandler(req);
- return rv;
- }
- SSMStatus SSMSecurityAdvisorContext_FormSubmitHandler(SSMResource *res,
- HTTPRequest *req)
- {
- SSMStatus rv;
- char *formName;
- if (!SSM_IsAKindOf(res, SSM_RESTYPE_SECADVISOR_CONTEXT)) {
- return SSM_FAILURE;
- }
- /* First figure out which form we're processing. */
- rv = SSM_HTTPParamValue(req, "formName", &formName);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- if (PL_strcmp(formName, "prefs_submit_form") == 0) {
- /* save pref changes and close the Security Advisor */
- rv = SSMSecurityAdvisorContext_SavePrefs
- ((SSMSecurityAdvisorContext*)res, req);
- }
- else if (!strcmp(formName, "cert_mine_form") ||
- !strcmp(formName, "cert_others_form") ||
- !strcmp(formName, "cert_websites_form") ||
- !strcmp(formName, "cert_authorities_form")) {
- rv = SSMSecurityAdvisorContext_Process_cert_mine_form
- ((SSMSecurityAdvisorContext*)res, req);
- } else if (!strcmp(formName, "choose_cert_by_usage")) {
- rv = SSM_ChooseCertUsageHandler(req);
- } else if (!strcmp(formName, "set_db_password")) {
- rv = SSM_SetDBPasswordHandler(req);
- } else if (!strcmp(formName, "configureOCSPForm")){
- rv = SSMSecurityAdvisorContext_ProcessOCSPForm
- ((SSMSecurityAdvisorContext*)res, req);
- } else if (!strcmp(formName, "crlDialog")){
- rv = SSMSecurityAdvisorContext_ProcessCRLDialog(req);
- }else {
- rv = SSM_ERR_BAD_REQUEST;
- SSM_HTTPReportSpecificError(req, "Do not know how to process form %s",
- formName);
- }
- loser:
- return rv;
- }
- SSMStatus
- SSMSecurityAdvisorContext_Print(SSMResource *res,
- char *fmt, PRIntn numParam,
- char **value, char **resultStr)
- {
- SSMSecurityAdvisorContext *cx = (SSMSecurityAdvisorContext*)res;
- SSMStatus rv;
- PR_ASSERT(fmt != NULL && resultStr != NULL);
- if (!SSM_IsAKindOf(res, SSM_RESTYPE_SECADVISOR_CONTEXT)) {
- return PR_FAILURE;
- }
- /* We don't use the extra parameters */
- if (cx->m_nickname != NULL) {
- *resultStr = PR_smprintf(fmt, res->m_id, "backup", cx->m_nickname, *value);
- rv = (*resultStr == NULL) ? PR_FAILURE : PR_SUCCESS;
- } else {
- rv = SSMResource_Print(res, fmt, numParam, value, resultStr);
- }
- return rv;
- }
- SSMStatus SSM_SetSelectedItemInfo(SSMSecurityAdvisorContext* cx)
- {
- SSMStatus rv = SSM_SUCCESS;
- switch (cx->infoContext)
- {
- case SSM_NOINFO:
- cx->selectedItemPage = SSM_NO_INFO;
- break;
- case SSM_COMPOSE:
- break;
- case SSM_SNEWS_MESSAGE:
- case SSM_NEWS_MESSAGE:
- case SSM_MAIL_MESSAGE:
- cx->selectedItemPage = SSM_MESSAGE;
- if (cx->encryptedP7CInfo) {
- /* Get the P7 Content info resource */
- rv = SSMControlConnection_GetResource(SSMRESOURCE(cx)->m_connection, (SSMResourceID)cx->encryptedP7CInfo,
- (SSMResource**)&cx->encryptedP7CInfoRes);
- if ((rv != PR_SUCCESS) || (cx->encryptedP7CInfoRes == NULL)) {
- goto loser;
- }
- }
- if (cx->signedP7CInfo) {
- /* Get the P7 Content info resource */
- rv = SSMControlConnection_GetResource(SSMRESOURCE(cx)->m_connection, (SSMResourceID)cx->signedP7CInfo,
- (SSMResource**)&cx->signedP7CInfoRes);
- if ((rv != PR_SUCCESS) || (cx->signedP7CInfoRes == NULL)) {
- goto loser;
- }
- }
- if (!cx->encryptedP7CInfo &&
- !cx->signedP7CInfo &&
- cx->verifyError &&
- !cx->decodeError) {
- /* Somehow we have the error code backwards */
- cx->decodeError = cx->verifyError;
- cx->verifyError = 0;
- }
- cx->encrypted_b = (cx->decodeError ||
- (cx->encryptedP7CInfo &&
- SEC_PKCS7ContentIsEncrypted(cx->encryptedP7CInfoRes->m_cinfo)) ||
- (cx->signedP7CInfo &&
- SEC_PKCS7ContentIsEncrypted(cx->signedP7CInfoRes->m_cinfo)));
- cx->signed_b = (cx->verifyError ||
- (cx->encryptedP7CInfo &&
- SEC_PKCS7ContentIsSigned(cx->encryptedP7CInfoRes->m_cinfo)) ||
- (cx->signedP7CInfo &&
- SEC_PKCS7ContentIsSigned(cx->signedP7CInfoRes->m_cinfo)));
- break;
- case SSM_BROWSER:
- if (cx->resID == 0) {
- cx->selectedItemPage = SSM_NAVIGATOR_NO_SEC;
- } else {
- cx->selectedItemPage = SSM_NAVIGATOR_SSL;
- }
- break;
- default:
- cx->selectedItemPage = SSM_NO_INFO;
- break;
- }
- return rv;
- loser:
- return SSM_FAILURE;
- }
- SSMStatus sa_noinfo(SSMTextGenContext *cx)
- {
- SSMStatus rv = SSM_SUCCESS;
- SSMResource *target = NULL;
- SSMSecurityAdvisorContext* res = NULL;
- char *fmt = NULL;
- /* get the connection object */
- target = SSMTextGen_GetTargetObject(cx);
- PR_ASSERT(target != NULL);
- res = (SSMSecurityAdvisorContext*)target;
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_noinfo", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- PR_FREEIF(cx->m_result);
- cx->m_result = fmt;
- return SSM_SUCCESS;
- loser:
- return SSM_FAILURE;
- }
- SSMStatus sa_navigator(SSMTextGenContext *cx)
- {
- SSMStatus rv = SSM_SUCCESS;
- SSMResource *target = NULL;
- SSMSecurityAdvisorContext* res = NULL;
- char *fmt = NULL;
- SSMSSLSocketStatus *socketStatusRes = NULL;
- char * encryption_level = NULL;
- char * serverCN = NULL;
- char * issuerName = NULL;
- CERTCertificate *issuerCert = NULL;
- SSMResourceCert *serverCertRes = NULL, *issuerCertRes = NULL;
- int serverCertResID, issuerCertResID;
- /* get the connection object */
- target = SSMTextGen_GetTargetObject(cx);
- PR_ASSERT(target != NULL);
- res = (SSMSecurityAdvisorContext*)target;
- if (res->resID == 0) {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_navigator_no_sec", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- PR_FREEIF(cx->m_result);
- cx->m_result = PR_smprintf(fmt, res->hostname, res->hostname);
- PR_Free(fmt);
- return SSM_SUCCESS;
- } else {
- /* Get the socket status resource */
- rv = SSMControlConnection_GetResource(SSMRESOURCE(res)->m_connection, (SSMResourceID)res->resID,
- (SSMResource**)&socketStatusRes);
- if ((rv != PR_SUCCESS) || (socketStatusRes == NULL)) {
- goto loser;
- }
- /*
- * We inherit the client's reference here.
- */
- res->socketStatus = socketStatusRes;
- /* Do we have an error */
- if (!socketStatusRes->m_error) {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_navigator_ssl", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- #if 0
- /* Create a resource for this cert */
- rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE,
- socketStatusRes->m_cert,
- SSMRESOURCE(res)->m_connection,
- (long *) &serverCertResID,
- (SSMResource**)&serverCertRes);
- if (rv != PR_SUCCESS) {
- goto loser;
- }
- #else
- serverCertResID = socketStatusRes->m_cert->super.m_id;
- serverCertRes = socketStatusRes->m_cert;
- #endif
- issuerName = CERT_NameToAscii(&socketStatusRes->m_cert->cert->issuer);
- if (socketStatusRes->m_level == SSL_SECURITY_STATUS_ON_HIGH) {
- SSM_GetUTF8Text(cx, "high_grade_encryption", &encryption_level);
- } else {
- SSM_GetUTF8Text(cx, "low_grade_encryption", &encryption_level);
- }
- PR_FREEIF(cx->m_result);
- cx->m_result = PR_smprintf(fmt, res->hostname, issuerName, target->m_id, serverCertResID,
- encryption_level, socketStatusRes->m_cipherName,
- socketStatusRes->m_secretKeySize);
- PR_Free(issuerName);
- PR_Free(encryption_level);
- PR_Free(fmt);
- SSM_FreeResource(&socketStatusRes->super);
- return SSM_SUCCESS;
- } else {
- if (socketStatusRes->m_error == SEC_ERROR_UNKNOWN_ISSUER ||
- socketStatusRes->m_error == SEC_ERROR_CA_CERT_INVALID ) {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_navigator_ssl_unknown_issuer", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- /* Get the common name of the issuer */
- issuerName = CERT_NameToAscii(&socketStatusRes->m_cert->cert->issuer);
- if (!issuerName) {
- goto loser;
- }
- /* Get the common name of the server cert */
- serverCN = CERT_GetCommonName(&socketStatusRes->m_cert->cert->subject);
- if (!serverCN) {
- goto loser;
- }
- #if 0
- /* Create resource for the server cert */
- rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE,
- socketStatusRes->m_cert,
- SSMRESOURCE(res)->m_connection,
- (long *) &serverCertResID,
- (SSMResource**)&serverCertRes);
- if (rv != PR_SUCCESS) {
- goto loser;
- }
- #else
- serverCertRes = socketStatusRes->m_cert;
- serverCertResID = serverCertRes->super.m_id;
- #endif
- if (socketStatusRes->m_level == SSL_SECURITY_STATUS_ON_HIGH) {
- SSM_GetUTF8Text(cx, "high_grade_encryption", &encryption_level);
- } else {
- SSM_GetUTF8Text(cx, "low_grade_encryption", &encryption_level);
- }
- PR_FREEIF(cx->m_result);
- cx->m_result = PR_smprintf(fmt, res->hostname, issuerName, target->m_id, serverCertResID,
- encryption_level, socketStatusRes->m_cipherName,
- socketStatusRes->m_secretKeySize);
- PR_Free(fmt);
- PR_Free(issuerName);
- PR_Free(serverCN);
- PR_Free(encryption_level);
- SSM_FreeResource(&socketStatusRes->super);
- return SSM_SUCCESS;
- } else if(socketStatusRes->m_error == SEC_ERROR_UNTRUSTED_ISSUER) {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_navigator_ssl_bad_issuer", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- /* Get the common name of the issuer */
- issuerName = CERT_NameToAscii(&socketStatusRes->m_cert->cert->issuer);
- if (!issuerName) {
- goto loser;
- }
- /* Get the common name of the server cert */
- serverCN = CERT_GetCommonName(&socketStatusRes->m_cert->cert->subject);
- if (!serverCN) {
- goto loser;
- }
- #if 0
- /* Create resource for the server cert */
- rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE,
- socketStatusRes->m_cert,
- SSMRESOURCE(res)->m_connection,
- (long *) &serverCertResID,
- (SSMResource**)&serverCertRes);
- if (rv != PR_SUCCESS) {
- goto loser;
- }
- #else
- serverCertRes = socketStatusRes->m_cert;
- serverCertResID = serverCertRes->super.m_id;
- #endif
- /* Create a resource for the issuer cert (if it exists) */
- issuerCert = CERT_FindCertIssuer(socketStatusRes->m_cert->cert,
- PR_Now(), certUsageAnyCA);
- if (issuerCert) {
- /* Create resource for the issuer cert */
- rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE,
- issuerCert,
- SSMRESOURCE(res)->m_connection,
- (long *) &issuerCertResID,
- (SSMResource**)&issuerCertRes);
- if (rv != PR_SUCCESS) {
- goto loser;
- }
- } else {
- issuerCertResID = 0;
- }
- if (socketStatusRes->m_level == SSL_SECURITY_STATUS_ON_HIGH) {
- SSM_GetUTF8Text(cx, "high_grade_encryption", &encryption_level);
- } else {
- SSM_GetUTF8Text(cx, "low_grade_encryption", &encryption_level);
- }
- PR_FREEIF(cx->m_result);
- cx->m_result = PR_smprintf(fmt, res->hostname, issuerName, target->m_id, serverCertResID,
- issuerCertResID, encryption_level, socketStatusRes->m_cipherName,
- socketStatusRes->m_secretKeySize);
- PR_Free(fmt);
- PR_Free(issuerName);
- PR_Free(serverCN);
- PR_Free(encryption_level);
- SSM_FreeResource(&socketStatusRes->super);
- return SSM_SUCCESS;
- } else if (socketStatusRes->m_error == SSL_ERROR_BAD_CERT_DOMAIN) {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_navigator_ssl_bad_cert_domain", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- /* Get the common name of the server cert */
- serverCN = CERT_GetCommonName(&socketStatusRes->m_cert->cert->subject);
- if (!serverCN) {
- goto loser;
- }
- if (socketStatusRes->m_level == SSL_SECURITY_STATUS_ON_HIGH) {
- SSM_GetUTF8Text(cx, "high_grade_encryption", &encryption_level);
- } else {
- SSM_GetUTF8Text(cx, "low_grade_encryption", &encryption_level);
- }
- PR_FREEIF(cx->m_result);
- cx->m_result = PR_smprintf(fmt, res->hostname, serverCN, encryption_level, socketStatusRes->m_cipherName,
- socketStatusRes->m_secretKeySize);
- PR_Free(fmt);
- PR_Free(serverCN);
- PR_Free(encryption_level);
- SSM_FreeResource(&socketStatusRes->super);
- return SSM_SUCCESS;
- } else {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_navigator_ssl_unknown_error", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- #if 0
- /* Create resource for the server cert */
- rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE,
- socketStatusRes->m_cert,
- SSMRESOURCE(res)->m_connection,
- (long *) &serverCertResID,
- (SSMResource**)&serverCertRes);
- if (rv != PR_SUCCESS) {
- goto loser;
- }
- #else
- serverCertRes = socketStatusRes->m_cert;
- serverCertResID = serverCertRes->super.m_id;
- #endif
- if (socketStatusRes->m_level == SSL_SECURITY_STATUS_ON_HIGH) {
- SSM_GetUTF8Text(cx, "high_grade_encryption", &encryption_level);
- } else {
- SSM_GetUTF8Text(cx, "low_grade_encryption", &encryption_level);
- }
- PR_FREEIF(cx->m_result);
- cx->m_result = PR_smprintf(fmt, res->hostname, target->m_id, serverCertResID, encryption_level, socketStatusRes->m_cipherName,
- socketStatusRes->m_secretKeySize);
- PR_Free(fmt);
- SSM_FreeResource(&socketStatusRes->super);
- return SSM_SUCCESS;
- }
- }
- }
- loser:
- PR_FREEIF(fmt);
- PR_FREEIF(serverCN);
- PR_FREEIF(issuerName);
- if (socketStatusRes) {
- SSM_FreeResource(&socketStatusRes->super);
- }
- return SSM_FAILURE;
- }
- static CERTCertificate * get_signer_cert(SSMSecurityAdvisorContext *res)
- {
- CERTCertificate * cert = NULL;
- /* Get the signing cert */
- if (res->signedP7CInfoRes ||
- res->encryptedP7CInfoRes) {
- SEC_PKCS7SignerInfo **signerinfos;
- SEC_PKCS7ContentInfo *ci = res->signedP7CInfoRes->m_cinfo;
- if (!ci) ci = res->encryptedP7CInfoRes->m_cinfo;
- /* Finding the signers cert */
- switch(ci->contentTypeTag->offset) {
- default:
- case SEC_OID_PKCS7_DATA:
- case SEC_OID_PKCS7_DIGESTED_DATA:
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- /* Could only get here if SEC_PKCS7ContentIsSigned
- * is broken. */
- {
- PORT_Assert (0);
- cert=NULL;
- }
- break;
- case SEC_OID_PKCS7_SIGNED_DATA:
- {
- SEC_PKCS7SignedData *sdp;
- sdp = ci->content.signedData;
- signerinfos = sdp->signerInfos;
- cert = signerinfos[0]->cert;
- }
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- {
- SEC_PKCS7SignedAndEnvelopedData *saedp;
- saedp = ci->content.signedAndEnvelopedData;
- signerinfos = saedp->signerInfos;
- cert = signerinfos[0]->cert;
- }
- break;
- } /* finding the signer cert */
- }
- return cert;
- }
- char*
- SSM_GetOCSPURL(CERTCertificate *cert, PrefSet *prefs)
- {
- SSMStatus rv;
- PRBool boolval = PR_FALSE;
- char *responderURL = NULL;
- /* Is there a default responder installed */
- rv = PREF_GetBoolPref(prefs, "security.OCSP.useDefaultResponder", &boolval);
- if (boolval) {
- PREF_CopyStringPref(prefs, "security.OCSP.URL", &responderURL);
- } else {
- responderURL = CERT_GetOCSPAuthorityInfoAccessLocation(cert);
- }
- return responderURL;
- }
- static CERTCertificate * get_encryption_cert(SSMSecurityAdvisorContext *res)
- {
- return NULL;
- }
- static char *
- sa_get_algorithm_string(SEC_PKCS7ContentInfo *cinfo)
- {
- SECAlgorithmID *algid;
- SECOidTag algtag;
- const char *alg_name;
- int key_size;
- if (!cinfo) return 0;
- algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo);
- if (!algid) return 0;
- algtag = SECOID_GetAlgorithmTag(algid);
- alg_name = SECOID_FindOIDTagDescription(algtag);
- key_size = SEC_PKCS7GetKeyLength(cinfo);
- if (!alg_name || !*alg_name)
- return 0;
- else if (key_size > 0)
- return PR_smprintf("%d-bits %s",
- key_size, alg_name);
- else
- return PL_strdup(alg_name);
- }
- PRBool
- SSM_IsOCSPEnabled(SSMControlConnection *connection)
- {
- SSMStatus rv;
- PRBool isOCSPEnabled = PR_FALSE;
- rv = PREF_GetBoolPref(connection->m_prefs, "security.OCSP.enabled",
- &isOCSPEnabled);
- return (rv == SSM_SUCCESS) ? isOCSPEnabled : PR_FALSE;
- }
- char *
- SSM_GetGenericOCSPWarning(SSMControlConnection *ctrl,
- CERTCertificate *cert)
- {
- char *retString = NULL;
- char *responderURL = NULL;
- SSMTextGenContext *cx = NULL;
- SSMStatus rv;
- retString = PL_strdup("");
- if (SSM_IsOCSPEnabled(ctrl)) {
- responderURL = SSM_GetOCSPURL(cert, ctrl->m_prefs);
- if (responderURL == NULL) {
- goto done;
- }
- rv = SSMTextGen_NewTopLevelContext(NULL, &cx);
- if (rv != SSM_SUCCESS) {
- goto done;
- }
- SSM_GetAndExpandTextKeyedByString(cx, "ocsp_fail_message_generic",
- &retString);
- }
- done:
- PR_FREEIF(responderURL);
- if (cx) {
- SSMTextGen_DestroyContext(cx);
- }
- return retString;
- }
- SSMStatus sa_message(SSMTextGenContext *cx)
- {
- SSMStatus rv = SSM_SUCCESS;
- SSMResource *target = NULL;
- SSMSecurityAdvisorContext* res = NULL;
- char *fmt = NULL, *fmtSigned = NULL, *fmtEncrypted = NULL;
- char *genericOCSPWarning = NULL;
- /* get the connection object */
- target = SSMTextGen_GetTargetObject(cx);
- PR_ASSERT(target != NULL);
- res = (SSMSecurityAdvisorContext*)target;
- /* Deal with the signed part first */
- if (!res->signed_b) {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_message_not_signed", &fmtSigned);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- } else {
- if (res->verifyError == 0) {
- char *signer_email;
- CERTCertificate *signerCert = NULL;
- SSMResourceCert *signerCertRes = NULL;
- int signerCertResID;
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_message_signed", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- signerCert = get_signer_cert(res);
- if (!signerCert) {
- goto loser;
- }
- /* Get the signers email address */
- if (res->signedP7CInfoRes) {
- signer_email = SEC_PKCS7GetSignerEmailAddress(res->signedP7CInfoRes->m_cinfo);
- }
- if (!signer_email && res->encryptedP7CInfoRes) {
- signer_email = SEC_PKCS7GetSignerEmailAddress(res->encryptedP7CInfoRes->m_cinfo);
- }
- /* Create a cert resource for this certificate */
- rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE,
- signerCert,
- SSMRESOURCE(res)->m_connection,
- (long *) &signerCertResID,
- (SSMResource**)&signerCertRes);
- if (rv != PR_SUCCESS) {
- goto loser;
- }
- fmtSigned = PR_smprintf(fmt, signer_email, target->m_id, signerCertResID);
- PR_Free(fmt);
- } else {
- CERTCertificate *signerCert;
- /* Get the signing certificate */
- signerCert = get_signer_cert(res);
- if (!signerCert) {
- goto loser;
- }
- genericOCSPWarning =
- SSM_GetGenericOCSPWarning(target->m_connection,
- signerCert);
- switch(res->verifyError) {
- case SEC_ERROR_PKCS7_BAD_SIGNATURE:
- {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_message_signed_bad_signature", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- fmtSigned = PR_smprintf(fmt, genericOCSPWarning);
- PR_FREEIF(fmt);
- }
- break;
- /* This case handles both expired and not yet valid certs */
- case SEC_ERROR_EXPIRED_CERTIFICATE:
- {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_message_signed_expired_signing_cert", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- fmtSigned = PR_smprintf(fmt, genericOCSPWarning);
- PR_FREEIF(fmt);
- }
- break;
- case SEC_ERROR_REVOKED_CERTIFICATE:
- {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_message_signed_revoked_signing_cert", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- fmtSigned = PR_smprintf(fmt, genericOCSPWarning);
- PR_FREEIF(fmt);
- }
- break;
- case SEC_ERROR_UNKNOWN_ISSUER:
- {
- SSMResourceCert *signerCertRes;
- PRUint32 signerCertResID;
- char *fmt;
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_message_signed_unknown_issuer", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- /* Create a cert resource for this certificate */
- rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE,
- signerCert,
- SSMRESOURCE(res)->m_connection,
- (long *) &signerCertResID,
- (SSMResource**)&signerCertRes);
- if (rv != PR_SUCCESS) {
- goto loser;
- }
- fmtSigned = PR_smprintf(fmt, target->m_id,
- signerCertResID,
- genericOCSPWarning);
- PR_Free(fmt);
- }
- break;
- case SEC_ERROR_CA_CERT_INVALID:
- case SEC_ERROR_UNTRUSTED_ISSUER:
- {
- CERTCertificate *issuerCert;
- SSMResourceCert * signerCertRes, issuerCertRes;
- PRInt32 signerCertResID, issuerCertResID;
- char *fmt = NULL;
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_message_signed_untrusted_issuer", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- /* Get the isser cert */
- issuerCert = CERT_FindCertIssuer(signerCert, PR_Now(), certUsageAnyCA);
- if (!issuerCert) {
- goto loser;
- }
- /* Create resources for these certs */
- rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE,
- signerCert,
- SSMRESOURCE(res)->m_connection,
- (long *) &signerCertResID,
- (SSMResource**)&signerCertRes);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE,
- issuerCert,
- SSMRESOURCE(res)->m_connection,
- (long *) &issuerCertResID,
- (SSMResource**)&issuerCertRes);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- fmtSigned = PR_smprintf(fmt, target->m_id,
- signerCertResID,
- issuerCertResID,
- genericOCSPWarning);
- PR_Free(fmt);
- }
- break;
- /* This case handles both expired and not yet valid certs */
- case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
- {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_message_signed_expired_issuer_cert", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- fmtSigned = PR_smprintf(fmt, genericOCSPWarning);
- PR_FREEIF(fmt);
- }
- break;
- /* Cert address mismatch */
- case SEC_ERROR_CERT_ADDR_MISMATCH:
- {
- char * signer_email = NULL;
- char * signerCN = NULL;
- CERTCertificate *signerCert = NULL;
- SSMResourceCert *signerCertRes = NULL;
- PRInt32 signerCertResID;
- SECItem * item = NULL;
- char *signTime = NULL;
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_message_signed_addr_mismatch", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- /* Get the signer cert */
- signerCert = get_signer_cert(res);
- if (!signerCert) {
- goto loser;
- }
- /* Get the signer common name */
- signerCN = CERT_GetCommonName(&signerCert->subject);
- /* Get the signing time */
- item = SEC_PKCS7GetSigningTime(res->signedP7CInfoRes->m_cinfo);
- signTime = (item ? DER_UTCTimeToAscii(item) : 0);
- /* Create resources for these certs */
- rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE,
- signerCert,
- SSMRESOURCE(res)->m_connection,
- (long *) &signerCertResID,
- (SSMResource**)&signerCertRes);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- /* Get the signers email address */
- if (res->signedP7CInfoRes) {
- signer_email = SEC_PKCS7GetSignerEmailAddress(res->signedP7CInfoRes->m_cinfo);
- }
- if (!signer_email && res->encryptedP7CInfoRes) {
- signer_email = SEC_PKCS7GetSignerEmailAddress(res->encryptedP7CInfoRes->m_cinfo);
- }
- fmtSigned = PR_smprintf(fmt,res->senderAddr,signer_email,signerCN,signTime, target->m_id, signerCertResID);
- PR_Free(fmt);
- PR_FREEIF(signer_email);
- PR_FREEIF(signTime);
- }
- break;
- default:
- {
- CERTCertificate *signerCert = NULL;
- SSMStatus rv = SSM_SUCCESS;
- PrefSet* prefs = NULL;
- char *responderURL = NULL;
- prefs = res->super.m_connection->m_prefs;
- if (SSM_IsOCSPEnabled(res->super.m_connection)) {
-
- responderURL = SSM_GetOCSPURL(get_signer_cert(res), prefs);
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_message_signed_ocsp_error", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- fmtSigned = PR_smprintf(fmt,responderURL,res->verifyError);
- PR_Free(fmt);
- PR_Free(responderURL);
- } else {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_message_signed_unknown_error", &fmtSigned);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- }
- }
- break;
- /* XXX Missing the case where the issuer cert has been revoked XXX */
- }
- }
- }
- PR_FREEIF(genericOCSPWarning);
- /* Now deal with the encrypted part */
- if (!res->encrypted_b) {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_message_not_encrypted", &fmtEncrypted);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- } else {
- if (res->decodeError == 0) {
- SECAlgorithmID *algid;
- SECOidTag algtag;
- const char *alg_name;
- char *encryption_level;
- int key_size;
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_message_encrypted", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- if (res->encryptedP7CInfoRes == NULL) {
- algid = SEC_PKCS7GetEncryptionAlgorithm(res->signedP7CInfoRes->m_cinfo);
- } else {
- algid = SEC_PKCS7GetEncryptionAlgorithm(res->encryptedP7CInfoRes->m_cinfo);
- }
- if (!algid) {
- goto loser;
- }
- algtag = SECOID_GetAlgorithmTag(algid);
- alg_name = SECOID_FindOIDTagDescription(algtag);
- if (res->encryptedP7CInfoRes) {
- key_size = SEC_PKCS7GetKeyLength(res->encryptedP7CInfoRes->m_cinfo);
- } else {
- key_size = SEC_PKCS7GetKeyLength(res->signedP7CInfoRes->m_cinfo);
- }
- if (key_size == 40) {
- SSM_GetUTF8Text(cx, "low_grade_encryption", &encryption_level);
- } else if (key_size == 56 || key_size == 64) {
- SSM_GetUTF8Text(cx, "medium_grade_encryption", &encryption_level);
- } else {
- SSM_GetUTF8Text(cx, "high_grade_encryption", &encryption_level);
- }
- fmtEncrypted = PR_smprintf(fmt, encryption_level, key_size, alg_name);
- PR_Free(fmt);
- } else {
- switch (res->decodeError) {
- case SEC_ERROR_NOT_A_RECIPIENT:
- {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_message_encrypted_no_recipient", &fmtEncrypted);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- }
- break;
- case SEC_ERROR_BAD_PASSWORD:
- {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_message_encrypted_bad_password", &fmtEncrypted);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- }
- break;
- /* XXX Missing cases for contents altered and encryption strength mismatch XXX */
- default:
- {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_message_encrypted_unknown_error", &fmtEncrypted);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- }
- }
- }
- }
- /* Output the stirngs */
- PR_FREEIF(cx->m_result);
- cx->m_result = PR_smprintf("%s%s", fmtSigned, fmtEncrypted);
- PR_Free(fmtSigned);
- PR_Free(fmtEncrypted);
- return SSM_SUCCESS;
- loser:
- PR_FREEIF(fmt);
- PR_FREEIF(fmtSigned);
- PR_FREEIF(fmtEncrypted);
- return SSM_FAILURE;
- }
- SSMStatus sa_compose(SSMTextGenContext *cx)
- {
- SSMStatus rv = SSM_SUCCESS;
- SSMResource *target = NULL;
- SSMSecurityAdvisorContext* res = NULL;
- char *fmt = NULL, *fmtSigned = NULL, *fmtEncrypted = NULL;
- CERTCertificate *cert = NULL;
- char *certNickname = NULL;
- int err;
- char ** errCerts = NULL;
- int numErrCerts, i;
- /* get the connection object */
- target = SSMTextGen_GetTargetObject(cx);
- PR_ASSERT(target != NULL);
- res = (SSMSecurityAdvisorContext*)target;
- /* Get the default email certificate */
- rv = PREF_GetStringPref(target->m_connection->m_prefs, "security.default_mail_cert",
- &certNickname);
- if (rv != PR_SUCCESS) {
- goto loser;
- }
- /* Deal with the signing part first */
- if (!res->signthis) {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_not_to_be_signed", &fmtSigned);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- } else {
- /* Do we have a default cert installed */
- if (!certNickname) {
- /* We have no signing cert */
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_sign_no_cert", &fmtSigned);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- } else {
- cert = CERT_FindUserCertByUsage(target->m_connection->m_certdb,
- certNickname,
- certUsageEmailSigner,
- PR_FALSE,
- target->m_connection);
- if (!cert){
- /* We have no signing cert */
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_sign_no_cert", &fmtSigned);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- } else {
- /* Verify the cert */
- if (CERT_VerifyCert(target->m_connection->m_certdb,
- cert,
- PR_TRUE,
- certUsageEmailSigner,
- PR_Now(),
- target->m_connection,
- NULL) == SECSuccess) {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_can_be_signed", &fmtSigned);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- } else {
- err = PR_GetError();
- switch (err) {
- case SEC_ERROR_EXPIRED_CERTIFICATE:
- {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_sign_expired_cert", &fmtSigned);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- }
- break;
- case SEC_ERROR_REVOKED_CERTIFICATE:
- {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_sign_revoked_cert", &fmtSigned);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- }
- break;
- case SEC_ERROR_CERT_USAGES_INVALID:
- {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_sign_invalid_cert", &fmtSigned);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- }
- break;
- default:
- {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_sign_unknown_error", &fmtSigned);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- }
- }
- }
- }
- }
- }
- /* Now deal with the encryption part */
- if (!res->encryptthis) {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_not_to_be_encrypted", &fmtEncrypted);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- } else {
- if (!res->numRecipients) {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_encrypted_no_recipients", &fmtEncrypted);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- } else {
- /* Do we have a default cert installed */
- if (!certNickname) {
- /* We have no cert */
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_encrypted_no_cert", &fmtEncrypted);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- } else {
- cert = CERT_FindUserCertByUsage(target->m_connection->m_certdb,
- certNickname,
- certUsageEmailRecipient,
- PR_FALSE,
- target->m_connection);
- if (!cert) {
- /* We have no cert */
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_encrypted_no_cert", &fmtEncrypted);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- } else {
- /* Verify the cert */
- if (CERT_VerifyCert(target->m_connection->m_certdb,
- cert,
- PR_TRUE,
- certUsageEmailRecipient,
- PR_Now(),
- target->m_connection,
- NULL) == SECSuccess) {
- errCerts = (char **) PR_CALLOC(sizeof(char*)*res->numRecipients);
- if (!errCerts) {
- goto loser;
- }
- /* Verify the recipient certs */
- for (i=0,numErrCerts=0; i<res->numRecipients; i++) {
- cert = CERT_FindCertByEmailAddr(target->m_connection->m_certdb, res->recipients[i]);
- if (!cert) {
- errCerts[numErrCerts++] = PL_strdup(res->recipients[i]);
- continue;
- }
- if (CERT_VerifyCertNow(target->m_connection->m_certdb,
- cert,
- PR_TRUE,
- certUsageEmailRecipient,
- target->m_connection) == SECFailure) {
- errCerts[numErrCerts++] = PL_strdup(res->recipients[i]);
- continue;
- }
- CERT_DestroyCertificate(cert);
- }
- if (!numErrCerts) {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_can_be_encrypted", &fmtEncrypted);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- } else {
- char *option = NULL;
- char *out = NULL;
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_encrypted_bad_recipients", &fmt);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
-
- for (i=0; i < numErrCerts; i++) {
- option = PR_smprintf("<option selected>%s</option>n", errCerts[i]);
- SSM_ConcatenateUTF8String(&out, option);
- }
- fmtEncrypted = PR_smprintf(fmt, target->m_id, numErrCerts, out);
- PR_Free(fmt);
- }
- } else {
- err = PR_GetError();
- switch (err) {
- case SEC_ERROR_EXPIRED_CERTIFICATE:
- {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_encrypted_expired_cert", &fmtEncrypted);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- }
- break;
- case SEC_ERROR_REVOKED_CERTIFICATE:
- {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_encrypted_revoked_cert", &fmtEncrypted);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- }
- break;
- case SEC_ERROR_CERT_USAGES_INVALID:
- {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_encrypted_invalid_cert", &fmtEncrypted);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- }
- break;
- default:
- {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "sa_compose_encrypted_unknown_error", &fmtEncrypted);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- }
- }
- }
- }
- }
- }
- }
- /* Output the stirngs */
- PR_FREEIF(cx->m_result);
- cx->m_result = PR_smprintf("%s%s", fmtSigned, fmtEncrypted);
- PR_Free(fmtSigned);
- PR_Free(fmtEncrypted);
- return SSM_SUCCESS;
- loser:
- PR_FREEIF(fmt);
- PR_FREEIF(fmtSigned);
- PR_FREEIF(fmtEncrypted);
- return SSM_FAILURE;
- }
- SSMStatus SSMSecurityAdvisorContext_sa_selected_item(SSMTextGenContext* cx)
- {
- SSMStatus rv = SSM_SUCCESS;
- SSMResource *target = NULL;
- SSMSecurityAdvisorContext* res = NULL;
- /* get the connection object */
- target = SSMTextGen_GetTargetObject(cx);
- PR_ASSERT(target != NULL);
- res = (SSMSecurityAdvisorContext*)target;
- /* Load the correct page */
- switch (res->infoContext)
- {
- case SSM_NOINFO:
- rv = sa_noinfo(cx);
- break;
- case SSM_BROWSER:
- rv = sa_navigator(cx);
- break;
- case SSM_SNEWS_MESSAGE:
- case SSM_NEWS_MESSAGE:
- case SSM_MAIL_MESSAGE:
- rv = sa_message(cx);
- break;
- case SSM_COMPOSE:
- rv = sa_compose(cx);
- break;
- default:
- rv = SSM_FAILURE;
- break;
- }
- goto done;
- done:
- return rv;
- }
- SSMStatus
- SSMSecurityAdvisorContext_GetPrefListKeywordHandler(SSMTextGenContext* cx)
- {
- SSMStatus rv = SSM_SUCCESS;
- SSMSecurityAdvisorContext* adv = NULL;
- PrefSet* prefs = NULL;
- char* subboolfmt;
- char* subfmt;
- char* fmt;
- PRBool boolval;
- char* strval = NULL;
- char* str1 = NULL;
- char* str2 = NULL;
- char* str3 = NULL;
- char* str4 = NULL;
- char* str5 = NULL;
- char* str6 = NULL;
- char* str7 = NULL;
- char* str8 = NULL;
- char* str9 = NULL;
- char* str10 = NULL;
- char* str11 = NULL;
- if ((cx == NULL) || (cx->m_request == NULL) || (cx->m_result == NULL)) {
- goto loser;
- }
- adv = (SSMSecurityAdvisorContext*)SSMTextGen_GetTargetObject(cx);
- if ((adv == NULL) ||
- !SSM_IsA((SSMResource*)adv, SSM_RESTYPE_SECADVISOR_CONTEXT)) {
- goto loser;
- }
- /* get the prefs object */
- if ((adv->super.m_connection == NULL) ||
- (adv->super.m_connection->m_prefs == NULL)) {
- goto loser;
- }
- prefs = adv->super.m_connection->m_prefs;
- /* strings and formats */
- subboolfmt = "var %1$s = %2$s;n";
- subfmt = "var %1$s = "%2$s";n";
- /* since nickname may contain ', I really should use " for quotes */
- fmt = "%1$s%2$s%3$s%4$s%5$s%6$s%7$s%8$s%9$s%10$s%11$s";
- /* make sure all the right default values are enforced */
- rv = PREF_GetBoolPref(prefs, "security.enable_ssl2", &boolval);
- if ((rv == SSM_SUCCESS) && (boolval == PR_FALSE)) {
- str1 = PR_smprintf(subboolfmt, SSL2_SPK, "false");
- }
- else { /* default */
- str1 = PR_smprintf(subboolfmt, SSL2_SPK, "true");
- }
- rv = PREF_GetBoolPref(prefs, "security.enable_ssl3", &boolval);
- if ((rv == SSM_SUCCESS) && (boolval == PR_FALSE)) {
- str2 = PR_smprintf(subboolfmt, SSL3_SPK, "false");
- }
- else { /* default */
- str2 = PR_smprintf(subboolfmt, SSL3_SPK, "true");
- }
- rv = PREF_GetStringPref(prefs, "security.default_personal_cert", &strval);
- if ((strval != NULL) && (PL_strcmp(strval, "Select Automatically") == 0)) {
- str3 = PR_smprintf(subboolfmt, CLIENT_AUTH_SPK, "true");
- }
- else { /* default */
- str3 = PR_smprintf(subboolfmt, CLIENT_AUTH_SPK, "false");
- }
- rv = PREF_GetStringPref(prefs, "security.default_mail_cert", &strval);
- if (strval != NULL) {
- str4 = PR_smprintf(subfmt, EMAIL_CERT_SPK, strval);
- }
- else {
- str4 = PR_smprintf(subfmt, EMAIL_CERT_SPK, "");
- }
- rv = PREF_GetBoolPref(prefs, "security.warn_entering_secure", &boolval);
- if ((rv == SSM_SUCCESS) && (boolval == PR_FALSE)) {
- str5 = PR_smprintf(subboolfmt, WARN_ENTER_SECURE_SPK, "false");
- }
- else { /* default */
- str5 = PR_smprintf(subboolfmt, WARN_ENTER_SECURE_SPK, "true");
- }
- rv = PREF_GetBoolPref(prefs, "security.warn_leaving_secure", &boolval);
- if ((rv == SSM_SUCCESS) && (boolval == PR_FALSE)) {
- str6 = PR_smprintf(subboolfmt, WARN_LEAVE_SECURE_SPK, "false");
- }
- else { /* default */
- str6 = PR_smprintf(subboolfmt, WARN_LEAVE_SECURE_SPK, "true");
- }
- rv = PREF_GetBoolPref(prefs, "security.warn_viewing_mixed", &boolval);
- if ((rv == SSM_SUCCESS) && (boolval == PR_FALSE)) {
- str7 = PR_smprintf(subboolfmt, WARN_VIEW_MIXED_SPK, "false");
- }
- else { /* default */
- str7 = PR_smprintf(subboolfmt, WARN_VIEW_MIXED_SPK, "true");
- }
- rv = PREF_GetBoolPref(prefs, "security.warn_submit_insecure", &boolval);
- if ((rv == SSM_SUCCESS) && (boolval == PR_FALSE)) {
- str8 = PR_smprintf(subboolfmt, WARN_SUBMIT_INSECURE_SPK, "false");
- }
- else { /* default */
- str8 = PR_smprintf(subboolfmt, WARN_SUBMIT_INSECURE_SPK, "true");
- }
- rv = PREF_GetBoolPref(prefs, "mail.encrypt_outgoing_mail", &boolval);
- if ((rv == SSM_SUCCESS) && (boolval == PR_TRUE)) {
- str9 = PR_smprintf(subboolfmt, ENCRYPT_MAIL_SPK, "true");
- }
- else { /* default */
- str9 = PR_smprintf(subboolfmt, ENCRYPT_MAIL_SPK, "false");
- }
- rv = PREF_GetBoolPref(prefs, "mail.crypto_sign_outgoing_mail", &boolval);
- if ((rv == SSM_SUCCESS) && (boolval == PR_TRUE)) {
- str10 = PR_smprintf(subboolfmt, SIGN_MAIL_SPK, "true");
- }
- else { /* default */
- str10 = PR_smprintf(subboolfmt, SIGN_MAIL_SPK, "false");
- }
- rv = PREF_GetBoolPref(prefs, "mail.crypto_sign_outgoing_news", &boolval);
- if ((rv == SSM_SUCCESS) && (boolval == PR_TRUE)) {
- str11 = PR_smprintf(subboolfmt, SIGN_NEWS_SPK, "true");
- }
- else { /* default */
- str11 = PR_smprintf(subboolfmt, SIGN_NEWS_SPK, "false");
- }
- PR_FREEIF(cx->m_result);
- cx->m_result = PR_smprintf(fmt, str1, str2, str3, str4, str5, str6, str7,
- str8, str9, str10, str11);
- SSM_DebugUTF8String("security advisor prefs list", cx->m_result);
- goto done;
- loser:
- if (rv == SSM_SUCCESS) {
- rv = SSM_FAILURE;
- }
- done:
- PR_FREEIF(str1);
- PR_FREEIF(str2);
- PR_FREEIF(str3);
- PR_FREEIF(str4);
- PR_FREEIF(str5);
- PR_FREEIF(str6);
- PR_FREEIF(str7);
- PR_FREEIF(str8);
- PR_FREEIF(str9);
- PR_FREEIF(str10);
- PR_FREEIF(str11);
- return SSM_SUCCESS;
- }
- SSMStatus
- SSM_FreeTarget(SSMTextGenContext *cx)
- {
- SSMResource *res = NULL;
- res = SSMTextGen_GetTargetObject(cx);
- if (res != NULL) {
- SSM_FreeResource(res);
- }
- return SSM_SUCCESS;
- }
- #if 0
- /*---- Functions for handling Java principal certs ----*/
- static SSMStatus ssm_parse_token(char* start, char** dest)
- {
- char* openQuote = NULL;
- char* closeQuote = NULL;
- *dest = NULL;
- openQuote = strchr(start, '"');
- if (openQuote == NULL) {
- return SSM_FAILURE;
- }
- closeQuote = strchr(openQuote+1, '"');
- if (closeQuote == NULL) {
- return SSM_FAILURE;
- }
- *dest = (char*)PR_Calloc(closeQuote-openQuote, sizeof(char));
- if (*dest == NULL) {
- return SSM_FAILURE;
- }
- /* copy the string */
- memcpy(*dest, openQuote+1, closeQuote-openQuote-1);
-
- return SSM_SUCCESS;
- }
- static SSMStatus ssm_parse_principals(char* principalsData,
- char*** principals, PRIntn* size)
- {
- SSMStatus rv;
- PRIntn i = 1;
- char* start = NULL;
- *principals = NULL;
- /* first check whether the data is empty */
- if (*principalsData == ' ') {
- /* this is not a failure */
- *size = 0;
- return SSM_SUCCESS;
- }
- /* data looks like ""Netscape", "AOL"": tokenize the string */
- /* first determine the number of tokens */
- start = principalsData;
- while ((start = strchr(start+1, ',')) != NULL) {
- i++;
- }
- *principals = (char**)PR_Calloc(i, sizeof(char*));
- if (*principals == NULL) {
- return SSM_FAILURE;
- }
- *size = i;
- /* parse the tokens and store them in principals */
- for (start = principalsData, i = 0; start != NULL;
- start = strchr(start, ','), i++) {
- rv = ssm_parse_token(start, &((*principals)[i]));
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- }
- return SSM_SUCCESS;
- loser:
- for (i = 0; i < *size; i++) {
- PR_FREEIF((*principals)[i]);
- }
- return SSM_FAILURE;
- }
- static SSMStatus ssm_retrieve_principals(SSMSecurityAdvisorContext* adv,
- char*** principals, PRIntn* size)
- {
- SSMStatus rv;
- SingleNumMessage request;
- CMTItem message;
- /* first, clear data */
- PR_FREEIF(adv->m_principalsData);
- /* pack the request */
- request.value = (PRIntn)adv->super.m_id;
- if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) !=
- CMTSuccess) {
- return SSM_FAILURE;
- }
- message.type = SSM_EVENT_MESSAGE | SSM_GET_JAVA_PRINCIPALS_EVENT;
- /* send the message through the control out queue */
- SSM_SendQMessage(adv->super.m_connection->m_controlOutQ,
- SSM_PRIORITY_NORMAL, message.type, message.len,
- (char*)message.data, PR_TRUE);
- /* awkward way of blocking, but can't be helped */
- SSM_LockUIEvent(SSMRESOURCE(adv));
- while (adv->m_principalsData == NULL) {
- SSM_WaitUIEvent(SSMRESOURCE(adv), PR_INTERVAL_NO_TIMEOUT);
- }
- SSM_UnlockUIEvent(SSMRESOURCE(adv));
- /* parse the date that came from the plugin */
- rv = ssm_parse_principals(adv->m_principalsData, principals, size);
- return rv;
- }
- SSMStatus SSM_JavaPrincipalsKeywordHandler(SSMTextGenContext* cx)
- {
- SSMStatus rv;
- SSMSecurityAdvisorContext* adv = NULL;
- char* prefix = NULL;
- char* wrapper = NULL;
- char* suffix = NULL;
- char* prefixKey = NULL;
- char* wrapperKey = NULL;
- char* suffixKey = NULL;
- char* tmpStr = NULL;
- char* finalStr = NULL;
- const PRIntn CERT_PREFIX = 0;
- const PRIntn CERT_WRAPPER = 1;
- const PRIntn CERT_SUFFIX = 2;
- PRIntn i;
- #if 0
- char* principals[5] = {"Macromedia", "NetCenter", "Sun Microsystems",
- "MindSpring", "Hong Kong Telecom"};
- #else
- char** principals = NULL;
- PRIntn size;
- #endif
- if ((cx == NULL) || (cx->m_result == NULL)) {
- goto loser;
- }
- cx->m_result = NULL; /* in case we fail */
- adv = (SSMSecurityAdvisorContext*)SSMTextGen_GetTargetObject(cx);
- if ((adv == NULL) ||
- !SSM_IsA((SSMResource*)adv, SSM_RESTYPE_SECADVISOR_CONTEXT)) {
- goto loser;
- }
- /* retrieve the principals in string form from the plugin */
- rv = ssm_retrieve_principals(adv, &principals, &size);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- prefixKey = (char*)SSM_At(cx->m_params, CERT_PREFIX);
- wrapperKey = (char*)SSM_At(cx->m_params, CERT_WRAPPER);
- suffixKey = (char*)SSM_At(cx->m_params, CERT_SUFFIX);
- rv = SSM_GetAndExpandTextKeyedByString(cx, prefixKey, &prefix);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
-
- rv = SSM_GetAndExpandTextKeyedByString(cx, suffixKey, &suffix);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- finalStr = PL_strdup(prefix);
- if (finalStr == NULL) {
- goto loser;
- }
- /* add individual certs */
- if (principals != NULL) {
- rv = SSM_GetAndExpandTextKeyedByString(cx, wrapperKey, &wrapper);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- for (i = 0; i < size; i++) {
- tmpStr = PR_smprintf(wrapper, principals[i]);
- if (SSM_ConcatenateUTF8String(&finalStr, tmpStr) != SSM_SUCCESS) {
- goto loser;
- }
- PR_Free(tmpStr);
- tmpStr = NULL;
- }
- }
- rv = SSM_ConcatenateUTF8String(&finalStr, suffix);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- cx->m_result = finalStr;
- goto done;
- loser:
- if (rv == SSM_SUCCESS) {
- rv = SSM_FAILURE;
- }
- PR_FREEIF(finalStr);
- PR_FREEIF(tmpStr);
- done:
- PR_FREEIF(prefix);
- PR_FREEIF(wrapper);
- PR_FREEIF(suffix);
- return rv;
- }
- void SSM_HandleGetJavaPrincipalsReply(SSMControlConnection* ctrl,
- SECItem* message)
- {
- SSMStatus rv;
- GetJavaPrincipalsReply reply;
- SSMResource* res = NULL;
- SSMSecurityAdvisorContext* adv = NULL;
- if (CMT_DecodeMessage(GetJavaPrincipalsReplyTemplate, &reply,
- (CMTItem*)message) != CMTSuccess) {
- goto loser;
- }
- rv = SSMControlConnection_GetResource(ctrl, reply.resID, &res);
- if (rv != PR_SUCCESS || res == NULL) {
- goto loser;
- }
- /* make sure it is a Security Advisor context */
- if (!SSM_IsA(res, SSM_RESTYPE_SECADVISOR_CONTEXT)) {
- goto loser;
- }
- adv = (SSMSecurityAdvisorContext*)res;
- SSM_LockUIEvent(res);
- adv->m_principalsData = reply.principals;
- /* it will be freed by the Security Advisor */
- if (adv->m_principalsData == NULL) {
- adv->m_principalsData = PL_strdup("");
- }
- SSM_NotifyUIEvent(res);
- SSM_UnlockUIEvent(res);
- return;
- loser:
- /* XXX we can't really wake up the waiting Security Advisor object
- * because we don't know which resource to wake up. Bad.
- */
- PR_FREEIF(reply.principals);
- return;
- }
- #endif
- /* platform-dependent names for signed.db */
- #ifdef XP_UNIX
- #define SIGNED "/signedapplet.db"
- #else
- #ifdef XP_MAC
- #define SIGNED ":SignedAppletDB"
- #else
- #define SIGNED "\signed.db"
- #endif
- #endif
- SSMStatus SSM_RemovePrivilegesHandler(HTTPRequest* req)
- {
- SSMResource* res = NULL;
- char* buttonValue;
- SSMStatus rv;
- res = (req->target) ? req->target : (SSMResource*)req->ctrlconn;
- rv = SSM_HTTPParamValue(req, "OK", &buttonValue);
- if (rv == SSM_SUCCESS) {
- /* do action */
- char* signeddb;
- signeddb = PR_smprintf("%s%s", req->ctrlconn->m_dirRoot, SIGNED);
- /* XXX we delete the signed.db file here, but we do not actively
- * check the return value. There may be failures (file does
- * not exist, file may be already open, etc.) but we do not
- * have other recourses. Sigh.
- */
- PR_Delete(signeddb);
- PR_Free(signeddb);
- }
- else {
- rv = SSM_HTTPParamValue(req, "Cancel", &buttonValue);
- }
- if (rv != SSM_SUCCESS) {
- rv = SSM_ERR_NO_BUTTON;
- goto done;
- }
- done:
- rv = SSM_HTTPDefaultCommandHandler(req);
- return rv;
- }
- static PRBool
- ocsplist_is_default_signer(CERTCertificate *cert,
- SSMDefaultOCSPRespondersList *potResponders)
- {
- if (!cert->nickname) {
- return PR_FALSE;
- }
- return (PL_strcmp(cert->nickname, potResponders->defaultSigner) == 0) ?
- PR_TRUE : PR_FALSE;
- }
- static PRBool ocsplist_include_cert(CERTCertificate *cert)
- {
- CERTCertTrust *trust;
- char *nickname;
- trust = cert->trust;
- nickname = cert->nickname;
-
- if ( ( ( trust->sslFlags & CERTDB_INVISIBLE_CA ) ||
- (trust->emailFlags & CERTDB_INVISIBLE_CA ) ||
- (trust->objectSigningFlags & CERTDB_INVISIBLE_CA ) ) ||
- nickname == NULL) {
- return PR_FALSE;
- }
- if ((trust->sslFlags & CERTDB_VALID_CA) ||
- (trust->emailFlags & CERTDB_VALID_CA) ||
- (trust->objectSigningFlags & CERTDB_VALID_CA)) {
- return PR_TRUE;
- }
- return PR_FALSE;
- }
- static SECStatus ssm_get_potential_ocsp_signers(CERTCertificate *cert,
- SECItem *dbKey,
- void *arg)
- {
- SSMDefaultOCSPRespondersList *potResponders;
- char *serviceURL, *nickname;
- potResponders = (SSMDefaultOCSPRespondersList*)arg;
- if (!ocsplist_include_cert(cert) ||
- ocsplist_is_default_signer(cert, potResponders)) {
- goto done;
- }
- /*
- * We've got a CA cert, now we need to figure out if it has the AIA
- * extension that points to a responder somewhere. Get our own copy
- * of the nickname.
- */
- nickname = PL_strdup(cert->nickname);
- serviceURL = CERT_GetOCSPAuthorityInfoAccessLocation(cert);
- if (serviceURL != NULL) {
- /*
- * This CA has an AIA extension so we'll bundle it with the group
- * certs that have the
- */
- SSMSortedList_Insert(potResponders->respondersWithAIA,
- nickname, serviceURL);
- } else {
- /*
- * This CA doesn't have an AIA extension so we lump with the
- * rest of the CA's.
- */
- SSMSortedList_Insert(potResponders->respondersWithoutAIA,
- nickname, NULL);
- }
-
- done:
- return SECSuccess;
- }
- static void
- ocsplist_freedata(void *data)
- {
- if (data) {
- PR_Free(data);
- }
- }
- static void
- ocsplist_freekey(void *data)
- {
- ocsplist_freedata(data);
- }
- static SSMStatus
- ocsplist_aiacerts_enumerator(PRIntn index, void * arg, void *key,
- void *data)
- {
- SSMDefaultOCSPRespondersList *potResps;
- char *nextChunk;
- SSMStatus rv;
- potResps = (SSMDefaultOCSPRespondersList*)arg;
- nextChunk = PR_smprintf(potResps->wrapper, (char*)key,
- (data == NULL) ? "http://" : (char*)data);
- rv = SSM_ConcatenateUTF8String(&potResps->cx->m_result, nextChunk);
- PR_Free(nextChunk);
- return rv;
- }
- static SSMStatus
- ocsplist_cacerts_enumerator(PRIntn index, void * arg, void *key,
- void *data)
- {
- return ocsplist_aiacerts_enumerator(index, arg, key, data);
- }
- SSMStatus
- SSM_OCSPResponderList(SSMTextGenContext *cx)
- {
- SECStatus srv;
- SSMDefaultOCSPRespondersList potentialResponders = {NULL, NULL,
- NULL, NULL, NULL};
- SSMSortedListFn funcs;
- char *prefix, *suffix, *tmpStr, *prefService, *prefSigner;
- SSMStatus rv;
- PR_ASSERT(cx != NULL);
- funcs.keyCompare = certlist_compare_strings;
- funcs.freeListItemData = ocsplist_freedata;
- funcs.freeListItemKey = ocsplist_freekey;
- potentialResponders.respondersWithAIA = SSMSortedList_New(&funcs);
- potentialResponders.respondersWithoutAIA = SSMSortedList_New(&funcs);
- PREF_GetStringPref(cx->m_request->ctrlconn->m_prefs,
- "security.OCSP.signingCA",
- &potentialResponders.defaultSigner);
- srv = SEC_TraversePermCerts(cx->m_request->ctrlconn->m_certdb,
- ssm_get_potential_ocsp_signers,
- &potentialResponders);
- if (srv == SECSuccess) {
- srv = PK11_TraverseSlotCerts(ssm_get_potential_ocsp_signers,
- &potentialResponders,
- cx->m_request->ctrlconn);
- }
- if (srv != SECSuccess) {
- goto loser;
- }
- prefix = (char*)SSM_At(cx->m_params, 0);
- suffix = (char*)SSM_At(cx->m_params, 1);
- PR_ASSERT(prefix);
- PR_ASSERT(suffix);
- if (prefix == NULL || suffix == NULL) {
- goto loser;
- }
- rv = SSM_GetAndExpandTextKeyedByString(cx, prefix, &tmpStr);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- rv = SSM_ConcatenateUTF8String(&cx->m_result, tmpStr);
- PR_Free(tmpStr);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- rv = SSM_GetAndExpandTextKeyedByString(cx, "ocsp_list_wrapper",
- &potentialResponders.wrapper);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- potentialResponders.cx = cx;
- /*
- * Now it's time to build the list of potential OCSP Responders.
- */
- SSMSortedList_Enumerate(potentialResponders.respondersWithAIA,
- ocsplist_aiacerts_enumerator,
- &potentialResponders);
- SSMSortedList_Enumerate(potentialResponders.respondersWithoutAIA,
- ocsplist_cacerts_enumerator,
- &potentialResponders);
- /*
- * If there was a default responder enabled, let's over-ride whatever
- * the cert said with what the user entered as the appropriate value.
- */
- if (PREF_GetStringPref(cx->m_request->ctrlconn->m_prefs,
- "security.OCSP.URL", &prefService) == SSM_SUCCESS) {
- if (PREF_GetStringPref(cx->m_request->ctrlconn->m_prefs,
- "security.OCSP.signingCA", &prefSigner) == SSM_SUCCESS) {
- tmpStr = PR_smprintf("addNewServiceURL("%1$s","%2$s");n",
- prefSigner, prefService);
- rv = SSM_ConcatenateUTF8String(&cx->m_result, tmpStr);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- PR_Free(tmpStr);
- }
- }
- rv = SSM_GetAndExpandTextKeyedByString(cx, suffix, &tmpStr);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- rv = SSM_ConcatenateUTF8String(&cx->m_result, tmpStr);
- PR_Free(tmpStr);
- if (rv != SSM_SUCCESS) {
- goto loser;
- }
- PR_Free(potentialResponders.wrapper);
- SSMSortedList_Destroy(potentialResponders.respondersWithAIA);
- SSMSortedList_Destroy(potentialResponders.respondersWithoutAIA);
- return SSM_SUCCESS;
- loser:
- PR_FREEIF(potentialResponders.wrapper);
- if (potentialResponders.respondersWithAIA) {
- SSMSortedList_Destroy(potentialResponders.respondersWithAIA);
- }
- if (potentialResponders.respondersWithoutAIA) {
- SSMSortedList_Destroy(potentialResponders.respondersWithoutAIA);
- }
- return SSM_FAILURE;
- }
- SSMStatus
- SSM_DisplayCRLButton(SSMTextGenContext *cx)
- {
- SSMControlConnection *ctrl;
- char *crlHTML = NULL;
- SSMStatus rv;
- ctrl = SSMTextGen_GetControlConnection(cx);
- if (ctrl == NULL) {
- goto loser;
- }
- if (SSM_IsCRLPresent(ctrl)) {
- rv = SSM_GetAndExpandTextKeyedByString(cx, "crlButtonHTML", &crlHTML);
- if (rv == SSM_SUCCESS) {
- PR_FREEIF(cx->m_result);
- cx->m_result = crlHTML;
- }
- }
- return SSM_SUCCESS;
- loser:
- return SSM_FAILURE;
- }
- SSMStatus
- SSM_ListCRLs(SSMTextGenContext *cx)
- {
- SECStatus srv;
- CERTCrlHeadNode *head = NULL;
- CERTCrlNode *node;
- SSMControlConnection *ctrl;
- char *retString = NULL;
- char *currString ;
- char *emptyString = "";
- char *currCRLName = NULL;
- char *name = NULL;
- char *b64Name = NULL, *b64HTMLName;
-
- ctrl = SSMTextGen_GetControlConnection(cx);
- srv = SEC_LookupCrls(ctrl->m_certdb, &head, -1);
- if (srv != SECSuccess || head == NULL) {
- goto loser;
- }
- currString = emptyString;
- for (node=head->first; node != NULL; node = node->next) {
- name = CERT_GetCommonName(&(node->crl->crl.name));
- b64Name = BTOA_ConvertItemToAscii(&node->crl->crl.derName);
- b64HTMLName = ssm_packb64_name(b64Name);
- retString = PR_smprintf("%1$sn<option value="%4$d%2$s">%3$s",
- currString, b64HTMLName, name, node->type);
- PR_Free(name);
- PR_Free(b64Name);
- PR_Free(b64HTMLName);
- if (currString != emptyString)
- PR_Free(currString);
- currString = retString;
- }
- PR_FREEIF(cx->m_result);
- cx->m_result = retString;
- return SSM_SUCCESS;
- loser:
- return SSM_FAILURE;
- }
- SSMStatus
- ssm_getStringForAbleAgent(SSMTextGenContext *cx, const char *agents[])
- {
- int i;
- SSMStatus rv;
- char *key;
-
- key = SSM_At(cx->m_params, 0);
- for (i=0; agents[i] != NULL; i++) {
- if (PL_strstr(cx->m_request->agent, agents[i]) != NULL) {
- PR_FREEIF(cx->m_result);
- rv = SSM_GetAndExpandText(cx, key, &cx->m_result);
- if (rv != SSM_SUCCESS) {
- return rv;
- }
- break;
- }
- }
- return SSM_SUCCESS;
- }
- SSMStatus SSM_LayoutSMIMETab(SSMTextGenContext *cx)
- {
- return ssm_getStringForAbleAgent(cx, kSMimeApps);
- }
- SSMStatus SSM_LayoutJavaJSTab(SSMTextGenContext *cx)
- {
- return ssm_getStringForAbleAgent(cx, kJavaJSApps);
- }
- SSMStatus SSM_LayoutOthersTab(SSMTextGenContext *cx)
- {
- return ssm_getStringForAbleAgent(cx, kSMimeApps);
- }