netscape-revival
security/lib/nav/advisor.c
/* -*- Mode: C; tab-width: 8 -*-
* Security Advisor for Mozilla
*
* Copyright © 1995 Netscape Communications Corporation, all rights reserved.
*
* $Id: advisor.c,v 1.12.2.31 1997/05/24 00:23:37 jwz Exp $
*/
#include "xp.h"
#include "xpgetstr.h"
#include "prtypes.h"
#include "htmldlgs.h"
#include "secprefs.h"
#include "secnav.h"
#include "cert.h"
#include "ssl.h"
#ifndef NSPR20
#include "prglobal.h"
#else
#include "prtypes.h"
#include "prlog.h"
#endif /* NSPR20 */
#include "prefapi.h"
#include "sslproto.h"
#include "pk11func.h"
#include "secmod.h"
#include "pk11dlgs.h"
#include "structs.h"
#include "ntypes.h"
#include "secpkcs7.h"
#include "pkcs12.h"
#include "msgcom.h"
#include "fe_proto.h"
#ifdef AKBAR
# include "nspr/prtime.h"
#else /* !AKBAR */
# include "prtime.h"
#endif /* !AKBAR */
#ifdef XP_MAC
# include "certdb.h"
#else
# include "../cert/certdb.h"
#endif
#ifdef JAVA
#include "javasec.h"
#endif
extern int MK_OUT_OF_MEMORY;
extern int XP_SA_ALG_AND_BITS_FORMAT;
extern int SEC_ERROR_CERT_ADDR_MISMATCH;
extern int SA_STRINGS_BEGIN;
extern int SA_STRINGS_END;
extern int SA_VARNAMES_BEGIN;
extern int SA_VARNAMES_END;
extern int SA_VIEW_BUTTON_LABEL;
extern int SA_GET_CERT_BUTTON_LABEL;
extern int SA_GET_CERTS_BUTTON_LABEL;
extern int SA_VERIFY_BUTTON_LABEL;
extern int SA_DELETE_BUTTON_LABEL;
extern int SA_EXPORT_BUTTON_LABEL;
extern int SA_IMPORT_BUTTON_LABEL;
extern int SA_EDIT_BUTTON_LABEL;
extern int SA_SSL2_CONFIG_LABEL;
extern int SA_SSL3_CONFIG_LABEL;
extern int SA_SMIME_CONFIG_LABEL;
extern int SA_VIEW_CERT_BUTTON_LABEL;
extern int SA_EDIT_PRIVS_BUTTON_LABEL;
extern int SA_REMOVE_BUTTON_LABEL;
extern int SA_SET_PASSWORD_LABEL;
extern int SA_CHANGE_PASSWORD_LABEL;
extern int SA_VIEW_EDIT_BUTTON_LABEL;
extern int SA_ADD_BUTTON_LABEL;
extern int SA_LOGOUT_ALL_BUTTON_LABEL;
extern int SA_SEARCH_DIR_BUTTON_LABEL;
extern int SA_SEND_CERT_BUTTON_LABEL;
extern int SA_PAGE_INFO_LABEL;
static char *all_sa_strings = 0;
static int
init_sa_strings(void)
{
int status = 0;
if (all_sa_strings)
return 0;
else
{
int n_strings = 0;
int total_size = 0;
int i = 0;
char **vars = 0;
char **localized = 0;
char *out = 0;
n_strings = (SA_STRINGS_END - SA_STRINGS_BEGIN);
XP_ASSERT(n_strings == (SA_VARNAMES_END - SA_VARNAMES_BEGIN));
vars = (char **) PORT_Alloc (sizeof(char*) * (n_strings + 1));
if (!vars)
{
status = MK_OUT_OF_MEMORY;
goto FAIL;
}
PORT_Memset(vars, 0, (sizeof(char*) * (n_strings + 1)));
localized = (char **) PORT_Alloc (sizeof(char*) * (n_strings + 1));
if (!localized)
{
status = MK_OUT_OF_MEMORY;
goto FAIL;
}
PORT_Memset(localized, 0, (sizeof(char*) * (n_strings + 1)));
for (i = 1; i < n_strings; i++)
{
const char *str;
str = XP_GetString(SA_VARNAMES_BEGIN + i);
if (!str)
{
status = MK_OUT_OF_MEMORY;
goto FAIL;
}
vars[i] = PORT_Strdup(str);
if (!vars[i])
{
status = MK_OUT_OF_MEMORY;
goto FAIL;
}
str = XP_GetString(SA_STRINGS_BEGIN + i);
if (!str)
{
status = MK_OUT_OF_MEMORY;
goto FAIL;
}
localized[i] = PORT_Strdup(str);
if (!localized[i])
{
status = MK_OUT_OF_MEMORY;
goto FAIL;
}
total_size += PORT_Strlen(vars[i]);
total_size += PORT_Strlen(localized[i]);
total_size += 50;
}
all_sa_strings = (char *) PORT_Alloc(total_size + 200);
if (!all_sa_strings)
{
status = MK_OUT_OF_MEMORY;
goto FAIL;
}
out = all_sa_strings;
*out = 0;
#ifdef AKBAR
XP_STRCAT(out, "var Event = null;\n"); /* Kludge! */
out += XP_STRLEN(out);
#endif
for (i = 1; i < n_strings; i++)
{
const char *s;
PORT_Strcpy(out, "var ");
PORT_Strcat(out, vars[i]);
PORT_Strcat(out, " = \"");
out += PORT_Strlen(out);
PORT_Free(vars[i]);
vars[i] = 0;
for (s = localized[i]; s && *s; s++)
{
if (*s == '"' || *s == '\t' || *s == CR || *s == LF)
{
XP_SPRINTF(out, "\\%03o",
(unsigned int) ((unsigned char *) s));
out += PORT_Strlen(out);
}
else
{
*out++ = *s;
}
}
*out = '\0';
PORT_Free(localized[i]);
localized[i] = 0;
PORT_Strcat(out, "\";\n");
out += PORT_Strlen(out);
}
FAIL:
if (vars)
{
for (i = 0; i < n_strings; i++)
if (vars[i]) PORT_Free(vars[i]);
PORT_Free(vars);
}
if (localized)
{
for (i = 0; i < n_strings; i++)
if (localized[i]) PORT_Free(localized[i]);
PORT_Free(localized);
}
}
return status;
}
/* These defines are used for passing information to the Info Panel (drawn in
* drawstatus() in secprefs.html). The numbers here match numbers in the
* javascript for the context-sensitive messaging feaure
*
* Encrypt errors are passed in a javascript array, hence the quotes
*/
#define NOINFO 0
#define COMPOSE 1
#define MAIL_MESSAGE 2
#define NEWS_MESSAGE 3
#define SNEWS_MESSAGE 4
#define NAVIGATOR 5
#define MAIL_THREADS 6
#define NEWS_THREADS 7
#define ENC_NOERR 0 /* Encryption is possible or encrypted message is okay*/
#define SIG_NOERR 0 /* Signing is possible or signed message is okay */
/* Errors for COMPOSE context */
#define ENC_NORECIPIENT 1 /* There is a NULL recipient list. */
#define ENC_CERTMISSING 2 /* No cert for intended recipient */
#define ENC_CERTEXPIRED 3 /* Have recipient cert, but it is expired */
#define ENC_CERTREVOKED 4 /* The recipient cert has been revoked */
#define ENC_CERTNOALIAS 5 /* There is no cert for the recipient alias */
#define ENC_NEWSGROUP 6 /* Recipient is a news/discussion group, no encryption */
#define ENC_CERTINVALID 7
#define ENC_CERTUNTRUSTED 8
#define ENC_ISSUERUNTRUSTED 9
#define ENC_ISSUERUNKNOWN 10
#define ENC_CERT_UNKNOWN_ERROR 11
#define SIG_CERTMISSING 1 /* User does not have a cert to sign with */
/* Errors for MAIL_MESSAGE context and NEWS_MESSAGE context where appropriate*/
#define ENC_NOTENCRYPTED 1 /* Clear-text message */
#define ENC_FORANOTHER 2 /* Encrypted for another user, not readable */
#define ENC_UNKNOWN_ERROR 3 /* Uh, something else. */
#define SIG_NOTSIGNED 1 /* The message is not signed */
#define SIG_INVALID 2 /* The signer's cert is invalid (expired, etc) */
#define SIG_TAMPERED 3 /* The signed content is bogus */
#define SIG_ADDR_MISMATCH 4 /* "From" header and Cert email addrs differ */
/* Errors for NEWS_MESSAGE context that differ from MAIL_MESSAGE context */
#define ENC_SECURE 0
#define ENC_NOTSECURE 1
extern int XP_SECURITY_ADVISOR;
extern int XP_SECURITY_ADVISOR_TITLE_STRING;
extern int SECADV_STRINGS_0;
extern int SECADV_STRINGS_END;
extern int XP_CERT_SELECT_EDIT_STRING;
extern int XP_CERT_SELECT_DEL_STRING;
extern int XP_CERT_SELECT_VIEW_STRING;
extern int XP_CERT_SELECT_VERIFY_STRING;
extern int SEC_ERROR_NOT_A_RECIPIENT;
extern int SEC_ERROR_PKCS7_BAD_SIGNATURE;
extern int SEC_ERROR_NO_MEMORY;
/* errors for PKCS 12 */
extern int SEC_ERROR_EXPORTING_CERTIFICATES;
extern int SEC_ERROR_IMPORTING_CERTIFICATES;
/* errors from CERT_VerifyCert() */
extern int SEC_ERROR_UNTRUSTED_CERT;
extern int SEC_ERROR_UNTRUSTED_ISSUER;
extern int SEC_ERROR_UNKNOWN_ISSUER;
extern int SEC_ERROR_EXPIRED_CERTIFICATE;
extern int SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE;
extern int SEC_ERROR_CRL_EXPIRED;
extern int SEC_ERROR_KRL_EXPIRED;
extern int SEC_ERROR_REVOKED_KEY;
extern int SEC_ERROR_REVOKED_CERTIFICATE;
extern int SEC_ERROR_CERT_NOT_VALID;
extern int SEC_ERROR_CA_CERT_INVALID;
extern int SEC_ERROR_BAD_DER;
extern int SEC_ERROR_CRL_BAD_SIGNATURE;
extern int SEC_ERROR_KRL_BAD_SIGNATURE;
extern int SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID;
extern int SEC_ERROR_NO_KRL;
extern int SEC_ERROR_BAD_SIGNATURE;
extern void MimeGetCompositionSecurityInfo(MWContext *context,
char **sender_ret,
char **mail_recipients_ret,
char **news_recipients_ret,
XP_Bool *encrypt_p_ret,
XP_Bool *sign_p_ret,
int *delivery_error_ret);
extern void MimeGetSecurityInfo(MWContext *context, const char *url,
SEC_PKCS7ContentInfo **encrypted_cinfo_return,
SEC_PKCS7ContentInfo **signed_cinfo_return,
char **sender_addr_return,
int32 *decode_error_return,
int32 *verify_error_return);
extern char *MSG_ExtractRFC822AddressMailboxes (const char *line);
extern char *MSG_RemoveDuplicateAddresses (const char *addrs, const char *other_addrs);
extern int MSG_ParseRFC822Addresses (const char *line, char **names, char **addresses);
#ifdef AKBAR
extern void MSG_Command (MWContext *context, MSG_CommandType command);
#endif /* !AKBAR */
typedef struct _nnNode {
char *nickname;
struct _nnNode *next;
} nnNode;
typedef struct {
CERTCertDBHandle *handle;
MWContext *globalMWContext;
SEC_PKCS7ContentInfo *encrypted_p7contentinfo;
SEC_PKCS7ContentInfo *signed_p7contentinfo;
unsigned int curpage;
unsigned int pwasktype;
unsigned int pwaskinterval;
char *sslcertname;
char *mailcertname;
PRBool warnentersecure;
PRBool warnleavesecure;
PRBool warnmixed;
PRBool warnsendclear;
PRBool enablessl2;
PRBool enablessl3;
PRBool passwordset;
PRBool encryptalways;
PRBool signalways;
PRBool signnewsalways;
PRBool encryptthis;
PRBool oldencryptthis;
PRBool signthis;
PRBool oldsignthis;
/* stuff for HTTP security info, only valid for infocontext == 5 */
PRBool ssl_encrypted;
PRBool ssl_mixed;
PRBool nav_chrome_missing;
PRBool nav_missing_menubar;
PRBool nav_missing_toolbar;
PRBool nav_missing_personalbar;
PRBool nav_missing_location;
PRBool nav_missing_status;
PRBool nav_java;
PRBool nav_js;
char *nav_site_name;
char *nav_creator_name;
CERTCertificate *server_cert;
#if 0
PRBool fwdwarning;
PRBool rewarning;
#endif
unsigned int infocontext;
char *encrypterrors;
char *encrypterrorstr;
char *algorithmdesc;
unsigned int signerror;
char *signerrorstr;
char *signtime;
char *signername;
char *signeraddr;
char *senderaddr;
char *destnames;
char *mycerts;
char *mysslcerts;
char *mymailcerts;
char *peoplescerts;
char *sitecerts;
char *cacerts;
char *crmodules;
char *principals;
char *certs_to_fetch;
PRArenaPool *tmparena;
nnNode *mycertsList;
nnNode *mysslcertsList;
nnNode *mymailcertsList;
nnNode *sitecertsList;
nnNode *cacertsList;
nnNode *peoplescertsList;
URL_Struct *url;
void *proto_win;
} SecurityAdvisorState;
CERTCertificate *
SECNAV_GetDefaultEMailCert(void *win_cx)
{
char *charvalue = NULL;
CERTCertificate *cert = NULL;
int ret;
ret = PREF_CopyCharPref("security.default_mail_cert", &charvalue);
if ( charvalue ) {
cert = CERT_FindCertByNicknameOrEmailAddr(CERT_GetDefaultCertDB(),
charvalue);
if (cert == NULL) {
/* WE NEED TO GET THE WINDOW CONTEXT IN OUR CALL!! */
if (win_cx != NULL) {
cert = PK11_FindCertFromNickname(charvalue,win_cx);
}
}
PORT_Free(charvalue);
}
return(cert);
}
static SECStatus
setupDefaultEmailCert(void)
{
CERTCertificate *cert;
SECStatus rv = SECFailure;
cert = SECNAV_GetDefaultEMailCert(NULL);
if ( cert && ( cert->subjectList->emailAddr == NULL ) ) {
/* the user's cert does not have an e-mail address entry, so add one */
if ( cert->emailAddr && ( cert->rawKeyUsage & KU_KEY_ENCIPHERMENT ) ) {
rv = CERT_SaveSMimeProfile(cert, NULL, NULL);
/* don't care if it fails */
}
}
return(rv);
}
int
PR_CALLBACK SECNAV_MailCertPrefChange(const char *prefname, void *arg)
{
SECStatus rv;
rv = setupDefaultEmailCert();
return rv;
}
static void
initDefaultMailCertPref(void)
{
char *charvalue = NULL;
CERTCertificate *cert = NULL;
int ret;
CERTCertNicknames *names;
int i;
ret = PREF_CopyCharPref("security.default_mail_cert", &charvalue);
if ( ( charvalue == NULL ) || ( *charvalue == '\0' ) ) {
/* the user does not have a preference value */
names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(),
SEC_CERT_NICKNAMES_USER, NULL);
if ( names ) {
for ( i = 0; i < names->numnicknames; i++ ) {
cert =
CERT_FindCertByNicknameOrEmailAddr(CERT_GetDefaultCertDB(),
names->nicknames[i]);
if ( cert != NULL ) {
if ( cert->emailAddr ) {
/* cert has an email addr, so make it the default */
ret = PREF_SetCharPref("security.default_mail_cert",
names->nicknames[i]);
#ifdef AKBAR
/* We don't have PREF_RegisterCallback() in Akbar. */
SECNAV_MailCertPrefChange("security.default_mail_cert",
names->nicknames[i]);
#endif /* AKBAR */
ret = PREF_SavePrefFile();
CERT_DestroyCertificate(cert);
break;
}
CERT_DestroyCertificate(cert);
}
}
CERT_FreeNicknames(names);
}
}
return;
}
void
SECNAV_DefaultEmailCertInit(void)
{
SECStatus rv;
#ifndef AKBAR
/* We don't have PREF_RegisterCallback() in Akbar. */
PREF_RegisterCallback("security.default_mail_cert",
SECNAV_MailCertPrefChange,
NULL);
#endif /*!AKBAR */
rv = setupDefaultEmailCert();
if ( rv != SECSuccess ) {
initDefaultMailCertPref();
}
return;
}
#ifdef XP_WIN
static char *secprefsfooter = NULL;
static char *secprefsfooter2 = "";
extern char *wfe_LoadResourceString(char *);
#endif
/* Converts a C string to JavaScript, properly quoted.
if add_quotes is true, wraps the whole thing in double-quotes too.
*/
static char *
sa_make_js_string(const char *string, PRBool add_quotes)
{
const char *s;
char *result, *out;
int L = 0;
if (!string) string = "";
/* put a \ before \ or "
turn CRLF into LF
put \n\ before CR or LF
*/
for (s = string; *s; s++)
{
L++;
if (*s == CR && s[1] == LF)
s++;
if (*s == CR || *s == LF)
L += 3;
else if (*s == '\\' || *s == '"')
L++;
}
if (add_quotes)
L += 2;
result = (char *) PORT_Alloc(L+1);
if (!result) return 0;
out = result;
if (add_quotes)
*out++ = '"';
for (s = string; *s; s++)
{
if (*s == CR && s[1] == LF)
s++;
if (*s == CR || *s == LF)
{
*out++ = '\\';
*out++ = 'n';
*out++ = '\\';
}
else if (*s == '\\' || *s == '"')
*out++ = '\\';
*out++ = *s;
}
if (add_quotes)
*out++ = '"';
*out = 0;
return result;
}
/* This kludgy little hack appends data to the `dest' string.
prefix, if non-null, is appended as-is.
new_string is wrapped in double-quotes and properly escaped as
a JavaScript string, then appended.
then suffix, if non-null, is appended as-is.
dest is realloc'ed larger as needed, and returned.
*/
static char *
sa_push_js_string(char *dest,
const char *prefix,
const char *new_string,
const char *suffix)
{
char *s, *result;
if (!new_string) new_string = "";
s = sa_make_js_string(new_string, PR_TRUE);
if (!s) return dest; /* #### MK_OUT_OF_MEMORY */
result = PR_sprintf_append(dest, "%s%s%s",
(prefix ? prefix : ""),
s,
(suffix ? suffix : ""));
if (s) PORT_Free(s);
return result;
}
/* This is like sa_push_js_string, but appends an integer instead of
a string. realloc, prefix, and suffix behavior are the same.
*/
static char *
sa_push_js_int(char *dest,
const char *prefix,
int value,
const char *suffix)
{
return PR_sprintf_append(dest, "%s%i%s",
(prefix ? prefix : ""),
value,
(suffix ? suffix : ""));
}
static XPDialogStrings *
getAdvisorStrings(SecurityAdvisorState *state)
{
XPDialogStrings *strings;
char *varstring;
#ifdef XP_WIN
if ( secprefsfooter == NULL ) {
secprefsfooter = wfe_LoadResourceString("secprefs");
}
#endif
/* get empty strings */
strings = XP_GetDialogStrings(XP_SECURITY_ADVISOR);
if ( strings == NULL ) {
return(NULL);
}
/* This does a lot of realloc'ing, but it's a hell of a lot easier to
deal with than one enormous call to PR_smprintf. */
#define PUSH_RAW(NAME,VALUE) \
varstring = PR_sprintf_append(varstring, "var " NAME "=%s;\n", VALUE)
#define PUSH_INT(NAME,VALUE) \
varstring = PR_sprintf_append(varstring, "var " NAME "=%d;\n", VALUE)
#define PUSH_BOOL(NAME,VALUE) \
varstring = PR_sprintf_append(varstring, "var " NAME "=%s;\n", \
(VALUE ? "true" : "false"))
#define PUSH_STRING(NAME,VALUE) \
varstring = sa_push_js_string(varstring, "var " NAME "=", VALUE, ";\n")
/* Close off the `sa_handle' kludge... */
varstring = PORT_Strdup("';\n");
PUSH_INT ("sa_curpage", state->curpage);
PUSH_STRING ("sa_selected_ssl_cert", state->sslcertname);
PUSH_STRING ("sa_selected_mail_cert", state->mailcertname);
PUSH_BOOL ("sa_warn_enter_secure", state->warnentersecure);
PUSH_BOOL ("sa_warn_leave_secure", state->warnleavesecure);
PUSH_BOOL ("sa_warn_mixed", state->warnmixed);
PUSH_BOOL ("sa_warn_send_clear", state->warnsendclear);
PUSH_BOOL ("sa_enable_ssl2", state->enablessl2);
PUSH_BOOL ("sa_enable_ssl3", state->enablessl3);
PUSH_BOOL ("sa_password_set", state->passwordset);
PUSH_INT ("sa_password_ask_type", state->pwasktype);
PUSH_INT ("sa_password_ask_interval", state->pwaskinterval);
PUSH_BOOL ("sa_encrypt_always", state->encryptalways);
PUSH_BOOL ("sa_sign_mail_always", state->signalways);
PUSH_BOOL ("sa_sign_news_always", state->signnewsalways);
PUSH_BOOL ("sa_encrypt_this", state->encryptthis);
PUSH_BOOL ("sa_sign_this", state->signthis);
/* PUSH_BOOL ("sa_fwd_warning", state->fwdwarning); */
/* PUSH_BOOL ("sa_re_warning", state->rewarning); */
PUSH_INT ("sa_info_context", state->infocontext);
PUSH_RAW ("sa_encrypt_errors", state->encrypterrors);
PUSH_STRING ("sa_encrypt_error_str", state->encrypterrorstr);
PUSH_STRING ("sa_encryption_algorithm", state->algorithmdesc);
PUSH_INT ("sa_sign_error", state->signerror);
PUSH_STRING ("sa_sign_error_str", state->signerrorstr);
PUSH_STRING ("sa_signing_time", state->signtime);
PUSH_STRING ("sa_signer_name", state->signername);
PUSH_STRING ("sa_signer_addr", state->signeraddr);
PUSH_STRING ("sa_sender_addr", state->senderaddr);
PUSH_RAW ("sa_dest_names", state->destnames);
PUSH_RAW ("sa_your_certs", state->mycerts);
PUSH_RAW ("sa_your_ssl_certs", state->mysslcerts);
PUSH_RAW ("sa_your_mail_certs", state->mymailcerts);
PUSH_RAW ("sa_people_certs", state->peoplescerts);
PUSH_RAW ("sa_site_certs", state->sitecerts);
PUSH_RAW ("sa_signers_certs", state->cacerts);
PUSH_RAW ("sa_cr_modules", state->crmodules);
PUSH_RAW ("sa_principals", state->principals);
PUSH_BOOL ("sa_nav_info_encrypted", state->ssl_encrypted);
PUSH_BOOL ("sa_nav_info_mixed", state->ssl_mixed);
PUSH_BOOL ("sa_nav_info_chrome_missing", state->nav_chrome_missing);
PUSH_BOOL ("sa_nav_info_missing_menubar", state->nav_missing_menubar);
PUSH_BOOL ("sa_nav_info_missing_toolbar", state->nav_missing_toolbar);
PUSH_BOOL ("sa_nav_info_missing_personalbar",
state->nav_missing_personalbar);
PUSH_BOOL ("sa_nav_info_missing_location", state->nav_missing_location);
PUSH_BOOL ("sa_nav_info_missing_status", state->nav_missing_status);
PUSH_BOOL ("sa_nav_info_java", state->nav_java);
PUSH_BOOL ("sa_nav_info_js", state->nav_js);
PUSH_STRING ("sa_nav_info_site_name", state->nav_site_name);
PUSH_STRING ("sa_nav_info_creator_name", state->nav_creator_name);
#undef PUSH_RAW
#undef PUSH_INT
#undef PUSH_BOOL
#undef PUSH_STRING
/* make sure we will work on win16 */
PORT_Assert( ( PORT_Strlen(secprefsheader) +
PORT_Strlen(varstring) +
PORT_Strlen(all_sa_strings) ) < 30000 );
#ifdef XP_WIN
PORT_Assert( PORT_Strlen(secprefsfooter) < 60000 );
#else
PORT_Assert( PORT_Strlen(secprefsfooter) < 30000 );
#endif
PORT_Assert( PORT_Strlen(secprefsfooter2) < 30000 );
XP_SetDialogString(strings, 0, secprefsheader);
/* The value of sa_handle is in slot 1. */
XP_CopyDialogString(strings, 2, varstring);
XP_SetDialogString(strings, 3, all_sa_strings);
XP_SetDialogString(strings, 4, secprefsfooter);
XP_SetDialogString(strings, 5, secprefsfooter2);
PORT_Free(varstring);
return(strings);
}
static void
addNickname(PRArenaPool *arena, char *nickname, nnNode **headPtr)
{
nnNode *node;
int len;
node = *headPtr;
while ( node ) {
if ( PORT_Strcmp(nickname, node->nickname) == 0 ) {
return;
}
node = node->next;
}
/* if we get here then this is a new node */
node = PORT_ArenaAlloc(arena, sizeof(nnNode));
if ( node != NULL ) {
len = PORT_Strlen(nickname) + 1;
node->nickname = PORT_ArenaAlloc(arena,len);
if ( node->nickname != NULL ) {
PORT_Memcpy(node->nickname, nickname, len);
node->next = *headPtr;
*headPtr = node;
}
}
return;
}
SECStatus
collectCertStrings(CERTCertificate *cert, SECItem *dbkey, void *arg)
{
SecurityAdvisorState *state;
CERTCertTrust *trust;
char *nickname;
char *emailAddr;
PRBool usercert = PR_FALSE;
state = (SecurityAdvisorState *)arg;
/* look at the base cert info stuff, not the dbEntry since
* we may have been called from a PKCS#11 module */
nickname = cert->nickname;
trust = cert->trust;
emailAddr = cert->emailAddr;
if ( nickname ) {
/* it is my cert */
if ( ( trust->sslFlags & CERTDB_USER ) ||
( trust->emailFlags & CERTDB_USER ) ||
( trust->objectSigningFlags & CERTDB_USER ) ) {
usercert = PR_TRUE;
addNickname(state->tmparena, nickname, &state->mycertsList);
/* it is my SSL cert */
if ( trust->sslFlags & CERTDB_USER ) {
addNickname(state->tmparena, nickname, &state->mysslcertsList);
}
/* it is my mail cert */
if ( ( cert->emailAddr != NULL ) &&
( trust->emailFlags & CERTDB_USER ) ) {
addNickname(state->tmparena, nickname,
&state->mymailcertsList);
}
}
/* it is an SSL site */
if ( trust->sslFlags & CERTDB_VALID_PEER ) {
addNickname(state->tmparena, nickname, &state->sitecertsList);
}
/* CA certs */
if ( ( trust->sslFlags & CERTDB_VALID_CA ) ||
( trust->emailFlags & CERTDB_VALID_CA ) ||
( trust->objectSigningFlags & CERTDB_VALID_CA ) ) {
/* Don't display CAs that are invisible */
if ( ! ( ( trust->sslFlags & CERTDB_INVISIBLE_CA ) ||
(trust->emailFlags & CERTDB_INVISIBLE_CA ) ||
(trust->objectSigningFlags & CERTDB_INVISIBLE_CA ) ) ) {
addNickname(state->tmparena, nickname, &state->cacertsList);
}
}
}
if ( emailAddr != NULL ) {
/* Other peoples e-mail certs */
if ( ( !usercert ) && ( trust->emailFlags & CERTDB_VALID_PEER ) ) {
addNickname(state->tmparena, emailAddr,
&state->peoplescertsList);
}
}
return(SECSuccess);
}
static char *
sa_make_cert_list(nnNode *head)
{
nnNode *node;
char *retstr;
if ( head ) {
retstr = sa_push_js_string(NULL, "sa_init_sorted_array(",
head->nickname, NULL);
node = head->next;
while ( node ) {
retstr = sa_push_js_string(retstr, ",", node->nickname, NULL);
node = node->next;
}
retstr = PR_sprintf_append(retstr, ")");
} else {
retstr = PORT_Strdup("sa_init_sorted_array()");
}
return(retstr);
}
SECStatus
getCertVarStrings(SecurityAdvisorState *state, void *proto_win)
{
SECStatus rv;
CERTCertDBHandle *handle = state->handle;
/* free any strings hanging around */
if ( state->mycerts ) {
PORT_Free(state->mycerts);
state->mycerts = NULL;
}
if ( state->mysslcerts ) {
PORT_Free(state->mysslcerts);
state->mysslcerts = NULL;
}
if ( state->mymailcerts ) {
PORT_Free(state->mymailcerts);
state->mymailcerts = NULL;
}
if ( state->peoplescerts ) {
PORT_Free(state->peoplescerts);
state->peoplescerts = NULL;
}
if ( state->sitecerts ) {
PORT_Free(state->sitecerts);
state->sitecerts = NULL;
}
if ( state->cacerts ) {
PORT_Free(state->cacerts);
state->cacerts = NULL;
}
state->tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (state->tmparena == NULL) {
goto loser;
}
state->mycertsList = NULL;
state->mysslcertsList = NULL;
state->mymailcertsList = NULL;
state->sitecertsList = NULL;
state->cacertsList = NULL;
state->peoplescertsList = NULL;
rv = SEC_TraversePermCerts(handle, collectCertStrings, (void *)state);
if (rv == SECSuccess) {
rv=PK11_TraverseSlotCerts(collectCertStrings,(void *)state,proto_win);
}
state->mycerts = sa_make_cert_list(state->mycertsList);
state->mysslcerts = sa_make_cert_list(state->mysslcertsList);
state->mymailcerts = sa_make_cert_list(state->mymailcertsList);
state->peoplescerts = sa_make_cert_list(state->peoplescertsList);
state->sitecerts = sa_make_cert_list(state->sitecertsList);
state->cacerts = sa_make_cert_list(state->cacertsList);
PORT_FreeArena(state->tmparena, PR_FALSE);
loser:
if ( ( state->mysslcerts == NULL ) ||
( state->mymailcerts == NULL ) ||
( state->peoplescerts == NULL ) ||
( state->sitecerts == NULL ) ||
( state->cacerts == NULL ) ) {
return(SECFailure);
} else {
return(SECSuccess);
}
}
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(XP_GetString(XP_SA_ALG_AND_BITS_FORMAT),
key_size, alg_name);
else
return PORT_Strdup(alg_name);
}
/*
* Fill the context and error values and name strings for context-sensitive
* Security Advisor "Security Info" display. See "function displaystatus()
* in secprefs.html
*/
SECStatus
getStatusValues(SecurityAdvisorState *state, void *proto_win, URL_Struct *url)
{
char *sender = 0, *mail_recipients = 0, *news_recipients = 0, *tempname = 0;
XP_Bool encryptthis = FALSE, signthis = FALSE, encrypted_b = FALSE,
signed_b = FALSE, snews_hint = FALSE;
int delivery_error = 0;
int32 decode_error = 0, verify_error = 0;
int errorflag = 0, errorcount=0;
SEC_PKCS7ContentInfo *encrypted_p7contentinfo = 0;
SEC_PKCS7ContentInfo *signed_p7contentinfo = 0;
CERTCertDBHandle *handle = state->handle;
CERTCertificate *signercert, *receivercert;
if (state->encrypterrors) {
PORT_Free(state->encrypterrors);
state->encrypterrors = NULL;
}
if (state->encrypterrorstr) {
PORT_Free(state->encrypterrorstr);
state->encrypterrorstr = NULL;
}
if (state->algorithmdesc) {
PORT_Free(state->algorithmdesc);
state->algorithmdesc = NULL;
}
if (state->signerrorstr) {
PORT_Free(state->signerrorstr);
state->signerrorstr = NULL;
}
if (state->signtime) {
PORT_Free(state->signtime);
state->signtime = NULL;
}
if (state->signername) {
PORT_Free(state->signername);
state->signername = NULL;
}
if (state->signeraddr) {
PORT_Free(state->signeraddr);
state->signeraddr = NULL;
}
if (state->senderaddr) {
PORT_Free(state->senderaddr);
state->senderaddr = NULL;
}
if (state->destnames) {
PORT_Free(state->destnames);
state->destnames = NULL;
}
if (state->nav_site_name) {
PORT_Free(state->nav_site_name);
state->nav_site_name = NULL;
}
if (state->nav_creator_name) {
PORT_Free(state->nav_creator_name);
state->nav_creator_name = NULL;
}
if (state->server_cert) {
CERT_DestroyCertificate(state->server_cert);
state->server_cert = NULL;
}
if (state->certs_to_fetch) {
PORT_Free(state->certs_to_fetch);
state->certs_to_fetch = NULL;
}
switch (state->infocontext) {
#ifndef MOZ_LITE
case COMPOSE: {
char *all_mailboxes = 0, *mailboxes = 0, *mailbox_list = 0;
const char *mailbox = 0, *newsbox = 0;
int count = 0;
XP_Bool valid_list=PR_TRUE;
MimeGetCompositionSecurityInfo((MWContext *)proto_win, &sender, &mail_recipients,
&news_recipients, &encryptthis, &signthis, &delivery_error);
state->oldencryptthis = state->encryptthis = encryptthis;
state->oldsignthis = state->signthis = signthis;
/* Initial value of javascript strings set here, closing paren added
* after the recipient check loop. The closing paren will replace
* the trailing comman to make javascript happy
*/
PORT_Assert(!state->encrypterrors);
PORT_Assert(!state->destnames);
state->encrypterrors = PORT_Strdup("sa_init_array(");
state->destnames = PORT_Strdup("sa_init_array(");
/* We want either an encrypterrors list with at most one ENC_NOERR entry
* or at least one non-ENC_NOERR entry to keep the list short.
*/
all_mailboxes = MSG_ExtractRFC822AddressMailboxes(mail_recipients);
mailboxes = MSG_RemoveDuplicateAddresses(all_mailboxes, 0);
if (all_mailboxes) PORT_Free(all_mailboxes);
if (mailboxes)
count = MSG_ParseRFC822Addresses (mailboxes, 0, &mailbox_list);
/* An empty mail_recipient list is noteworthy */
valid_list = (XP_Bool)count;
errorflag=(valid_list ? ENC_NOERR : ENC_NORECIPIENT);
if (mailboxes) PORT_Free(mailboxes);
mailbox = mailbox_list;
for (; count > 0; count--)
{
errorflag=ENC_NOERR;
receivercert = CERT_FindCertByEmailAddr(handle, (char *)mailbox);
if (receivercert == NULL) {
errorflag= ENC_CERTMISSING;
} else if (CERT_VerifyCertNow(CERT_GetDefaultCertDB(),
receivercert,
TRUE,
certUsageEmailRecipient,
(MWContext *)proto_win)
== SECFailure) {
int xperr = XP_GetError();
if (xperr == SEC_ERROR_UNTRUSTED_CERT)
errorflag = ENC_CERTUNTRUSTED;
else if (xperr == SEC_ERROR_UNTRUSTED_ISSUER)
errorflag = ENC_ISSUERUNTRUSTED;
else if (xperr == SEC_ERROR_UNKNOWN_ISSUER)
errorflag = ENC_ISSUERUNKNOWN;
else if (xperr == SEC_ERROR_EXPIRED_CERTIFICATE ||
xperr == SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE ||
xperr == SEC_ERROR_CRL_EXPIRED ||
xperr == SEC_ERROR_KRL_EXPIRED)
errorflag = ENC_CERTEXPIRED;
else if (xperr == SEC_ERROR_REVOKED_KEY ||
xperr == SEC_ERROR_REVOKED_CERTIFICATE)
errorflag = ENC_CERTREVOKED;
else if (xperr == SEC_ERROR_CERT_NOT_VALID ||
xperr == SEC_ERROR_BAD_SIGNATURE ||
xperr == SEC_ERROR_CA_CERT_INVALID ||
xperr == SEC_ERROR_BAD_DER ||
xperr == SEC_ERROR_CRL_BAD_SIGNATURE ||
xperr == SEC_ERROR_KRL_BAD_SIGNATURE ||
xperr == SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID ||
xperr == SEC_ERROR_NO_KRL)
errorflag = ENC_CERTINVALID;
else
errorflag = ENC_CERT_UNKNOWN_ERROR;
} else { /* CERT_VerifyCert() passed */
errorflag = ENC_NOERR;
}
if (errorflag != ENC_NOERR) {
state->encrypterrors = sa_push_js_int(state->encrypterrors,
NULL, errorflag, ",");
state->destnames = sa_push_js_string(state->destnames,
NULL, mailbox, ",");
state->certs_to_fetch = PR_sprintf_append(state->certs_to_fetch,
"%s,", mailbox);
errorcount++;
}
if (receivercert) CERT_DestroyCertificate(receivercert);
mailbox += PORT_Strlen(mailbox) + 1;
}
if(mailbox_list) PORT_Free(mailbox_list);
newsbox = (news_recipients ? PORT_Strtok(news_recipients,",") : 0);
while(newsbox) {
state->encrypterrors = sa_push_js_int(state->encrypterrors,
NULL, ENC_NEWSGROUP, ",");
state->destnames = sa_push_js_string(state->destnames,
NULL, newsbox, ",");
errorcount++;
newsbox = PORT_Strtok(NULL,",");
}
if (errorcount == 0) {
state->encrypterrors = sa_push_js_int(state->encrypterrors,
NULL,
(valid_list
? ENC_NOERR
: ENC_NORECIPIENT),
",");
state->destnames = PR_sprintf_append(state->destnames, "\"\",");
}
/* Replace trailing commas with closing paren */
state->destnames[PORT_Strlen(state->destnames) - 1] = ')';
state->encrypterrors[PORT_Strlen(state->encrypterrors) - 1] = ')';
/* XXX Is simply checking for whether we have one sufficient ? */
if (state->mymailcerts)
state->signerror = SIG_NOERR;
else
state->signerror = SIG_CERTMISSING;
/* XXX On WinNT, passing 'sender' in signername causes a javascript bug,
* along the lines of "var sa_signer_name=""common name<email@domain.top>"""
* which causes parse errors in JS, halting the whole dialog.
*/
break;
}
case SNEWS_MESSAGE:
case NEWS_MESSAGE:
case MAIL_MESSAGE: {
int sign_error = 0, encrypt_error = 0;
char *commonname = 0;
char *addr = 0;
char *sender_addr = 0;
XP_Bool news_p = (state->infocontext == NEWS_MESSAGE ||
state->infocontext == SNEWS_MESSAGE);
/* Look up the security status of the message. Note that decode_error
may be set even if we don't have any content-infos -- that will
happen if the message is encrypted but totally mangled.
*/
MimeGetSecurityInfo((MWContext *)proto_win, url->address,
&encrypted_p7contentinfo,
&signed_p7contentinfo,
&sender_addr,
&decode_error, &verify_error);
state->encrypted_p7contentinfo = encrypted_p7contentinfo;
state->signed_p7contentinfo = signed_p7contentinfo;
state->destnames = PORT_Strdup("sa_init_array(\"\")");
state->encrypterrors = PORT_Strdup("sa_init_array(");
PORT_Assert(!state->senderaddr);
state->senderaddr = sender_addr;
sender_addr = 0;
if (news_p)
{
/* News messages are never encrypted. This is error protection in
case something went wonky in MimeGetSecurityInfo(). */
XP_ASSERT(!encrypted_p7contentinfo);
if (encrypted_p7contentinfo && !signed_p7contentinfo)
{
signed_p7contentinfo = encrypted_p7contentinfo;
encrypted_p7contentinfo = 0;
}
}
if (!encrypted_p7contentinfo &&
!signed_p7contentinfo &&
verify_error &&
!decode_error)
{
/* Something's gone all bass-ackwards on us.
This must be a decrypt-error (like "can't do that algorithm")
but it came to us in `verify_error' instead.
*/
decode_error = verify_error;
verify_error = 0;
}
/* Decide whether the message was encrypted/signed (whether valid
or not.)
*/
encrypted_b = (decode_error ||
(encrypted_p7contentinfo &&
SEC_PKCS7ContentIsEncrypted(encrypted_p7contentinfo))||
(signed_p7contentinfo &&
SEC_PKCS7ContentIsEncrypted(signed_p7contentinfo)));
signed_b = (verify_error ||
(encrypted_p7contentinfo &&
SEC_PKCS7ContentIsSigned(encrypted_p7contentinfo))||
(signed_p7contentinfo &&
SEC_PKCS7ContentIsSigned(signed_p7contentinfo)));
/* Pull the names/addresses out of the certs, if possible.
*/
if (signed_p7contentinfo &&
SEC_PKCS7ContentIsSigned(signed_p7contentinfo))
{
commonname =
SEC_PKCS7GetSignerCommonName(signed_p7contentinfo);
addr = SEC_PKCS7GetSignerEmailAddress(signed_p7contentinfo);
}
if (encrypted_p7contentinfo &&
SEC_PKCS7ContentIsSigned(encrypted_p7contentinfo))
{
if (!commonname)
commonname =
SEC_PKCS7GetSignerCommonName(encrypted_p7contentinfo);
if (!addr)
addr =
SEC_PKCS7GetSignerEmailAddress(encrypted_p7contentinfo);
}
PORT_Assert(!state->signername);
PORT_Assert(!state->signeraddr);
state->signername = PORT_Strdup((commonname && *commonname)
? commonname
: (addr ? addr : ""));
state->signeraddr = PORT_Strdup(addr ? addr : "");
if (commonname) PORT_Free(commonname);
if (addr) PORT_Free(addr);
commonname = 0;
addr = 0;
/* Describe the encryption algorithm used.
*/
if (encrypted_b)
{
if (encrypted_p7contentinfo &&
SEC_PKCS7ContentIsEncrypted(encrypted_p7contentinfo))
state->algorithmdesc =
sa_get_algorithm_string(encrypted_p7contentinfo);
if (!state->algorithmdesc &&
signed_p7contentinfo &&
SEC_PKCS7ContentIsEncrypted(signed_p7contentinfo))
state->algorithmdesc =
sa_get_algorithm_string(signed_p7contentinfo);
}
/* Decide which of the hokey signature-error-codes to pass to the
JavaScript code (in `var sa_sign_error').
*/
if (!signed_b)
sign_error = SIG_NOTSIGNED;
else if (verify_error == 0)
state->signerror = SIG_NOERR;
else if (verify_error == SEC_ERROR_PKCS7_BAD_SIGNATURE)
sign_error = SIG_TAMPERED;
else if (verify_error == SEC_ERROR_CERT_ADDR_MISMATCH)
sign_error = SIG_ADDR_MISMATCH;
else
{
sign_error = SIG_INVALID;
if (verify_error != -1)
state->signerrorstr = PORT_Strdup(XP_GetString(verify_error));
}
/* Decide which of the hokey encryption-error-codes to pass to the
JavaScript code (in `var sa_encrypt_errors').
*/
if (news_p)
{
/* If it's a news message, set the encryption bits based on the
SSL connection, rather than the message. */
int seclevel = XP_GetSecurityStatus((MWContext *)proto_win);
if (state->infocontext != SNEWS_MESSAGE ||
seclevel == SSL_SECURITY_STATUS_OFF ||
seclevel == SSL_SECURITY_STATUS_NOOPT)
encrypt_error = ENC_NOTSECURE;
else
encrypt_error = ENC_SECURE;
}
else if (!encrypted_b)
encrypt_error = ENC_NOTENCRYPTED;
else if (decode_error == 0)
encrypt_error = ENC_NOERR;
else if (decode_error == SEC_ERROR_NOT_A_RECIPIENT)
encrypt_error = ENC_FORANOTHER;
else
{
encrypt_error = ENC_UNKNOWN_ERROR;
if (decode_error != -1)
state->encrypterrorstr = PORT_Strdup(XP_GetString(decode_error));
}
state->signerror = sign_error;
state->encrypterrors = sa_push_js_int(state->encrypterrors,
NULL, encrypt_error, ")");
/* Figure out what signing-time to pass to the JavaScript.
*/
if (signed_p7contentinfo &&
SEC_PKCS7ContentIsSigned(signed_p7contentinfo))
{
SECItem *item = SEC_PKCS7GetSigningTime(signed_p7contentinfo);
state->signtime = (item ? DER_UTCTimeToAscii(item) : 0);
}
break;
}
#endif /* MOZ_LITE */
case NAVIGATOR: {
/* We still don't fully deal with all mixed cases. There's also no
* way to tell if java or js created the window, so we can't fill
* in nav_java, nav_js, or nav_creator_name.
*/
extern int NET_FindURLInCache(URL_Struct * URL_s, MWContext *ctxt);
Chrome chrome;
/* We have to call this to fill in the URL struct */
NET_FindURLInCache(url, (MWContext *)proto_win);
state->ssl_encrypted = url->security_on;
if (state->ssl_encrypted) {
state->server_cert = CERT_DupCertificate(url->certificate);
if (XP_GetSecurityStatus((MWContext *)proto_win) ==
SSL_SECURITY_STATUS_OFF) {
state->ssl_mixed = PR_TRUE;
}
}
#ifndef AKBAR
FE_QueryChrome((MWContext *)proto_win, &chrome);
state->nav_missing_menubar = !chrome.show_menu;
state->nav_missing_toolbar = !chrome.show_button_bar;
state->nav_missing_personalbar = !chrome.show_directory_buttons;
state->nav_missing_location = !chrome.show_url_bar;
state->nav_missing_status = !chrome.show_bottom_status_bar;
state->nav_chrome_missing = state->nav_missing_menubar ||
state->nav_missing_toolbar ||
state->nav_missing_personalbar ||
state->nav_missing_location ||
state->nav_missing_status;
#endif /* AKBAR */
state->nav_site_name = NET_ParseURL(url->address, GET_HOST_PART);
break;
}
case MAIL_THREADS:
case NEWS_THREADS:
break;
case NOINFO:
default:{
PORT_Assert(!state->encrypterrors);
state->encrypterrors = PORT_Strdup("sa_init_array(0)");
state->signerror = SIG_NOERR;
PORT_Assert(!state->destnames);
state->destnames = PORT_Strdup("sa_init_array(\"\")");
break;
}
}
if (sender) PORT_Free(sender);
if (mail_recipients) PORT_Free(mail_recipients);
if (news_recipients) PORT_Free(news_recipients);
return(SECSuccess);
}
SECStatus
getCryptoModuleStrings(SecurityAdvisorState *state)
{
/* free any strings hanging around */
SECMODModuleList *mlp;
SECMODModuleList *modules = SECMOD_GetDefaultModuleList();
SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
if ( state->crmodules ) {
PORT_Free(state->crmodules);
state->crmodules = NULL;
}
state->crmodules = PORT_Strdup("sa_init_array(");
SECMOD_GetReadLock(moduleLock);
for(mlp = modules; mlp != NULL; mlp = mlp->next) {
state->crmodules = sa_push_js_string(state->crmodules,
NULL,
mlp->module->commonName,
(mlp->next ? "," : ""));
}
SECMOD_ReleaseReadLock(moduleLock);
state->crmodules = PR_sprintf_append(state->crmodules, ")");
return(SECSuccess);
}
SECStatus
getJavaPrincipalStrings(SecurityAdvisorState *state)
{
char *java_principals = NULL;
/* free any strings hanging around */
if ( state->principals ) {
PORT_Free(state->principals);
state->principals = NULL;
}
#if defined(JAVA) && !defined(AKBAR)
java_principals = (char *)java_netscape_security_getPrincipals();
# endif /* JAVA && !AKBAR */
if (java_principals != NULL) {
/* java_principals string is already escaped in java. For example
* java_principals is "\\\"signtest\\\""
*/
state->principals =
PR_sprintf_append(state->principals, "sa_init_array(%s",
java_principals);
state->principals = PR_sprintf_append(state->principals, ")");
} else {
state->principals = PORT_Strdup("sa_init_array()");
}
return(SECSuccess);
}
SECStatus
setInfoContext(SecurityAdvisorState *state, void *context, URL_Struct *url)
{
if (((MWContext *)context)->type == MWContextMessageComposition) {
state->infocontext = COMPOSE;
} else if (!url || !url->address || !*url->address) {
state->infocontext = NOINFO;
} else {
/* Guess the content-type based on the URL. (Kinda bogus...) */
switch (NET_URL_Type(url->address)) {
case MAILBOX_TYPE_URL:
#ifdef IMAP_TYPE_URL
case IMAP_TYPE_URL:
#endif
state->infocontext = MAIL_MESSAGE;
break;
case NEWS_TYPE_URL:
if (url->address[0] == 's' || url->address[0] == 'S')
state->infocontext = SNEWS_MESSAGE;
else
state->infocontext = NEWS_MESSAGE;
break;
default:
state->infocontext = NAVIGATOR;
break;
}
#ifndef MOZ_LITE
/* If we didn't already guess that it's a mail or news message, then
* see if we can guess any better than that: if libmime gives us a
* cinfo, then it's definitely a message, regardless of what kind
* of URL it came from.
*/
if (state->infocontext == NAVIGATOR) {
SEC_PKCS7ContentInfo *encrypted_p7contentinfo = 0;
SEC_PKCS7ContentInfo *signed_p7contentinfo = 0;
int32 decode_error = 0, verify_error = 0;
MimeGetSecurityInfo((MWContext *)context,
url->address,
&encrypted_p7contentinfo,
&signed_p7contentinfo,
NULL, /* &sender_addr */
&decode_error, &verify_error);
if (encrypted_p7contentinfo || signed_p7contentinfo ||
decode_error || verify_error) {
state->infocontext = MAIL_MESSAGE;
if (encrypted_p7contentinfo)
SEC_PKCS7DestroyContentInfo(encrypted_p7contentinfo);
if (signed_p7contentinfo)
SEC_PKCS7DestroyContentInfo(signed_p7contentinfo);
}
}
#endif /* MOZ_LITE */
}
#if !defined(AKBAR) && !defined(MOZ_LITE)
if ((state->infocontext == NAVIGATOR) ||
(state->infocontext == NOINFO)) {
MSG_Pane *pane;
MSG_FolderInfo *folder;
MSG_NewsHost *host;
pane = MSG_FindPaneOfContext((MWContext *)context, MSG_THREADPANE);
if (pane != NULL) {
folder = MSG_GetThreadFolder(pane);
if (folder != NULL) {
host = MSG_GetNewsHostForFolder(folder);
if (host == NULL) {
state->infocontext = MAIL_THREADS;
} else {
state->infocontext = NEWS_THREADS;
if (MSG_IsNewsHostSecure(host) == PR_TRUE) {
state->ssl_encrypted = PR_TRUE;
} else {
state->ssl_encrypted = PR_FALSE;
}
}
}
}
}
#endif /* !AKBAR && !MOZ_LITE */
return(SECSuccess);
}
static void
freeSecurityAdvisorState(SecurityAdvisorState *state)
{
if ( state ) {
if ( state->mycerts ) {
PORT_Free(state->mycerts);
}
if ( state->mysslcerts ) {
PORT_Free(state->mysslcerts);
}
if ( state->mymailcerts ) {
PORT_Free(state->mymailcerts);
}
if ( state->peoplescerts ) {
PORT_Free(state->peoplescerts);
}
if ( state->sitecerts ) {
PORT_Free(state->sitecerts);
}
if ( state->cacerts ) {
PORT_Free(state->cacerts);
}
if ( state->sslcertname ) {
PORT_Free(state->sslcertname);
}
if ( state->mailcertname ) {
PORT_Free(state->mailcertname);
}
if ( state->crmodules ) {
PORT_Free(state->crmodules);
}
if ( state->principals ) {
PORT_Free(state->principals);
}
if ( state->encrypterrors ) {
PORT_Free(state->encrypterrors);
}
if (state->destnames) {
PORT_Free(state->destnames);
}
if ( state->nav_site_name ) {
PORT_Free(state->nav_site_name);
}
if ( state->nav_creator_name ) {
PORT_Free(state->nav_creator_name);
}
if ( state->server_cert ) {
CERT_DestroyCertificate(state->server_cert);
}
if (state->encrypted_p7contentinfo) {
SEC_PKCS7DestroyContentInfo(state->encrypted_p7contentinfo);
}
if (state->signed_p7contentinfo) {
SEC_PKCS7DestroyContentInfo(state->signed_p7contentinfo);
}
if (state->certs_to_fetch) {
PORT_Free(state->certs_to_fetch);
}
PORT_Free(state);
}
return;
}
extern void FE_SecurityOptionsChanged(MWContext *);
int
SECNAV_AskPrefToPK11(int asktype) {
switch (asktype) {
case 1:
return -1;
case 2:
return 1;
}
return 0;
}
static SECStatus
setSecurityPrefs(SecurityAdvisorState *state)
{
XP_Bool value;
int ret;
char *charvalue;
PK11SlotInfo *slot;
value = (XP_Bool)state->enablessl2;
ret = PREF_SetBoolPref("security.enable_ssl2", value);
SSL_EnableDefault(SSL_ENABLE_SSL2, value);
value = (XP_Bool)state->enablessl3;
ret = PREF_SetBoolPref("security.enable_ssl3", value);
SSL_EnableDefault(SSL_ENABLE_SSL3, value);
value = (XP_Bool)state->warnentersecure;
ret = PREF_SetBoolPref("security.warn_entering_secure", value);
value = (XP_Bool)state->warnleavesecure;
ret = PREF_SetBoolPref("security.warn_leaving_secure", value);
value = (XP_Bool)state->warnmixed;
ret = PREF_SetBoolPref("security.warn_viewing_mixed", value);
value = (XP_Bool)state->warnsendclear;
ret = PREF_SetBoolPref("security.warn_submit_insecure", value);
charvalue = state->sslcertname;
ret = PREF_SetCharPref("security.default_personal_cert", charvalue);
SECNAV_SetDefUserCertList(charvalue);
charvalue = state->mailcertname;
ret = PREF_SetCharPref("security.default_mail_cert", charvalue);
#ifdef AKBAR
/* We don't have PREF_RegisterCallback() in Akbar. */
SECNAV_MailCertPrefChange("security.default_mail_cert", charvalue);
#endif /* AKBAR */
ret = PREF_SetIntPref("security.ask_for_password",
(int32)state->pwasktype);
ret = PREF_SetIntPref("security.password_lifetime",
(int32)state->pwaskinterval);
slot = PK11_GetInternalKeySlot();
PK11_SetSlotPWValues(slot,SECNAV_AskPrefToPK11(state->pwasktype),
state->pwaskinterval);
PK11_FreeSlot(slot);
value = (XP_Bool)state->encryptalways;
ret = PREF_SetBoolPref("mail.encrypt_outgoing_mail", value);
value = (XP_Bool)state->signalways;
ret = PREF_SetBoolPref("mail.crypto_sign_outgoing_mail", value);
value = (XP_Bool)state->signnewsalways;
ret = PREF_SetBoolPref("mail.crypto_sign_outgoing_news", value);
#if 0
value = (XP_Bool)state->fwdwarning;
ret = PREF_SetBoolPref("mail.warn_forward_encrypted", value);
value = (XP_Bool)state->rewarning;
ret = PREF_SetBoolPref("mail.warn_reply_unencrypted", value);
#endif
ret = PREF_SavePrefFile();
#ifndef MOZ_LITE
#ifdef AKBAR
if ((XP_Bool)state->oldencryptthis != (XP_Bool)state->encryptthis)
MSG_Command(state->globalMWContext, MSG_SendEncrypted);
if ((XP_Bool)state->oldsignthis != (XP_Bool)state->signthis)
MSG_Command(state->globalMWContext, MSG_SendSigned);
#else /* !AKBAR */
if(state->oldencryptthis != state->encryptthis)
MSG_SetCompBoolHeader(MSG_FindPane(state->globalMWContext, MSG_COMPOSITIONPANE),
MSG_ENCRYPTED_BOOL_HEADER_MASK,
(XP_Bool)state->encryptthis);
if(state->oldsignthis != state->signthis)
MSG_SetCompBoolHeader(MSG_FindPane(state->globalMWContext, MSG_COMPOSITIONPANE),
MSG_SIGNED_BOOL_HEADER_MASK,
(XP_Bool)state->signthis);
#if defined(XP_MAC) || defined(XP_WIN) || defined(XP_UNIX) /* #### waiting for other FEs to catch up */
if(state->oldencryptthis != state->encryptthis ||
state->oldsignthis != state->signthis)
FE_SecurityOptionsChanged(state->globalMWContext);
#endif
#endif /* !AKBAR */
#endif /* MOZ_LITE */
return(SECSuccess);
}
static SECStatus
getSecurityPrefs(SecurityAdvisorState *state)
{
XP_Bool value;
int ret;
char *charvalue;
int32 intvalue;
ret = PREF_GetBoolPref("security.enable_ssl2", &value);
state->enablessl2 = (PRBool)value;
ret = PREF_GetBoolPref("security.enable_ssl3", &value);
state->enablessl3 = (PRBool)value;
ret = PREF_GetBoolPref("security.warn_entering_secure", &value);
state->warnentersecure = (PRBool)value;
ret = PREF_GetBoolPref("security.warn_leaving_secure", &value);
state->warnleavesecure = (PRBool)value;
ret = PREF_GetBoolPref("security.warn_viewing_mixed", &value);
state->warnmixed = (PRBool)value;
ret = PREF_GetBoolPref("security.warn_submit_insecure", &value);
state->warnsendclear = (PRBool)value;
ret = PREF_CopyCharPref("security.default_personal_cert", &charvalue);
state->sslcertname = charvalue;
ret = PREF_CopyCharPref("security.default_mail_cert", &charvalue);
#ifdef AKBAR
/* We don't have PREF_RegisterCallback() in Akbar. */
SECNAV_MailCertPrefChange("security.default_mail_cert", charvalue);
#endif /* AKBAR */
state->mailcertname = charvalue;
ret = PREF_GetIntPref("security.ask_for_password", &intvalue);
state->pwasktype = intvalue;
state->passwordset = !PK11_NeedPWInit();
ret = PREF_GetIntPref("security.password_lifetime", &intvalue);
state->pwaskinterval = intvalue;
ret = PREF_GetBoolPref("mail.encrypt_outgoing_mail", &value);
state->encryptalways = (PRBool)value;
ret = PREF_GetBoolPref("mail.crypto_sign_outgoing_mail", &value);
state->signalways = (PRBool)value;
ret = PREF_GetBoolPref("mail.crypto_sign_outgoing_news", &value);
state->signnewsalways = (PRBool)value;
#if 0
ret = PREF_GetBoolPref("mail.warn_forward_encrypted", &value);
state->fwdwarning = (PRBool)value;
ret = PREF_GetBoolPref("mail.warn_reply_unencrypted", &value);
state->rewarning = (PRBool)value;
#endif /* 0 */
return(SECSuccess);
}
static SecurityAdvisorState *
getSecurityAdvisorState(CERTCertDBHandle *handle,void *proto_win, URL_Struct *url)
{
SECStatus rv;
SecurityAdvisorState *state;
state = (SecurityAdvisorState *)PORT_ZAlloc(sizeof(SecurityAdvisorState));
if ( state == NULL ) {
goto loser;
}
state->handle = handle;
state->curpage = 1;
state->url = url;
state->proto_win = proto_win;
rv = setInfoContext(state, proto_win, url);
if ( rv != SECSuccess ) {
goto loser;
}
rv = getSecurityPrefs(state);
if ( rv != SECSuccess ) {
goto loser;
}
rv = getCertVarStrings(state,proto_win);
if ( rv != SECSuccess ) {
goto loser;
}
rv = getCryptoModuleStrings(state);
if ( rv != SECSuccess ) {
goto loser;
}
rv = getJavaPrincipalStrings(state);
if ( rv != SECSuccess ) {
goto loser;
}
rv = getStatusValues(state, proto_win, url);
if (rv != SECSuccess) {
goto loser;
}
return(state);
loser:
freeSecurityAdvisorState(state);
return(NULL);
}
static void
collectAdvisorState(SecurityAdvisorState *state, char **argv, int argc)
{
char *tmpstr;
tmpstr = XP_FindValueInArgs("submit_current_page", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
state->curpage = PORT_Atoi(tmpstr);
}
tmpstr = XP_FindValueInArgs("submit_ssl_cert", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
if (state->sslcertname) PORT_Free(state->sslcertname);
state->sslcertname = PORT_Strdup(tmpstr);
}
tmpstr = XP_FindValueInArgs("submit_mail_cert", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
if (state->mailcertname) PORT_Free(state->mailcertname);
state->mailcertname = PORT_Strdup(tmpstr);
}
tmpstr = XP_FindValueInArgs("submit_enter", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
state->warnentersecure = ( 't' == tmpstr[0] );
}
tmpstr = XP_FindValueInArgs("submit_leave", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
state->warnleavesecure = ( 't' == tmpstr[0] );
}
tmpstr = XP_FindValueInArgs("submit_mixed", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
state->warnmixed = ( 't' == tmpstr[0] );
}
tmpstr = XP_FindValueInArgs("submit_send", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
state->warnsendclear = ( 't' == tmpstr[0] );
}
tmpstr = XP_FindValueInArgs("submit_ssl2", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
state->enablessl2 = ( 't' == tmpstr[0] );
}
tmpstr = XP_FindValueInArgs("submit_ssl3", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
state->enablessl3 = ( 't' == tmpstr[0] );
}
tmpstr = XP_FindValueInArgs("submit_password_ask_type", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
state->pwasktype = PORT_Atoi(tmpstr);
}
tmpstr = XP_FindValueInArgs("submit_password_ask_interval", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
state->pwaskinterval = PORT_Atoi(tmpstr);
}
tmpstr = XP_FindValueInArgs("submit_encrypt_always", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
state->encryptalways = ( 't' == tmpstr[0] );
}
tmpstr = XP_FindValueInArgs("submit_sign_mail_always", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
state->signalways = ( 't' == tmpstr[0] );
}
tmpstr = XP_FindValueInArgs("submit_sign_news_always", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
state->signnewsalways = ( 't' == tmpstr[0] );
}
tmpstr = XP_FindValueInArgs("submit_encrypt_this", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
state->encryptthis = ( 't' == tmpstr[0] );
}
tmpstr = XP_FindValueInArgs("submit_sign_this", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
state->signthis = ( 't' == tmpstr[0] );
}
#if 0
tmpstr = XP_FindValueInArgs("submit_fwd_warning", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
state->fwdwarning = ( 't' == tmpstr[0] );
}
tmpstr = XP_FindValueInArgs("submit_re_warning", argv, argc);
XP_ASSERT(tmpstr);
if ( tmpstr ) {
state->rewarning = ( 't' == tmpstr[0] );
}
#endif /* 0 */
return;
}
typedef struct {
SecurityAdvisorState *state;
XPDialogState *dlgstate;
} DeleteCallbackArg;
static void
redrawCallback(void *arg)
{
SECStatus rv;
DeleteCallbackArg *cbarg = (DeleteCallbackArg *)arg;
int ret;
XPDialogStrings *strings = NULL;
/* update the certificate strings */
rv = getCertVarStrings(cbarg->state,cbarg->dlgstate->window);
if ( rv != SECSuccess ) {
goto loser;
}
/* update the security module strings */
rv = getCryptoModuleStrings(cbarg->state);
if ( rv != SECSuccess ) {
goto loser;
}
/* Update the java principals strings */
rv = getJavaPrincipalStrings(cbarg->state);
if ( rv != SECSuccess ) {
goto loser;
}
rv = getStatusValues(cbarg->state, cbarg->state->proto_win,
cbarg->state->url);
if (rv != SECSuccess) {
goto loser;
}
/* make the dialog strings */
strings = getAdvisorStrings(cbarg->state);
/* redraw the dialog */
ret = XP_RedrawRawHTMLDialog(cbarg->dlgstate, strings, 1);
loser:
if ( strings ) {
XP_FreeDialogStrings(strings);
}
PORT_Free(arg);
return;
}
void
SECNAV_AdvisorRedraw(void *arg) {
redrawCallback(arg);
return;
}
static PRBool
securityAdvisorHandler(XPDialogState *dlgstate, char **argv, int argc,
unsigned int button)
{
SecurityAdvisorState *state;
SECStatus rv;
char *buttonString;
char *tmpstring;
char *certname;
char *moduleName;
CERTCertificate *cert;
PRBool sitepage;
state = (SecurityAdvisorState *)dlgstate->arg;
collectAdvisorState(state, argv, argc);
if ( button == 0 ) {
tmpstring = XP_FindValueInArgs("submit_current_page", argv, argc);
XP_ASSERT(tmpstring);
if ( tmpstring == NULL ) {
goto loser;
}
state->curpage = PORT_Atoi(tmpstring);
buttonString = XP_FindValueInArgs("button", argv, argc);
XP_ASSERT(buttonString);
if ( buttonString != NULL ) {
certname = XP_FindValueInArgs("certs", argv, argc);
sitepage = PR_FALSE;
switch ( state->curpage ) {
case 1: /* secinfo_page */
if ((PORT_Strcasecmp(buttonString,
XP_GetString(SA_VIEW_BUTTON_LABEL)) == 0) ||
(PORT_Strcasecmp(buttonString,
XP_GetString(SA_VIEW_CERT_BUTTON_LABEL)) == 0)) {
if (state->infocontext == NAVIGATOR) {
cert = state->server_cert;
if (cert) {
SECNAV_DisplayCertDialog(dlgstate->window, cert);
}
} else if (state->signed_p7contentinfo ||
state->encrypted_p7contentinfo) {
SEC_PKCS7SignerInfo **signerinfos;
SEC_PKCS7ContentInfo *ci = state->signed_p7contentinfo;
XP_ASSERT(ci);
if (!ci) ci = state->encrypted_p7contentinfo;
/* 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 */
if (cert) {
SECNAV_DisplayCertDialog(dlgstate->window,cert);
}
}
} else if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_GET_CERT_BUTTON_LABEL)) == 0){
SECNAV_NewUserCertificate((MWContext *)dlgstate->proto_win);
} else if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_PAGE_INFO_LABEL)) == 0){
FE_GetURL((MWContext *)dlgstate->proto_win,
NET_CreateURLStruct("about:document",
NET_DONT_RELOAD));
#ifndef MOZ_LITE
} else if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_GET_CERTS_BUTTON_LABEL)) == 0){
#ifndef AKBAR
DeleteCallbackArg *cbarg;
cbarg = (DeleteCallbackArg *)
PORT_Alloc(sizeof(DeleteCallbackArg));
if ( cbarg ) {
cbarg->dlgstate = dlgstate;
cbarg->state = state;
SECNAV_SearchLDAPDialog(dlgstate->window,
SECNAV_MakeDeleteCertCB(redrawCallback, (void *)cbarg),
state->certs_to_fetch);
}
#endif /* !AKBAR */
#endif /* MOZ_LITE */
}
break; /* Info panel */
case 7: /* your_certs_page */
if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_VIEW_BUTTON_LABEL)) == 0 ) {
/* bring up the viewing window */
if ( certname ) {
rv = SECNAV_SelectCert(CERT_GetDefaultCertDB(),
certname,
XP_CERT_SELECT_VIEW_STRING,
dlgstate->window,
SECNAV_ViewUserCertificate,
NULL);
}
} else if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_VERIFY_BUTTON_LABEL)) == 0){
if ( certname ) {
rv = SECNAV_SelectCert(CERT_GetDefaultCertDB(),
certname,
XP_CERT_SELECT_VERIFY_STRING,
dlgstate->window,
SECNAV_VerifyCertificate,
(void *)certUsageEmailRecipient);
}
} else if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_DELETE_BUTTON_LABEL)) == 0){
if ( certname ) {
DeleteCallbackArg *cbarg;
cbarg = (DeleteCallbackArg *)
PORT_Alloc(sizeof(DeleteCallbackArg));
if ( cbarg ) {
cbarg->dlgstate = dlgstate;
cbarg->state = state;
rv = SECNAV_SelectCert(CERT_GetDefaultCertDB(),
certname,
XP_CERT_SELECT_DEL_STRING,
dlgstate->window,
SECNAV_DeleteUserCertificate,
SECNAV_MakeDeleteCertCB(redrawCallback, (void *)cbarg));
}
}
} else if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_EXPORT_BUTTON_LABEL)) == 0){
if(certname)
{
rv = SECNAV_SelectCert(CERT_GetDefaultCertDB(),
certname,
XP_CERT_SELECT_VIEW_STRING,
dlgstate->window,
SECNAV_ExportPKCS12Object,
(void *)certname);
}
} else if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_GET_CERT_BUTTON_LABEL)) == 0){
SECNAV_NewUserCertificate((MWContext *)dlgstate->proto_win);
} else if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_IMPORT_BUTTON_LABEL)) == 0){
SECNAVPKCS12ImportArg *p12imp_arg;
p12imp_arg = (SECNAVPKCS12ImportArg *)PORT_ZAlloc(
sizeof(SECNAVPKCS12ImportArg));
if(p12imp_arg) {
p12imp_arg->redrawCallback = (void *)redrawCallback;
p12imp_arg->sa_state = state;
p12imp_arg->dlg_state = dlgstate;
p12imp_arg->proto_win = dlgstate->window;
p12imp_arg->slot_ptr = PK11_GetInternalKeySlot();
if(PK11_NeedLogin((PK11SlotInfo *)p12imp_arg->slot_ptr) &&
PK11_NeedUserInit((PK11SlotInfo *)p12imp_arg->slot_ptr)) {
/* bring up the set password window */
SECNAV_MakePWSetupDialog(dlgstate->window, NULL,
SECNAV_ImportPKCS12Object,
(PK11SlotInfo *)p12imp_arg->slot_ptr,
p12imp_arg);
break;
} else {
SECNAV_ImportPKCS12Object(p12imp_arg, PR_FALSE);
}
} else {
FE_Alert(dlgstate->window,
XP_GetString(SEC_ERROR_NO_MEMORY));
}
}
break;
case 8: /* people_certs_page */
if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_VIEW_BUTTON_LABEL)) == 0 ) {
/* bring up the viewing window */
if ( certname ) {
rv = SECNAV_SelectCert(CERT_GetDefaultCertDB(),
certname,
XP_CERT_SELECT_VIEW_STRING,
dlgstate->window,
SECNAV_ViewUserCertificate,
NULL);
}
} else if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_VERIFY_BUTTON_LABEL)) == 0){
if ( certname ) {
rv = SECNAV_SelectCert(CERT_GetDefaultCertDB(),
certname,
XP_CERT_SELECT_VERIFY_STRING,
dlgstate->window,
SECNAV_VerifyCertificate,
(void *)certUsageEmailRecipient);
}
} else if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_DELETE_BUTTON_LABEL)) == 0){
if ( certname ) {
DeleteCallbackArg *cbarg;
cbarg = (DeleteCallbackArg *)
PORT_Alloc(sizeof(DeleteCallbackArg));
if ( cbarg ) {
cbarg->dlgstate = dlgstate;
cbarg->state = state;
rv = SECNAV_SelectCert(CERT_GetDefaultCertDB(),
certname,
XP_CERT_SELECT_DEL_STRING,
dlgstate->window,
SECNAV_DeleteEmailCertificate,
SECNAV_MakeDeleteCertCB(redrawCallback, (void *)cbarg));
}
}
#ifndef MOZ_LITE
} else if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_SEARCH_DIR_BUTTON_LABEL)) == 0){
#ifndef AKBAR
DeleteCallbackArg *cbarg;
cbarg = (DeleteCallbackArg *)
PORT_Alloc(sizeof(DeleteCallbackArg));
if ( cbarg ) {
cbarg->dlgstate = dlgstate;
cbarg->state = state;
SECNAV_SearchLDAPDialog(dlgstate->window,
SECNAV_MakeDeleteCertCB(redrawCallback, (void *)cbarg), NULL);
}
#endif /* !AKBAR */
#endif /* MOZ_LITE */
}
break;
case 9: /* site_certs_page */
sitepage = PR_TRUE;
case 10: /* signers_certs_page */
if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_EDIT_BUTTON_LABEL)) == 0 ) {
/* bring up the edit window */
if ( certname ) {
rv = SECNAV_SelectCert(CERT_GetDefaultCertDB(),
certname,
XP_CERT_SELECT_EDIT_STRING,
dlgstate->window,
SECNAV_EditSiteCertificate,
NULL);
}
} else if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_VERIFY_BUTTON_LABEL)) == 0){
if ( certname ) {
rv = SECNAV_SelectCert(CERT_GetDefaultCertDB(),
certname,
XP_CERT_SELECT_VERIFY_STRING,
dlgstate->window,
SECNAV_VerifyCertificate,
sitepage ?
(void *)certUsageSSLServer :
(void *)certUsageVerifyCA);
}
} else if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_DELETE_BUTTON_LABEL)) == 0){
if ( certname ) {
DeleteCallbackArg *cbarg;
cbarg = (DeleteCallbackArg *)
PORT_Alloc(sizeof(DeleteCallbackArg));
if ( cbarg ) {
cbarg->dlgstate = dlgstate;
cbarg->state = state;
rv = SECNAV_SelectCert(CERT_GetDefaultCertDB(),
certname,
XP_CERT_SELECT_DEL_STRING,
dlgstate->window,
SECNAV_DeleteSiteCertificate,
SECNAV_MakeDeleteCertCB(redrawCallback, (void *)cbarg));
}
}
}
break;
case 3: /* navigator_page */
if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_SSL2_CONFIG_LABEL)) == 0 ) {
SECNAV_MakeCiphersDialog(dlgstate->window,
SSL_LIBRARY_VERSION_2);
} else if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_SSL3_CONFIG_LABEL)) == 0 ) {
SECNAV_MakeCiphersDialog(dlgstate->window,
SSL_LIBRARY_VERSION_3_0);
}
break;
#ifndef MOZ_LITE
case 4: /* messenger_page */
if (!PORT_Strcasecmp(buttonString,
XP_GetString(SA_SMIME_CONFIG_LABEL))) {
SECNAV_MakeCiphersDialog(dlgstate->window,
SMIME_LIBRARY_VERSION_1_0);
} else if (!PORT_Strcasecmp(buttonString,
XP_GetString(SA_SEND_CERT_BUTTON_LABEL))) {
#ifndef AKBAR
SECNAV_PublishSMimeCertDialog(dlgstate->window);
#endif /* !AKBAR */
}
break;
#endif /* MOZ_LITE */
case 5: /* applet_certs_page */
if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_VIEW_CERT_BUTTON_LABEL)) == 0 ) {
/* bring up the viewing window */
if ( certname ) {
SECStatus rv = SECNAV_IsJavaPrinCert(dlgstate->window,
certname);
if (rv == SECSuccess) {
rv = SECNAV_SelectCert(CERT_GetDefaultCertDB(),
certname,
XP_CERT_SELECT_VIEW_STRING,
dlgstate->window,
SECNAV_ViewUserCertificate,
NULL);
}
}
} else if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_EDIT_PRIVS_BUTTON_LABEL)) == 0) {
/* bring up the edit window */
if ( certname ) {
SECNAV_EditJavaPrivileges(dlgstate->window, certname);
}
} else if ( PORT_Strcasecmp(buttonString,
XP_GetString(SA_REMOVE_BUTTON_LABEL)) == 0) {
if ( certname ) {
DeleteCallbackArg *cbarg;
cbarg = (DeleteCallbackArg *)
PORT_Alloc(sizeof(DeleteCallbackArg));
if ( cbarg ) {
cbarg->dlgstate = dlgstate;
cbarg->state = state;
SECNAV_DeleteJavaPrincipal(dlgstate->window,
certname,
redrawCallback,
(void *)cbarg);
}
}
}
break;
case 2: /* passwords_page */
if (( PORT_Strcasecmp(buttonString, XP_GetString(SA_SET_PASSWORD_LABEL)) == 0 ) ||
( PORT_Strcasecmp(buttonString, XP_GetString(SA_CHANGE_PASSWORD_LABEL)) == 0)) {
if (PK11_NeedPWInit()) {
/* bring up the set password window */
SECNAV_MakePWSetupDialog(dlgstate->window, NULL, NULL,
PK11_GetInternalKeySlot(),
NULL);
} else {
/* bring up the change password window */
SECNAV_MakePWChangeDialog(dlgstate->window,
PK11_GetInternalKeySlot());
}
}
break;
case 11: /* modules_page */
moduleName = XP_FindValueInArgs("sa_cr_modules", argv, argc);
if (PORT_Strcasecmp(buttonString, XP_GetString(SA_VIEW_EDIT_BUTTON_LABEL)) == 0 ) {
SECNAV_EditModule(dlgstate->window,moduleName);
} else if (PORT_Strcasecmp(buttonString, XP_GetString(SA_ADD_BUTTON_LABEL)) == 0 ) {
DeleteCallbackArg *cbarg;
cbarg = (DeleteCallbackArg *)
PORT_Alloc(sizeof(DeleteCallbackArg));
if ( cbarg ) {
cbarg->dlgstate = dlgstate;
cbarg->state = state;
SECNAV_NewSecurityModule(dlgstate->window,
redrawCallback,
(void *)cbarg);
}
} else if (PORT_Strcasecmp(buttonString,
XP_GetString(SA_DELETE_BUTTON_LABEL)) == 0 ) {
if ( moduleName ) {
DeleteCallbackArg *cbarg;
cbarg = (DeleteCallbackArg *)
PORT_Alloc(sizeof(DeleteCallbackArg));
if ( cbarg ) {
cbarg->dlgstate = dlgstate;
cbarg->state = state;
SECNAV_DeleteSecurityModule(dlgstate->window,
moduleName,
redrawCallback,
(void *)cbarg);
}
}
} else if (PORT_Strcasecmp(buttonString,
XP_GetString(SA_LOGOUT_ALL_BUTTON_LABEL)) == 0 ) {
SECNAV_LogoutAllSecurityModules(dlgstate->window);
}
break;
}
}
return(PR_TRUE);
}
/* OK, Cancel, or Help button */
switch ( button ) {
case XP_DIALOG_OK_BUTTON:
rv = setSecurityPrefs(state);
break;
case XP_DIALOG_CANCEL_BUTTON:
break;
}
goto done;
loser:
freeSecurityAdvisorState(state);
return(PR_TRUE);
done:
freeSecurityAdvisorState(state);
return(PR_FALSE);
}
static XPDialogInfo advisorDialog = {
0,
securityAdvisorHandler,
#ifdef AKBAR
640, 480
#else /* !AKBAR */
0, 0
#endif /* !AKBAR */
};
void
SECNAV_SecurityAdvisor(void *proto_win, URL_Struct *url)
{
XPDialogStrings *strings;
SecurityAdvisorState *state;
#ifndef AKBAR
int32 width, height;
#endif /* !AKBAR */
int status;
status = init_sa_strings();
if (status < 0) return; /* #### */
state = getSecurityAdvisorState(CERT_GetDefaultCertDB(),proto_win, url);
if ( state == NULL ) {
return;
}
#if defined(DEBUG_dhugo)
if (url) {
XP_Trace("Advisor passed url: %s",url->address);
} else {
XP_Trace("Advisor passed url: NULL");
}
#endif
state->globalMWContext = (MWContext *)proto_win;
/* generate the advisor strings */
strings = getAdvisorStrings(state);
#ifndef AKBAR
/* try to make the advisor a reasonable size if we have a big screen */
if ( advisorDialog.width == 0 ) {
FE_GetScreenSize((MWContext *)proto_win, &width, &height);
width = ( ( width * 3 ) >> 2 );
height = ( ( height * 3 ) >> 2 );
if ( width < 640 ) {
width = 640;
} else if ( width > 800 ) {
width = 800;
}
if ( height < 400 ) {
height = 400;
} else if ( height > 600 ) {
height = 600;
}
advisorDialog.width = width;
advisorDialog.height = height;
}
#endif /* !AKBAR */
/* put up the dialog */
XP_MakeRawHTMLDialog(proto_win, &advisorDialog,
XP_SECURITY_ADVISOR_TITLE_STRING,
strings, 1, (void *)state);
XP_FreeDialogStrings(strings);
return;
}