Expose the subject name for the cert and an nsISupports pointer to the cert on

nsIPrincipal that represents a certificate principal.  Change preference
storage to ensure matches in not only the fingerprint but also the subjectName
before applying privileges from preferences to a certificate principal.  Remove
possibility for creating certificate principals without a useful identifying
name and make sure that names don't get munged by being forced to ASCII.  Bug
240661, r=caillon, sr=dveditz, a=bsmedberg
This commit is contained in:
bzbarsky%mit.edu 2005-07-22 19:05:42 +00:00
Родитель 1dd3bccfda
Коммит dc27182f65
14 изменённых файлов: 439 добавлений и 151 удалений

Просмотреть файл

@ -51,7 +51,7 @@ interface nsIURI;
[ptr] native JSContext(JSContext);
[ptr] native JSPrincipals(JSPrincipals);
[uuid(a67c4736-9a95-4ce1-9ffc-3f88c0913a34)]
[uuid(fb9ddeb9-26f9-46b8-85d5-3978aaee05aa)]
interface nsIPrincipal : nsISerializable
{
/**
@ -68,17 +68,19 @@ interface nsIPrincipal : nsISerializable
* Returns the security preferences associated with this principal.
* prefBranch will be set to the pref branch to which these preferences
* pertain. id is a pseudo-unique identifier, pertaining to either the
* certificateID or the origin. grantedList and deniedList are
* space-separated lists of capabilities which were explicitly granted
* or denied by a pref.
* fingerprint or the origin. subjectName is a name that identifies the
* entity this principal represents (may be empty). grantedList and
* deniedList are space-separated lists of capabilities which were
* explicitly granted or denied by a pref.
*/
void getPreferences(out string prefBranch, out string id,
out string subjectName,
out string grantedList, out string deniedList);
/**
* Returns whether the other principal is equivalent to this principal.
* Principals are considered equal if they are the same principal,
* they have the same origin, or have the same certificate ID
* they have the same origin, or have the same certificate fingerprint ID
*/
boolean equals(in nsIPrincipal other);
@ -99,9 +101,18 @@ interface nsIPrincipal : nsISerializable
// XXXcaa should this be here? The script security manager is the only
// thing that should care about this. Wouldn't storing this data in one
// of the hashtables in nsScriptSecurityManager be better?
// XXXbz why is this writable? Who should have write access to this? What
// happens if this principal is in our hashtable and we pass it out of the
// security manager and someone writes to this field? Especially if they
// write garbage? If we need to give someone other than the security
// manager a way to set this (which I question, since it can increase the
// permissions of a page) it should be a |void clearSecurityPolicy()|
// method.
attribute voidPtr securityPolicy;
// XXXcaa probably should be turned into {get|set}CapabilityFlags
// XXXbz again, what if this lives in our hashtable and someone
// messes with it? Is that OK?
short canEnableCapability(in string capability);
void setCanEnableCapability(in string capability, in short canEnable);
boolean isCapabilityEnabled(in string capability, in voidPtr annotation);
@ -143,14 +154,18 @@ interface nsIPrincipal : nsISerializable
*/
// XXXcaa kaie says this may not be unique. We should probably
// consider using something else for this....
readonly attribute string certificateID;
readonly attribute AUTF8String fingerprint;
/**
* The common name for the certificate.
* This pertains to the certificate authority organization.
* The pretty name for the certificate. This sort of (but not really)
* identifies the subject of the certificate (the entity that stands behind
* the certificate). Note that this may be empty; prefer to get the
* certificate itself and get this information from it, since that may
* provide more information.
*
* Throws if there is no certificate associated with this principal.
*/
attribute string commonName;
readonly attribute AUTF8String prettyName;
/**
* Returns whether the other principal is equal to or weaker than this
@ -171,4 +186,21 @@ interface nsIPrincipal : nsISerializable
* release; note that nsIPrincipal is unfrozen, not slated to be frozen.
*/
boolean subsumes(in nsIPrincipal other);
/**
* The subject name for the certificate. This actually identifies the
* subject of the certificate. This may well not be a string that would
* mean much to a typical user on its own (e.g. it may have a number of
* different names all concatenated together with some information on what
* they mean in between).
*
* Throws if there is no certificate associated with this principal.
*/
readonly attribute AUTF8String subjectName;
/**
* The certificate associated with this principal, if any. If there isn't
* one, this will return null. Getting this attribute never throws.
*/
readonly attribute nsISupports certificate;
};

Просмотреть файл

@ -41,7 +41,7 @@
interface nsIURI;
[scriptable, uuid(463eb1fa-9dac-4ca7-826f-1fc921971d3a)]
[scriptable, uuid(f4d74511-2b2d-4a14-a3e4-a392ac5ac3ff)]
interface nsIScriptSecurityManager : nsIXPCSecurityManager
{
///////////////// Security Checks //////////////////
@ -161,9 +161,19 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
[noscript] nsIPrincipal getSystemPrincipal();
/**
* Return a principal with the specified certificate ID and codebase URI.
* Return a principal with the specified certificate fingerprint, subject
* name (the full name or concatenated set of names of the entity
* represented by the certificate), pretty name, certificate, and
* codebase URI. The certificate fingerprint and subject name MUST be
* nonempty; otherwise an error will be thrown. Similarly, aCert must
* not be null.
*/
[noscript] nsIPrincipal getCertificatePrincipal(in string CertID, in nsIURI aURI);
[noscript] nsIPrincipal
getCertificatePrincipal(in AUTF8String aCertFingerprint,
in AUTF8String aSubjectName,
in AUTF8String aPrettyName,
in nsISupports aCert,
in nsIURI aURI);
/**
* Return a principal that has the same origin as aURI.
@ -209,7 +219,11 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
* Allow 'certificateID' to enable 'capability.' Can only be performed
* by code signed by the system certificate.
*/
void setCanEnableCapability(in string certificateID, in string capability,
// XXXbz Capabilities can't have non-ascii chars?
// XXXbz ideally we'd pass a subjectName here too, and the nsISupports
// cert we're enabling for...
void setCanEnableCapability(in AUTF8String certificateFingerprint,
in string capability,
in short canEnable);
///////////////////////

Просмотреть файл

@ -68,14 +68,28 @@ public:
// Either Init() or InitFromPersistent() must be called before
// the principal is in a usable state.
nsresult Init(const char *aCertID, nsIURI *aCodebase);
nsresult Init(const nsACString& aCertFingerprint,
const nsACString& aSubjectName,
const nsACString& aPrettyName,
nsISupports* aCert,
nsIURI *aCodebase);
nsresult InitFromPersistent(const char* aPrefName,
const char* aToken,
const nsCString& aFingerprint,
const nsCString& aSubjectName,
const nsACString& aPrettyName,
const char* aGrantedList,
const char* aDeniedList,
nsISupports* aCert,
PRBool aIsCert,
PRBool aTrusted);
// Call this to ensure that this principal has a subject name, a pretty name,
// and a cert pointer. This method will throw if there is already a
// different subject name or if this principal has no certificate.
nsresult EnsureCertData(const nsACString& aSubjectName,
const nsACString& aPrettyName,
nsISupports* aCert);
enum AnnotationValue { AnnotationEnabled=1, AnnotationDisabled };
void SetURI(nsIURI *aURI);
@ -96,16 +110,24 @@ protected:
// that we can use yet.
struct Certificate
{
Certificate(const char* aCertID, const char* aName)
: certificateID(aCertID),
commonName(aName)
Certificate(const nsACString& aFingerprint, const nsACString& aSubjectName,
const nsACString& aPrettyName, nsISupports* aCert)
: fingerprint(aFingerprint),
subjectName(aSubjectName),
prettyName(aPrettyName),
cert(aCert)
{
};
nsCString certificateID;
nsCString commonName;
nsCString fingerprint;
nsCString subjectName;
nsCString prettyName;
nsCOMPtr<nsISupports> cert;
};
nsresult SetCertificate(const char* aCertID, const char* aName);
nsresult SetCertificate(const nsACString& aFingerprint,
const nsACString& aSubjectName,
const nsACString& aPrettyName,
nsISupports* aCert);
// Keep this is a pointer, even though it may slightly increase the
// cost of keeping a certificate, this is a good tradeoff though since

Просмотреть файл

@ -429,6 +429,18 @@ private:
nsresult
CreateCodebasePrincipal(nsIURI* aURI, nsIPrincipal** result);
// This is just like the API method, but it doesn't check that the subject
// name is nonempty or aCertificate is non-null, and it doesn't change the
// certificate in the table (if any) in any way if aModifyTable is false.
nsresult
DoGetCertificatePrincipal(const nsACString& aCertFingerprint,
const nsACString& aSubjectName,
const nsACString& aPrettyName,
nsISupports* aCertificate,
nsIURI* aURI,
PRBool aModifyTable,
nsIPrincipal **result);
// Returns null if a principal cannot be found. Note that rv can be NS_OK
// when this happens -- this means that there was no script for the
// context. Callers MUST pass in a non-null rv here.
@ -486,7 +498,10 @@ private:
InitPrefs();
static nsresult
PrincipalPrefNames(const char* pref, char** grantedPref, char** deniedPref);
GetPrincipalPrefNames(const char* prefBase,
nsCString& grantedPref,
nsCString& deniedPref,
nsCString& subjectNamePref);
nsresult
InitPolicies();

Просмотреть файл

@ -100,20 +100,24 @@ nsPrincipal::nsPrincipal()
}
nsresult
nsPrincipal::Init(const char *aCertID, nsIURI *aCodebase)
nsPrincipal::Init(const nsACString& aCertFingerprint,
const nsACString& aSubjectName,
const nsACString& aPrettyName,
nsISupports* aCert,
nsIURI *aCodebase)
{
NS_ENSURE_STATE(!mInitialized);
NS_ENSURE_ARG_POINTER(aCertID || aCodebase); // better have one of these.
NS_ENSURE_ARG(!aCertFingerprint.IsEmpty() || aCodebase); // better have one of these.
mInitialized = PR_TRUE;
mCodebase = aCodebase;
nsresult rv;
if (aCertID) {
rv = SetCertificate(aCertID, nsnull);
if (!aCertFingerprint.IsEmpty()) {
rv = SetCertificate(aCertFingerprint, aSubjectName, aPrettyName, aCert);
if (NS_SUCCEEDED(rv)) {
rv = mJSPrincipals.Init(this, aCertID);
rv = mJSPrincipals.Init(this, mCert->fingerprint.get());
}
}
else {
@ -238,9 +242,19 @@ nsPrincipal::Equals(nsIPrincipal *aOther, PRBool *aResult)
return NS_OK;
}
nsXPIDLCString otherCertID;
aOther->GetCertificateID(getter_Copies(otherCertID));
*aResult = otherCertID.Equals(mCert->certificateID);
nsCAutoString str;
aOther->GetFingerprint(str);
*aResult = str.Equals(mCert->fingerprint);
// If either subject name is empty, just let the result stand (so that
// nsScriptSecurityManager::SetCanEnableCapability works), but if they're
// both nonempty, only claim equality if they're equal.
if (*aResult && !mCert->subjectName.IsEmpty()) {
// Check the other principal's subject name
aOther->GetSubjectName(str);
*aResult = str.Equals(mCert->subjectName) || str.IsEmpty();
}
return NS_OK;
}
@ -489,15 +503,18 @@ nsPrincipal::SetURI(nsIURI* aURI)
nsresult
nsPrincipal::SetCertificate(const char* aID, const char* aName)
nsPrincipal::SetCertificate(const nsACString& aFingerprint,
const nsACString& aSubjectName,
const nsACString& aPrettyName,
nsISupports* aCert)
{
NS_ENSURE_STATE(!mCert);
if (!aID && !aName) {
return NS_ERROR_INVALID_POINTER;
if (aFingerprint.IsEmpty()) {
return NS_ERROR_INVALID_ARG;
}
mCert = new Certificate(aID, aName);
mCert = new Certificate(aFingerprint, aSubjectName, aPrettyName, aCert);
if (!mCert) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -506,44 +523,46 @@ nsPrincipal::SetCertificate(const char* aID, const char* aName)
}
NS_IMETHODIMP
nsPrincipal::GetCertificateID(char** aID)
nsPrincipal::GetFingerprint(nsACString& aFingerprint)
{
NS_ENSURE_STATE(mCert);
*aID = ToNewCString(mCert->certificateID);
if (!*aID) {
return NS_ERROR_OUT_OF_MEMORY;
}
aFingerprint = mCert->fingerprint;
return NS_OK;
}
NS_IMETHODIMP
nsPrincipal::GetCommonName(char** aName)
nsPrincipal::GetPrettyName(nsACString& aName)
{
NS_ENSURE_STATE(mCert);
*aName = ToNewCString(mCert->commonName);
if (!*aName) {
return NS_ERROR_OUT_OF_MEMORY;
}
aName = mCert->prettyName;
return NS_OK;
}
NS_IMETHODIMP
nsPrincipal::SetCommonName(const char* aName)
nsPrincipal::GetSubjectName(nsACString& aName)
{
if (!mCert) {
NS_ERROR("You must first initialize the certificate with an ID");
return NS_ERROR_FAILURE;
}
NS_ENSURE_STATE(mCert);
mCert->commonName = aName;
aName = mCert->subjectName;
return NS_OK;
}
NS_IMETHODIMP
nsPrincipal::GetCertificate(nsISupports** aCertificate)
{
if (mCert) {
NS_IF_ADDREF(*aCertificate = mCert->cert);
}
else {
*aCertificate = nsnull;
}
return NS_OK;
}
NS_IMETHODIMP
nsPrincipal::GetHashValue(PRUint32* aValue)
@ -552,7 +571,7 @@ nsPrincipal::GetHashValue(PRUint32* aValue)
// If there is a certificate, it takes precendence over the codebase.
if (mCert) {
*aValue = nsCRT::HashCode(mCert->certificateID.get(), nsnull);
*aValue = nsCRT::HashCode(mCert->fingerprint.get(), nsnull);
}
else {
nsCAutoString str;
@ -583,9 +602,12 @@ nsPrincipal::SetDomain(nsIURI* aDomain)
nsresult
nsPrincipal::InitFromPersistent(const char* aPrefName,
const char* aToken,
const nsCString& aToken,
const nsCString& aSubjectName,
const nsACString& aPrettyName,
const char* aGrantedList,
const char* aDeniedList,
nsISupports* aCert,
PRBool aIsCert,
PRBool aTrusted)
{
@ -599,7 +621,8 @@ nsPrincipal::InitFromPersistent(const char* aPrefName,
nsresult rv;
if (aIsCert) {
rv = SetCertificate(aToken, nsnull);
rv = SetCertificate(aToken, aSubjectName, aPrettyName, aCert);
if (NS_FAILED(rv)) {
return rv;
}
@ -614,7 +637,7 @@ nsPrincipal::InitFromPersistent(const char* aPrefName,
mTrusted = aTrusted;
}
rv = mJSPrincipals.Init(this, aToken);
rv = mJSPrincipals.Init(this, aToken.get());
NS_ENSURE_SUCCESS(rv, rv);
//-- Save the preference name
@ -641,6 +664,24 @@ nsPrincipal::InitFromPersistent(const char* aPrefName,
return rv;
}
nsresult
nsPrincipal::EnsureCertData(const nsACString& aSubjectName,
const nsACString& aPrettyName,
nsISupports* aCert)
{
NS_ENSURE_STATE(mCert);
if (!mCert->subjectName.IsEmpty() &&
!mCert->subjectName.Equals(aSubjectName)) {
return NS_ERROR_INVALID_ARG;
}
mCert->subjectName = aSubjectName;
mCert->prettyName = aPrettyName;
mCert->cert = aCert;
return NS_OK;
}
struct CapabilityList
{
nsCString* granted;
@ -667,6 +708,7 @@ AppendCapability(nsHashKey *aKey, void *aData, void *capListPtr)
NS_IMETHODIMP
nsPrincipal::GetPreferences(char** aPrefName, char** aID,
char** aSubjectName,
char** aGrantedList, char** aDeniedList)
{
if (mPrefName.IsEmpty()) {
@ -683,11 +725,13 @@ nsPrincipal::GetPreferences(char** aPrefName, char** aID,
*aPrefName = nsnull;
*aID = nsnull;
*aSubjectName = nsnull;
*aGrantedList = nsnull;
*aDeniedList = nsnull;
char *prefName = nsnull;
char *id = nsnull;
char *subjectName = nsnull;
char *granted = nsnull;
char *denied = nsnull;
@ -698,9 +742,12 @@ nsPrincipal::GetPreferences(char** aPrefName, char** aID,
}
//-- ID
nsresult rv;
nsresult rv = NS_OK;
if (mCert) {
rv = GetCertificateID(&id);
id = ToNewCString(mCert->fingerprint);
if (!id) {
rv = NS_ERROR_OUT_OF_MEMORY;
}
}
else {
rv = GetOrigin(&id);
@ -711,6 +758,18 @@ nsPrincipal::GetPreferences(char** aPrefName, char** aID,
return rv;
}
if (mCert) {
subjectName = ToNewCString(mCert->subjectName);
} else {
subjectName = ToNewCString(EmptyCString());
}
if (!subjectName) {
nsMemory::Free(prefName);
nsMemory::Free(id);
return NS_ERROR_OUT_OF_MEMORY;
}
//-- Capabilities
nsCAutoString grantedListStr, deniedListStr;
CapabilityList capList = CapabilityList();
@ -724,6 +783,7 @@ nsPrincipal::GetPreferences(char** aPrefName, char** aID,
if (!granted) {
nsMemory::Free(prefName);
nsMemory::Free(id);
nsMemory::Free(subjectName);
return NS_ERROR_OUT_OF_MEMORY;
}
}
@ -734,6 +794,7 @@ nsPrincipal::GetPreferences(char** aPrefName, char** aID,
if (!denied) {
nsMemory::Free(prefName);
nsMemory::Free(id);
nsMemory::Free(subjectName);
if (granted) {
nsMemory::Free(granted);
}
@ -743,6 +804,7 @@ nsPrincipal::GetPreferences(char** aPrefName, char** aID,
*aPrefName = prefName;
*aID = id;
*aSubjectName = subjectName;
*aGrantedList = granted;
*aDeniedList = denied;

Просмотреть файл

@ -1687,10 +1687,35 @@ nsScriptSecurityManager::SubjectPrincipalIsSystem(PRBool* aIsSystem)
}
NS_IMETHODIMP
nsScriptSecurityManager::GetCertificatePrincipal(const char* aCertID,
nsScriptSecurityManager::GetCertificatePrincipal(const nsACString& aCertFingerprint,
const nsACString& aSubjectName,
const nsACString& aPrettyName,
nsISupports* aCertificate,
nsIURI* aURI,
nsIPrincipal **result)
{
*result = nsnull;
NS_ENSURE_ARG(!aCertFingerprint.IsEmpty() &&
!aSubjectName.IsEmpty() &&
aCertificate);
return DoGetCertificatePrincipal(aCertFingerprint, aSubjectName,
aPrettyName, aCertificate, aURI, PR_TRUE,
result);
}
nsresult
nsScriptSecurityManager::DoGetCertificatePrincipal(const nsACString& aCertFingerprint,
const nsACString& aSubjectName,
const nsACString& aPrettyName,
nsISupports* aCertificate,
nsIURI* aURI,
PRBool aModifyTable,
nsIPrincipal **result)
{
NS_ENSURE_ARG(!aCertFingerprint.IsEmpty());
// Create a certificate principal out of the certificate ID
// and URI given to us. We will use this principal to test
// equality when doing our hashtable lookups below.
@ -1698,7 +1723,8 @@ nsScriptSecurityManager::GetCertificatePrincipal(const char* aCertID,
if (!certificate)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = certificate->Init(aCertID, aURI);
nsresult rv = certificate->Init(aCertFingerprint, aSubjectName,
aPrettyName, aCertificate, aURI);
NS_ENSURE_SUCCESS(rv, rv);
// Check to see if we already have this principal.
@ -1706,7 +1732,24 @@ nsScriptSecurityManager::GetCertificatePrincipal(const char* aCertID,
mPrincipals.Get(certificate, getter_AddRefs(fromTable));
if (fromTable) {
// Bingo. We found the certificate in the table, which means
// that it has escalated priveleges.
// that it has escalated privileges.
if (aModifyTable) {
// Make sure this principal has names, so if we ever go to save it
// we'll save them. If we get a name mismatch here we'll throw,
// but that's desirable.
rv = NS_STATIC_CAST(nsPrincipal*,
NS_STATIC_CAST(nsIPrincipal*, fromTable))
->EnsureCertData(aSubjectName, aPrettyName, aCertificate);
if (NS_FAILED(rv)) {
// We have a subject name mismatch for the same cert id.
// Hand back the |certificate| object we created and don't give
// it any rights from the table.
NS_ADDREF(*result = certificate);
return NS_OK;
}
}
if (!aURI) {
// We were asked to just get the base certificate, so output
// what we have in the table.
@ -1720,19 +1763,24 @@ nsScriptSecurityManager::GetCertificatePrincipal(const char* aCertID,
// things.
nsXPIDLCString prefName;
nsXPIDLCString id;
nsXPIDLCString subjectName;
nsXPIDLCString granted;
nsXPIDLCString denied;
rv = fromTable->GetPreferences(getter_Copies(prefName),
getter_Copies(id),
getter_Copies(subjectName),
getter_Copies(granted),
getter_Copies(denied));
// XXXbz assert something about subjectName and aSubjectName here?
if (NS_SUCCEEDED(rv)) {
certificate = new nsPrincipal();
if (!certificate)
return NS_ERROR_OUT_OF_MEMORY;
rv = certificate->InitFromPersistent(prefName, id,
subjectName, aPrettyName,
granted, denied,
aCertificate,
PR_TRUE, PR_FALSE);
if (NS_SUCCEEDED(rv))
certificate->SetURI(aURI);
@ -1752,7 +1800,8 @@ nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, nsIPrincipal **re
if (!codebase)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = codebase->Init(nsnull, aURI);
nsresult rv = codebase->Init(EmptyCString(), EmptyCString(),
EmptyCString(), nsnull, aURI);
if (NS_FAILED(rv))
return rv;
@ -2060,36 +2109,45 @@ nsScriptSecurityManager::SavePrincipal(nsIPrincipal* aToSave)
//-- Save to prefs
nsXPIDLCString idPrefName;
nsXPIDLCString id;
nsXPIDLCString subjectName;
nsXPIDLCString grantedList;
nsXPIDLCString deniedList;
nsresult rv = aToSave->GetPreferences(getter_Copies(idPrefName),
getter_Copies(id),
getter_Copies(subjectName),
getter_Copies(grantedList),
getter_Copies(deniedList));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
nsXPIDLCString grantedPrefName;
nsXPIDLCString deniedPrefName;
rv = PrincipalPrefNames( idPrefName,
getter_Copies(grantedPrefName),
getter_Copies(deniedPrefName) );
nsCAutoString grantedPrefName;
nsCAutoString deniedPrefName;
nsCAutoString subjectNamePrefName;
rv = GetPrincipalPrefNames( idPrefName,
grantedPrefName,
deniedPrefName,
subjectNamePrefName );
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
mIsWritingPrefs = PR_TRUE;
if (grantedList)
mSecurityPref->SecuritySetCharPref(grantedPrefName, grantedList);
mSecurityPref->SecuritySetCharPref(grantedPrefName.get(), grantedList);
else
mSecurityPref->SecurityClearUserPref(grantedPrefName);
mSecurityPref->SecurityClearUserPref(grantedPrefName.get());
if (deniedList)
mSecurityPref->SecuritySetCharPref(deniedPrefName, deniedList);
mSecurityPref->SecuritySetCharPref(deniedPrefName.get(), deniedList);
else
mSecurityPref->SecurityClearUserPref(deniedPrefName);
mSecurityPref->SecurityClearUserPref(deniedPrefName.get());
if (grantedList || deniedList)
if (grantedList || deniedList) {
mSecurityPref->SecuritySetCharPref(idPrefName, id);
else
mSecurityPref->SecuritySetCharPref(subjectNamePrefName.get(),
subjectName);
}
else {
mSecurityPref->SecurityClearUserPref(idPrefName);
mSecurityPref->SecurityClearUserPref(subjectNamePrefName.get());
}
mIsWritingPrefs = PR_FALSE;
@ -2265,14 +2323,14 @@ nsScriptSecurityManager::CheckConfirmDialog(JSContext* cx, nsIPrincipal* aPrinci
PRBool hasCert;
aPrincipal->GetHasCertificate(&hasCert);
if (hasCert)
rv = aPrincipal->GetCommonName(getter_Copies(val));
rv = aPrincipal->GetPrettyName(val);
else
rv = aPrincipal->GetOrigin(getter_Copies(val));
if (NS_FAILED(rv))
return PR_FALSE;
NS_ConvertUTF8toUTF16 location(val.get());
NS_ConvertUTF8toUTF16 location(val);
NS_ConvertASCIItoUTF16 capability(aCapability);
FormatCapabilityString(capability);
const PRUnichar *formatStrings[] = { location.get(), capability.get() };
@ -2387,14 +2445,14 @@ nsScriptSecurityManager::EnableCapability(const char *capability)
nsresult rv;
principal->GetHasCertificate(&hasCert);
if (hasCert)
rv = principal->GetCommonName(getter_Copies(val));
rv = principal->GetPrettyName(val);
else
rv = principal->GetOrigin(getter_Copies(val));
if (NS_FAILED(rv))
return rv;
NS_ConvertUTF8toUTF16 location(val.get());
NS_ConvertUTF8toUTF16 location(val);
NS_ConvertUTF8toUTF16 cap(capability);
const PRUnichar *formatStrings[] = { location.get(), cap.get() };
@ -2452,10 +2510,12 @@ nsScriptSecurityManager::DisableCapability(const char *capability)
//////////////// Master Certificate Functions ///////////////////////////////////////
NS_IMETHODIMP
nsScriptSecurityManager::SetCanEnableCapability(const char* certificateID,
nsScriptSecurityManager::SetCanEnableCapability(const nsACString& certFingerprint,
const char* capability,
PRInt16 canEnable)
{
NS_ENSURE_ARG(!certFingerprint.IsEmpty());
nsresult rv;
nsIPrincipal* subjectPrincipal = doGetSubjectPrincipal(&rv);
if (NS_FAILED(rv))
@ -2511,7 +2571,10 @@ nsScriptSecurityManager::SetCanEnableCapability(const char* certificateID,
//-- Get the target principal
nsCOMPtr<nsIPrincipal> objectPrincipal;
rv = GetCertificatePrincipal(certificateID, nsnull, getter_AddRefs(objectPrincipal));
rv = DoGetCertificatePrincipal(certFingerprint, EmptyCString(),
EmptyCString(), nsnull,
nsnull, PR_FALSE,
getter_AddRefs(objectPrincipal));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
rv = objectPrincipal->SetCanEnableCapability(capability, canEnable);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
@ -3261,33 +3324,44 @@ nsScriptSecurityManager::InitDomainPolicy(JSContext* cx,
}
// XXXbz We should really just get a prefbranch to handle this...
nsresult
nsScriptSecurityManager::PrincipalPrefNames(const char* pref,
char** grantedPref, char** deniedPref)
nsScriptSecurityManager::GetPrincipalPrefNames(const char* prefBase,
nsCString& grantedPref,
nsCString& deniedPref,
nsCString& subjectNamePref)
{
char* lastDot = PL_strrchr(pref, '.');
char* lastDot = PL_strrchr(prefBase, '.');
if (!lastDot) return NS_ERROR_FAILURE;
PRInt32 prefLen = lastDot - pref + 1;
PRInt32 prefLen = lastDot - prefBase + 1;
*grantedPref = nsnull;
*deniedPref = nsnull;
grantedPref.Assign(prefBase, prefLen);
deniedPref.Assign(prefBase, prefLen);
subjectNamePref.Assign(prefBase, prefLen);
static const char granted[] = "granted";
*grantedPref = (char*)PR_MALLOC(prefLen + sizeof(granted));
if (!grantedPref) return NS_ERROR_OUT_OF_MEMORY;
PL_strncpy(*grantedPref, pref, prefLen);
PL_strcpy(*grantedPref + prefLen, granted);
#define GRANTED "granted"
#define DENIED "denied"
#define SUBJECTNAME "subjectName"
static const char denied[] = "denied";
*deniedPref = (char*)PR_MALLOC(prefLen + sizeof(denied));
if (!deniedPref)
{
PR_FREEIF(*grantedPref);
grantedPref.AppendLiteral(GRANTED);
if (grantedPref.Length() != prefLen + sizeof(GRANTED) - 1) {
return NS_ERROR_OUT_OF_MEMORY;
}
PL_strncpy(*deniedPref, pref, prefLen);
PL_strcpy(*deniedPref + prefLen, denied);
deniedPref.AppendLiteral(DENIED);
if (deniedPref.Length() != prefLen + sizeof(DENIED) - 1) {
return NS_ERROR_OUT_OF_MEMORY;
}
subjectNamePref.AppendLiteral(SUBJECTNAME);
if (subjectNamePref.Length() != prefLen + sizeof(SUBJECTNAME) - 1) {
return NS_ERROR_OUT_OF_MEMORY;
}
#undef SUBJECTNAME
#undef DENIED
#undef GRANTED
return NS_OK;
}
@ -3311,7 +3385,8 @@ nsScriptSecurityManager::InitPrincipals(PRUint32 aPrefCount, const char** aPrefN
static const char idSuffix[] = ".id";
for (PRUint32 c = 0; c < aPrefCount; c++)
{
PRInt32 prefNameLen = PL_strlen(aPrefNames[c]) - (sizeof(idSuffix)-1);
PRInt32 prefNameLen = PL_strlen(aPrefNames[c]) -
(NS_ARRAY_LENGTH(idSuffix) - 1);
if (PL_strcasecmp(aPrefNames[c] + prefNameLen, idSuffix) != 0)
continue;
@ -3319,27 +3394,35 @@ nsScriptSecurityManager::InitPrincipals(PRUint32 aPrefCount, const char** aPrefN
if (NS_FAILED(mSecurityPref->SecurityGetCharPref(aPrefNames[c], getter_Copies(id))))
return NS_ERROR_FAILURE;
nsXPIDLCString grantedPrefName;
nsXPIDLCString deniedPrefName;
nsresult rv = PrincipalPrefNames(aPrefNames[c],
getter_Copies(grantedPrefName),
getter_Copies(deniedPrefName));
nsCAutoString grantedPrefName;
nsCAutoString deniedPrefName;
nsCAutoString subjectNamePrefName;
nsresult rv = GetPrincipalPrefNames(aPrefNames[c],
grantedPrefName,
deniedPrefName,
subjectNamePrefName);
if (rv == NS_ERROR_OUT_OF_MEMORY)
return rv;
if (NS_FAILED(rv))
continue;
nsXPIDLCString grantedList;
mSecurityPref->SecurityGetCharPref(grantedPrefName, getter_Copies(grantedList));
mSecurityPref->SecurityGetCharPref(grantedPrefName.get(),
getter_Copies(grantedList));
nsXPIDLCString deniedList;
mSecurityPref->SecurityGetCharPref(deniedPrefName, getter_Copies(deniedList));
mSecurityPref->SecurityGetCharPref(deniedPrefName.get(),
getter_Copies(deniedList));
nsXPIDLCString subjectName;
mSecurityPref->SecurityGetCharPref(subjectNamePrefName.get(),
getter_Copies(subjectName));
//-- Delete prefs if their value is the empty string
if (id.IsEmpty() || (grantedList.IsEmpty() && deniedList.IsEmpty()))
{
mSecurityPref->SecurityClearUserPref(aPrefNames[c]);
mSecurityPref->SecurityClearUserPref(grantedPrefName);
mSecurityPref->SecurityClearUserPref(deniedPrefName);
mSecurityPref->SecurityClearUserPref(grantedPrefName.get());
mSecurityPref->SecurityClearUserPref(deniedPrefName.get());
mSecurityPref->SecurityClearUserPref(subjectNamePrefName.get());
continue;
}
@ -3371,8 +3454,9 @@ nsScriptSecurityManager::InitPrincipals(PRUint32 aPrefCount, const char** aPrefN
if (!newPrincipal)
return NS_ERROR_OUT_OF_MEMORY;
rv = newPrincipal->InitFromPersistent(aPrefNames[c], id.get(),
grantedList, deniedList,
rv = newPrincipal->InitFromPersistent(aPrefNames[c], id, subjectName,
EmptyCString(),
grantedList, deniedList, nsnull,
isCert, isTrusted);
if (NS_SUCCEEDED(rv))
mPrincipals.Put(newPrincipal, newPrincipal);

Просмотреть файл

@ -51,6 +51,7 @@
#include "nsXPIDLString.h"
#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
#include "nsString.h"
#include "nsPrefsCID.h"
///////////////////////
@ -102,6 +103,30 @@ getStringArgument(JSContext *cx, JSObject *obj, PRUint16 argNum, uintN argc, jsv
return JS_GetStringBytes(str);
}
static void
getUTF8StringArgument(JSContext *cx, JSObject *obj, PRUint16 argNum,
uintN argc, jsval *argv, nsCString& aRetval)
{
if (argc <= argNum || !JSVAL_IS_STRING(argv[argNum])) {
JS_ReportError(cx, "String argument expected");
aRetval.Truncate();
return;
}
/*
* We don't want to use JS_ValueToString because we want to be able
* to have an object to represent a target in subsequent versions.
*/
JSString *str = JSVAL_TO_STRING(argv[argNum]);
if (!str) {
aRetval.Truncate();
return;
}
PRUnichar *data = (PRUnichar*)JS_GetStringChars(str);
CopyUTF16toUTF8(data, aRetval);
}
PR_STATIC_CALLBACK(JSBool)
netscape_security_isPrivilegeEnabled(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
@ -196,9 +221,10 @@ netscape_security_setCanEnablePrivilege(JSContext *cx, JSObject *obj, uintN argc
jsval *argv, jsval *rval)
{
if (argc < 2) return JS_FALSE;
char *principalID = getStringArgument(cx, obj, 0, argc, argv);
nsCAutoString principalFingerprint;
getUTF8StringArgument(cx, obj, 0, argc, argv, principalFingerprint);
char *cap = getStringArgument(cx, obj, 1, argc, argv);
if (!principalID || !cap)
if (principalFingerprint.IsEmpty() || !cap)
return JS_FALSE;
nsresult rv;
@ -209,7 +235,7 @@ netscape_security_setCanEnablePrivilege(JSContext *cx, JSObject *obj, uintN argc
// NS_ASSERTION(cx == GetCurrentContext(), "unexpected context");
rv = securityManager->SetCanEnableCapability(principalID, cap,
rv = securityManager->SetCanEnableCapability(principalFingerprint, cap,
nsIPrincipal::ENABLE_GRANTED);
if (NS_FAILED(rv))
return JS_FALSE;
@ -220,8 +246,9 @@ PR_STATIC_CALLBACK(JSBool)
netscape_security_invalidate(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
char *principalID = getStringArgument(cx, obj, 0, argc, argv);
if (!principalID)
nsCAutoString principalFingerprint;
getUTF8StringArgument(cx, obj, 0, argc, argv, principalFingerprint);
if (principalFingerprint.IsEmpty())
return JS_FALSE;
nsresult rv;
@ -232,7 +259,7 @@ netscape_security_invalidate(JSContext *cx, JSObject *obj, uintN argc,
// NS_ASSERTION(cx == GetCurrentContext(), "unexpected context");
rv = securityManager->SetCanEnableCapability(principalID,
rv = securityManager->SetCanEnableCapability(principalFingerprint,
nsPrincipal::sInvalid,
nsIPrincipal::ENABLE_GRANTED);
if (NS_FAILED(rv))

Просмотреть файл

@ -84,12 +84,14 @@ nsSystemPrincipal::Release()
///////////////////////////////////////
NS_IMETHODIMP
nsSystemPrincipal::GetPreferences(char** aPrefName, char** aID,
nsSystemPrincipal::GetPreferences(char** aPrefName, char** aID,
char** aSubjectName,
char** aGrantedList, char** aDeniedList)
{
// The system principal should never be streamed out
*aPrefName = nsnull;
*aID = nsnull;
*aSubjectName = nsnull;
*aGrantedList = nsnull;
*aDeniedList = nsnull;
@ -181,22 +183,27 @@ nsSystemPrincipal::GetOrigin(char** aOrigin)
}
NS_IMETHODIMP
nsSystemPrincipal::GetCertificateID(char** aID)
nsSystemPrincipal::GetFingerprint(nsACString& aID)
{
*aID = nsnull;
return NS_OK;
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsSystemPrincipal::GetCommonName(char** aName)
nsSystemPrincipal::GetPrettyName(nsACString& aName)
{
*aName = nsnull;
return NS_OK;
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsSystemPrincipal::SetCommonName(const char* aName)
nsSystemPrincipal::GetSubjectName(nsACString& aName)
{
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsSystemPrincipal::GetCertificate(nsISupports** aCertificate)
{
*aCertificate = nsnull;
return NS_OK;
}

Просмотреть файл

@ -455,25 +455,32 @@ nsJARChannel::GetOwner(nsISupports **result)
if (NS_FAILED(rv)) return rv;
if (cert) {
nsXPIDLCString certID;
rv = cert->GetCertificateID(getter_Copies(certID));
nsCAutoString certFingerprint;
rv = cert->GetFingerprint(certFingerprint);
if (NS_FAILED(rv)) return rv;
nsXPIDLCString commonName;
rv = cert->GetCommonName(getter_Copies(commonName));
nsCAutoString subjectName;
rv = cert->GetSubjectName(subjectName);
if (NS_FAILED(rv)) return rv;
nsCAutoString prettyName;
rv = cert->GetPrettyName(prettyName);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsISupports> certificate;
rv = cert->GetCertificate(getter_AddRefs(certificate));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIScriptSecurityManager> secMan =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
rv = secMan->GetCertificatePrincipal(certID, mJarBaseURI,
rv = secMan->GetCertificatePrincipal(certFingerprint, subjectName,
prettyName, certificate,
mJarBaseURI,
getter_AddRefs(cert));
if (NS_FAILED(rv)) return rv;
rv = cert->SetCommonName(commonName);
if (NS_FAILED(rv)) return rv;
mOwner = do_QueryInterface(cert, &rv);
if (NS_FAILED(rv)) return rv;

Просмотреть файл

@ -156,8 +156,8 @@ nsCSecurityContext::GetCertificateID(char* buf, int buflen)
return NS_ERROR_FAILURE;
}
nsXPIDLCString certificate;
principal->GetCertificateID(getter_Copies(certificate));
nsCAutoString certificate;
principal->GetFingerprint(certificate);
PRInt32 certlen = certificate.Length();
if (buflen <= certlen) {

Просмотреть файл

@ -903,7 +903,10 @@ nsJVMManager::IsLiveConnectEnabled(void)
* be derived, should have been verified before this method is
* called.
*/
// XXXbz this function has been deprecated for 4.5 years. We have no
// callers in the tree. Is it time to remove it? It's returning
// PRBools for a NS_METHOD, and NS_METHOD for an interface method, for
// goodness' sake!
NS_METHOD
nsJVMManager::IsAllPermissionGranted(
const char * lastFP,
@ -912,6 +915,10 @@ nsJVMManager::IsAllPermissionGranted(
const char * rootCN,
PRBool * isGranted)
{
if (!lastFP || !lastCN) {
return PR_FALSE;
}
nsresult rv = NS_OK;
nsCOMPtr<nsIPrincipal> pIPrincipal;
@ -926,13 +933,16 @@ nsJVMManager::IsAllPermissionGranted(
// The fingerprint is a one way hash of this certificate. It is used
// as the key to store the principal in the principal database.
rv = secMan->GetCertificatePrincipal(lastFP, nsnull,
// XXXbz using the |lastCN| for the subjectName for lack of
// anything better. Also not passing in a pointer to a cert,
// since we don't have one.
rv = secMan->GetCertificatePrincipal(nsDependentCString(lastFP),
nsDependentCString(lastCN),
nsDependentCString(lastCN),
nsnull, nsnull,
getter_AddRefs(pIPrincipal));
if (NS_FAILED(rv)) return PR_FALSE;
// Set the common name.
rv = pIPrincipal->SetCommonName(lastCN);
PRInt16 ret;
secMan->RequestCapability(pIPrincipal,"AllPermission",&ret);

Просмотреть файл

@ -1705,25 +1705,28 @@ nsNSSComponent::VerifySignature(const char* aRSABuf, PRUint32 aRSABufLen,
if (NS_FAILED(rv2)) {
break;
}
nsCOMPtr<nsIPrincipal> certPrincipal;
rv2 = mScriptSecurityManager->
GetCertificatePrincipal(NS_ConvertUTF16toUTF8(fingerprint).get(),
nsnull, getter_AddRefs(certPrincipal));
if (NS_FAILED(rv2) || !certPrincipal) {
break;
}
nsAutoString orgName;
rv2 = pCert->GetOrganization(orgName);
if (NS_FAILED(rv2)) {
break;
}
rv2 = certPrincipal->SetCommonName(NS_ConvertUTF16toUTF8(orgName).get());
nsAutoString subjectName;
rv2 = pCert->GetSubjectName(subjectName);
if (NS_FAILED(rv2)) {
break;
}
NS_ADDREF(*aPrincipal = certPrincipal);
nsCOMPtr<nsIPrincipal> certPrincipal;
rv2 = mScriptSecurityManager->
GetCertificatePrincipal(NS_ConvertUTF16toUTF8(fingerprint),
NS_ConvertUTF16toUTF8(subjectName),
NS_ConvertUTF16toUTF8(orgName),
pCert, nsnull, getter_AddRefs(certPrincipal));
if (NS_FAILED(rv2) || !certPrincipal) {
break;
}
certPrincipal.swap(*aPrincipal);
} while (0);
}

Просмотреть файл

@ -2646,12 +2646,14 @@ ExtensionManager.prototype = {
var zipReader = Components.classes["@mozilla.org/libjar/zip-reader;1"]
.createInstance(Components.interfaces.nsIZipReader);
zipReader.init(entry);
var commonName = "";
var prettyName = "";
try {
var jar = zipReader.QueryInterface(Components.interfaces.nsIJAR);
var principal = { };
var certPrincipal = zipReader.getCertificatePrincipal(null, principal);
commonName = principal.value.commonName;
// XXXbz This string could be empty. This needs better
// UI to present principal.value.certificate's subject.
prettyName = principal.value.prettyName;
}
catch (e) { }
xpinstallStrings = xpinstallStrings.concat([item.name,

Просмотреть файл

@ -142,9 +142,12 @@ nsXPITriggerItem::SetPrincipal(nsIPrincipal* aPrincipal)
PRBool hasCert;
aPrincipal->GetHasCertificate(&hasCert);
if (hasCert) {
nsXPIDLCString cName;
aPrincipal->GetCommonName(getter_Copies(cName));
CopyUTF8toUTF16(cName, mCertName);
nsCAutoString prettyName;
// XXXbz should this really be using the prettyName? Perhaps
// it wants to get the subjectName or nsIX509Cert and display
// it sanely?
aPrincipal->GetPrettyName(prettyName);
CopyUTF8toUTF16(prettyName, mCertName);
}
}