Fixes for bugs 27010, 32878, 32948.
This commit is contained in:
Родитель
9cbfebccc7
Коммит
9ac7780368
|
@ -31,7 +31,6 @@
|
|||
[uuid(ebfefcd0-25e1-11d2-8160-006008119d7a)]
|
||||
interface nsICertificatePrincipal : nsISupports {
|
||||
|
||||
readonly attribute string issuerName;
|
||||
readonly attribute string serialNumber;
|
||||
readonly attribute string companyName;
|
||||
readonly attribute string certificateID;
|
||||
attribute string commonName;
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Mitch Stoltz
|
||||
*/
|
||||
|
||||
/* Defines the abstract interface for a principal. */
|
||||
|
@ -26,14 +27,12 @@
|
|||
#include "nsISupports.idl"
|
||||
|
||||
%{C++
|
||||
class nsSupportsHashtable;
|
||||
struct JSPrincipals;
|
||||
%}
|
||||
|
||||
interface nsIPref;
|
||||
|
||||
[ptr] native JSPrincipals(JSPrincipals);
|
||||
[ptr] native nsSupportsHashtable(nsSupportsHashtable);
|
||||
|
||||
[uuid(ff9313d0-25e1-11d2-8160-006008119d7a)]
|
||||
interface nsIPrincipal : nsISupports {
|
||||
|
@ -50,6 +49,8 @@ interface nsIPrincipal : nsISupports {
|
|||
|
||||
string ToUserVisibleString();
|
||||
|
||||
void ToStreamableForm(out string name, out string data);
|
||||
|
||||
boolean Equals(in nsIPrincipal other);
|
||||
|
||||
unsigned long HashValue();
|
||||
|
@ -67,8 +68,6 @@ interface nsIPrincipal : nsISupports {
|
|||
void RevertCapability(in string capability, inout voidStar annotation);
|
||||
|
||||
void DisableCapability(in string capability, inout voidStar annotation);
|
||||
|
||||
void Save(in nsSupportsHashtable aPrincipals, in nsIPref prefs);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -56,8 +56,7 @@ interface nsIScriptSecurityManager : nsISupports
|
|||
/**
|
||||
* Return a principal that can be QI'd to nsICertificatePrincipal.
|
||||
*/
|
||||
nsIPrincipal GetCertificatePrincipal(in string aIssuer, in string aSerialNumber,
|
||||
in string companyName);
|
||||
nsIPrincipal GetCertificatePrincipal(in string CertID);
|
||||
|
||||
///////////////// Security Checks //////////////////
|
||||
|
||||
|
@ -136,6 +135,15 @@ interface nsIScriptSecurityManager : nsISupports
|
|||
* script.
|
||||
*/
|
||||
void DisableCapability(in string capability);
|
||||
|
||||
//////////////// Master Certificate Functions ////////////////////
|
||||
|
||||
/**
|
||||
* Allow 'certificateID' to enable 'capability.' Can only be performed
|
||||
* by code signed by the system certificate.
|
||||
*/
|
||||
void SetCanEnableCapability(in string certificateID, in string capability,
|
||||
in short canEnable);
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
|
|
@ -82,7 +82,7 @@ public:
|
|||
DisableCapability(const char *capability, void **annotation);
|
||||
|
||||
NS_IMETHOD
|
||||
Save(nsSupportsHashtable* aPrincipals, nsIPref *prefs);
|
||||
ToStreamableForm(char** aName, char** aData);
|
||||
|
||||
nsAggregatePrincipal();
|
||||
|
||||
|
|
|
@ -61,8 +61,10 @@ public:
|
|||
nsresult
|
||||
InitFromPersistent(const char *name, const char *data);
|
||||
|
||||
NS_IMETHOD
|
||||
Save(nsSupportsHashtable* aPrincipals, nsIPref *prefs);
|
||||
NS_IMETHOD
|
||||
ToStreamableForm(char** aName, char** aData);
|
||||
|
||||
static const char Invalid[];
|
||||
|
||||
protected:
|
||||
enum AnnotationValue { AnnotationEnabled=1, AnnotationDisabled };
|
||||
|
|
|
@ -48,6 +48,8 @@ public:
|
|||
|
||||
NS_IMETHOD ToUserVisibleString(char **result);
|
||||
|
||||
NS_IMETHOD ToStreamableForm(char** aName, char** aData);
|
||||
|
||||
NS_IMETHOD Equals(nsIPrincipal *other, PRBool *result);
|
||||
|
||||
NS_IMETHOD HashValue(PRUint32 *result);
|
||||
|
@ -56,17 +58,15 @@ public:
|
|||
|
||||
NS_IMETHOD InitFromPersistent(const char *name, const char* data);
|
||||
|
||||
NS_IMETHOD Init(const char* aIssuerName, const char* aSerialNumber,
|
||||
const char* aCompanyName);
|
||||
NS_IMETHOD Init(const char* aCertificateID);
|
||||
|
||||
nsCertificatePrincipal();
|
||||
|
||||
virtual ~nsCertificatePrincipal(void);
|
||||
|
||||
protected:
|
||||
char* mIssuerName;
|
||||
char* mSerialNumber;
|
||||
char* mCompanyName;
|
||||
char* mCertificateID;
|
||||
char* mCommonName;
|
||||
};
|
||||
|
||||
#endif // _NS_CERTIFICATE_PRINCIPAL_H_
|
||||
|
|
|
@ -47,6 +47,8 @@ public:
|
|||
|
||||
NS_IMETHOD ToUserVisibleString(char **result);
|
||||
|
||||
NS_IMETHOD ToStreamableForm(char** aName, char** aData);
|
||||
|
||||
NS_IMETHOD Equals(nsIPrincipal *other, PRBool *result);
|
||||
|
||||
NS_IMETHOD HashValue(PRUint32 *result);
|
||||
|
|
|
@ -103,8 +103,6 @@ public:
|
|||
GetScriptSecurityManager();
|
||||
|
||||
private:
|
||||
void
|
||||
LookupPrincipal(nsCOMPtr<nsIPrincipal>* aPrincipal);
|
||||
|
||||
NS_IMETHOD
|
||||
GetSubjectPrincipal(JSContext *aCx, nsIPrincipal **result);
|
||||
|
@ -140,6 +138,9 @@ private:
|
|||
GetPrincipalAndFrame(JSContext *cx, nsIPrincipal **result,
|
||||
JSStackFrame **frameResult);
|
||||
|
||||
NS_IMETHOD
|
||||
SavePrincipal(nsIPrincipal* aToSave);
|
||||
|
||||
NS_IMETHOD
|
||||
InitFromPrefs();
|
||||
|
||||
|
@ -158,10 +159,11 @@ private:
|
|||
nsObjectHashtable *mOriginToPolicyMap;
|
||||
nsIPref *mPrefs;
|
||||
nsIPrincipal *mSystemPrincipal;
|
||||
nsCOMPtr<nsIPrincipal> mSystemCertificate;
|
||||
nsSupportsHashtable *mPrincipals;
|
||||
PRBool mIsJavaScriptEnabled;
|
||||
PRBool mIsMailJavaScriptEnabled;
|
||||
PRBool mIsWritingPrefs;
|
||||
PRBool mIsAccessingPrefs;
|
||||
unsigned char hasPolicyVector[(NS_DOM_PROP_MAX >> 3) + 1];
|
||||
unsigned char hasDomainPolicyVector[(NS_DOM_PROP_MAX >> 3) + 1];
|
||||
};
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
|
||||
NS_IMETHOD DisableCapability(const char *capability, void * *annotation);
|
||||
|
||||
NS_IMETHOD Save(nsSupportsHashtable* aPrincipals, nsIPref* aPrefs);
|
||||
NS_IMETHOD ToStreamambleForm(char** aName, char** aData);
|
||||
|
||||
NS_IMETHOD Init();
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
/*describes principals which combine one or more principals*/
|
||||
#include "nsAggregatePrincipal.h"
|
||||
#include "nsIURI.h" //////////////////////
|
||||
#include "nsIURI.h"
|
||||
|
||||
static NS_DEFINE_IID(kIAggregatePrincipalIID, NS_IAGGREGATEPRINCIPAL_IID);
|
||||
|
||||
|
@ -38,42 +38,39 @@ NSBASEPRINCIPALS_RELEASE(nsAggregatePrincipal);
|
|||
// Methods implementing nsICertificatePrincipal //
|
||||
//////////////////////////////////////////////////
|
||||
NS_IMETHODIMP
|
||||
nsAggregatePrincipal::GetIssuerName(char** aIssuerName)
|
||||
nsAggregatePrincipal::GetCertificateID(char** aCertificateID)
|
||||
{
|
||||
if (!mCertificate)
|
||||
{
|
||||
aIssuerName = nsnull;
|
||||
aCertificateID = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICertificatePrincipal> certificate = do_QueryInterface(mCertificate);
|
||||
return certificate->GetIssuerName(aIssuerName);
|
||||
return certificate->GetCertificateID(aCertificateID);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAggregatePrincipal::GetSerialNumber(char** aSerialNumber)
|
||||
nsAggregatePrincipal::GetCommonName(char** aCommonName)
|
||||
{
|
||||
if (!mCertificate)
|
||||
{
|
||||
*aSerialNumber = nsnull;
|
||||
*aCommonName = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICertificatePrincipal> certificate = do_QueryInterface(mCertificate);
|
||||
return certificate->GetSerialNumber(aSerialNumber);
|
||||
return certificate->GetCommonName(aCommonName);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAggregatePrincipal::GetCompanyName(char** aCompanyName)
|
||||
nsAggregatePrincipal::SetCommonName(const char* aCommonName)
|
||||
{
|
||||
if (!mCertificate)
|
||||
{
|
||||
*aCompanyName = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICertificatePrincipal> certificate = do_QueryInterface(mCertificate);
|
||||
return certificate->GetCompanyName(aCompanyName);
|
||||
return certificate->SetCommonName(aCommonName);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
@ -191,16 +188,38 @@ nsAggregatePrincipal::SetCodebase(nsIPrincipal* aCodebase)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAggregatePrincipal::GetPrimaryChild(nsIPrincipal** aPrimaryChild)
|
||||
{
|
||||
//-- If a certificate is present, then that's the PrimaryChild principal.
|
||||
// Otherwise we use the codebase.
|
||||
if (mCertificate)
|
||||
*aPrimaryChild = mCertificate.get();
|
||||
else if (mCodebase)
|
||||
*aPrimaryChild = mCodebase.get();
|
||||
else
|
||||
{
|
||||
*aPrimaryChild = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aPrimaryChild);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAggregatePrincipal::Intersect(nsIPrincipal* other)
|
||||
{
|
||||
NS_ASSERTION(mCodebase, "Principal without codebase");
|
||||
|
||||
PRBool sameCert = PR_FALSE;
|
||||
if (NS_FAILED(mCertificate->Equals(other, &sameCert)))
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!sameCert)
|
||||
SetCertificate(nsnull);
|
||||
if (mCertificate)
|
||||
{
|
||||
PRBool sameCert = PR_FALSE;
|
||||
if (NS_FAILED(mCertificate->Equals(other, &sameCert)))
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!sameCert)
|
||||
SetCertificate(nsnull);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -228,30 +247,34 @@ nsAggregatePrincipal::ToUserVisibleString(char **result)
|
|||
NS_IMETHODIMP
|
||||
nsAggregatePrincipal::Equals(nsIPrincipal * other, PRBool * result)
|
||||
{
|
||||
*result = PR_FALSE;
|
||||
if (this == other) {
|
||||
*result = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
if (!other) {
|
||||
*result = PR_FALSE;
|
||||
if (!other)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIAggregatePrincipal> otherAgg =
|
||||
do_QueryInterface(other, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
*result = PR_FALSE;
|
||||
return NS_OK;
|
||||
//-- Two aggregates are equal if both codebase and certificate are equal
|
||||
PRBool certEqual = PR_TRUE;
|
||||
if (mCertificate)
|
||||
{
|
||||
mCertificate->Equals(other, &certEqual);
|
||||
if(NS_FAILED(rv)) return rv;
|
||||
}
|
||||
//-- Two aggregates are equal if both codebase and certificate are equal
|
||||
*result = PR_FALSE;
|
||||
PRBool certEqual, cbEqual;
|
||||
rv = mCertificate->Equals(other, &certEqual);
|
||||
if(NS_FAILED(rv)) return rv;
|
||||
rv = mCodebase->Equals(other, &cbEqual);
|
||||
if(NS_FAILED(rv)) return rv;
|
||||
*result = certEqual && cbEqual;
|
||||
PRBool cbEqual = PR_TRUE;
|
||||
if (mCodebase)
|
||||
{
|
||||
rv = mCodebase->Equals(other, &cbEqual);
|
||||
if(NS_FAILED(rv)) return rv;
|
||||
}
|
||||
if (mCertificate || mCodebase) // At least one must be present
|
||||
*result = certEqual && cbEqual;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -322,31 +345,12 @@ nsAggregatePrincipal::DisableCapability(const char *capability, void **annotatio
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAggregatePrincipal::Save(nsSupportsHashtable* aPrincipals, nsIPref *prefs)
|
||||
nsAggregatePrincipal::ToStreamableForm(char** aName, char** aData)
|
||||
{
|
||||
nsCOMPtr<nsIPrincipal> PrimaryChild;
|
||||
if (NS_FAILED(GetPrimaryChild(getter_AddRefs(PrimaryChild))))
|
||||
return NS_ERROR_FAILURE;
|
||||
return PrimaryChild->Save(aPrincipals, prefs);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAggregatePrincipal::GetPrimaryChild(nsIPrincipal** aPrimaryChild)
|
||||
{
|
||||
//-- If a certificate is present, then that's the PrimaryChild principal.
|
||||
// Otherwise we use the codebase.
|
||||
if (mCertificate)
|
||||
*aPrimaryChild = mCertificate.get();
|
||||
else if (mCodebase)
|
||||
*aPrimaryChild = mCodebase.get();
|
||||
else
|
||||
{
|
||||
*aPrimaryChild = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aPrimaryChild);
|
||||
return NS_OK;
|
||||
return PrimaryChild->ToStreamableForm(aName, aData);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
//////////////////////////
|
||||
|
||||
|
||||
nsBasePrincipal::nsBasePrincipal()
|
||||
: mCapabilities(nsnull), mPrefName(nsnull)
|
||||
{
|
||||
|
@ -62,6 +61,9 @@ nsBasePrincipal::GetJSPrincipals(JSPrincipals **jsprin)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
const char
|
||||
nsBasePrincipal::Invalid[] = "Invalid";
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBasePrincipal::CanEnableCapability(const char *capability, PRInt16 *result)
|
||||
{
|
||||
|
@ -69,6 +71,16 @@ nsBasePrincipal::CanEnableCapability(const char *capability, PRInt16 *result)
|
|||
*result = nsIPrincipal::ENABLE_UNKNOWN;
|
||||
return NS_OK;
|
||||
}
|
||||
else // If this principal is marked invalid, can't enable any capabilities
|
||||
{
|
||||
nsStringKey invalidKey(Invalid);
|
||||
if (mCapabilities->Exists(&invalidKey))
|
||||
{
|
||||
*result = nsIPrincipal::ENABLE_DENIED;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
const char *start = capability;
|
||||
*result = nsIPrincipal::ENABLE_GRANTED;
|
||||
for(;;) {
|
||||
|
@ -96,6 +108,16 @@ nsBasePrincipal::SetCanEnableCapability(const char *capability,
|
|||
if (!mCapabilities)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
else // If this principal is marked invalid, can't enable any capabilities
|
||||
{
|
||||
nsStringKey invalidKey(Invalid);
|
||||
if (mCapabilities->Exists(&invalidKey))
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (PL_strcmp(capability, Invalid) == 0)
|
||||
mCapabilities->Reset();
|
||||
|
||||
const char *start = capability;
|
||||
for(;;) {
|
||||
const char *space = PL_strchr(start, ' ');
|
||||
|
@ -166,7 +188,7 @@ nsBasePrincipal::RevertCapability(const char *capability, void **annotation)
|
|||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBasePrincipal::SetCapability(const char *capability, void **annotation,
|
||||
|
@ -175,7 +197,7 @@ nsBasePrincipal::SetCapability(const char *capability, void **annotation,
|
|||
if (*annotation == nsnull) {
|
||||
*annotation = new nsHashtable(5);
|
||||
if (!*annotation)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
// This object owns its annotations. Save them so we can release
|
||||
// them when we destroy this object.
|
||||
mAnnotations.AppendElement(*annotation);
|
||||
|
@ -202,37 +224,55 @@ nsBasePrincipal::InitFromPersistent(const char *name, const char* data)
|
|||
{
|
||||
// Parses capabilities strings of the form
|
||||
// "Capability=value ..."
|
||||
// ie. "UniversalBrowserRead=0 UniversalBrowserWrite=1"
|
||||
// where value is from 0 to 3 as defined in nsIPrincipal.idl
|
||||
// ie. "UniversalBrowserRead=Granted UniversalBrowserWrite=Denied"
|
||||
|
||||
//-- Empty the capability table
|
||||
if (mCapabilities)
|
||||
mCapabilities->Reset();
|
||||
|
||||
//-- Save the preference name
|
||||
nsCAutoString nameString(name);
|
||||
mPrefName = nameString.ToNewCString();
|
||||
|
||||
static const char *prefix = ".X";
|
||||
const char *p = PL_strstr(name, prefix);
|
||||
if (p) {
|
||||
int n = atoi(p + sizeof(prefix)-1);
|
||||
const char* ordinalBegin = PL_strpbrk(name, "1234567890");
|
||||
if (ordinalBegin) {
|
||||
int n = atoi(ordinalBegin);
|
||||
if (mCapabilitiesOrdinal <= n)
|
||||
mCapabilitiesOrdinal = n+1;
|
||||
}
|
||||
|
||||
//-- Parse the capabilities
|
||||
for (;;)
|
||||
{
|
||||
char* wordEnd = PL_strchr(data, '=');
|
||||
if (wordEnd == nsnull)
|
||||
break;
|
||||
*wordEnd = '\0';
|
||||
while (*(wordEnd-1) == ' ')
|
||||
wordEnd--;
|
||||
const char* cap = data;
|
||||
data = wordEnd+1; // data is now pointing at the numeric value
|
||||
PRInt16 value = (PRInt16)(*data) - (PRInt16)'0';
|
||||
nsresult rv = SetCanEnableCapability(cap, value);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (data[1] == '\0') // End of the data
|
||||
break;
|
||||
data = wordEnd+1;
|
||||
*wordEnd = '\0';
|
||||
while (*data == ' ' || *data == '=')
|
||||
data++;
|
||||
|
||||
PRInt16 value;
|
||||
if (*data == 'G' || *data == 'g' || *data == 'Y' ||
|
||||
*data == 'y' || *data == 'T' || *data == 't' ||
|
||||
(*data - '0') == nsIPrincipal::ENABLE_GRANTED ||
|
||||
*data == '1')
|
||||
value = nsIPrincipal::ENABLE_GRANTED;
|
||||
else if (*data == 'D' || *data == 'd' || *data == 'N' ||
|
||||
*data == 'n' || *data == 'F' || *data == 'f' ||
|
||||
(*data - '0') == nsIPrincipal::ENABLE_DENIED ||
|
||||
*data == '0')
|
||||
value = nsIPrincipal::ENABLE_DENIED;
|
||||
else
|
||||
data += 2; // data is now at the beginning of the next capability string
|
||||
value = nsIPrincipal::ENABLE_UNKNOWN;
|
||||
|
||||
if(NS_FAILED(SetCanEnableCapability(cap, value)))
|
||||
return NS_ERROR_FAILURE;
|
||||
while (*data != ' ' && *data != '\0') data++;
|
||||
while (*data == ' ') data++;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -240,43 +280,35 @@ nsBasePrincipal::InitFromPersistent(const char *name, const char* data)
|
|||
PR_STATIC_CALLBACK(PRBool)
|
||||
AppendCapability(nsHashKey *aKey, void *aData, void *aStr)
|
||||
{
|
||||
char value = (char)((unsigned int)aData) + '0';
|
||||
nsCString *capStr = (nsCString*) aStr;
|
||||
capStr->Append(' ');
|
||||
capStr->AppendWithConversion(((nsStringKey *) aKey)->GetString());
|
||||
capStr->Append('=');
|
||||
capStr->Append(value);
|
||||
switch ((PRInt16)aData)
|
||||
{
|
||||
case nsIPrincipal::ENABLE_GRANTED:
|
||||
capStr->Append("Granted");
|
||||
break;
|
||||
case nsIPrincipal::ENABLE_DENIED:
|
||||
capStr->Append("Denied");
|
||||
break;
|
||||
default:
|
||||
capStr->Append("Unknown");
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBasePrincipal::Save(nsSupportsHashtable* aPrincipals, nsIPref *aPref)
|
||||
NS_IMETHODIMP
|
||||
nsBasePrincipal::ToStreamableForm(char** aName, char** aData)
|
||||
{
|
||||
//-- Save in hashtable
|
||||
nsIPrincipalKey key(this);
|
||||
// This is a little sneaky. "supports" below is a void *, which won't
|
||||
// be refcounted, but is matched with a key that is the same object,
|
||||
// which will be refcounted.
|
||||
aPrincipals->Put(&key, this);
|
||||
|
||||
//-- Save to preferences
|
||||
char *streamableForm;
|
||||
if (NS_FAILED(ToString(&streamableForm)))
|
||||
return NS_ERROR_FAILURE;
|
||||
if (mCapabilities) {
|
||||
nsCAutoString result(streamableForm);
|
||||
mCapabilities->Enumerate(AppendCapability, (void*)&result);
|
||||
streamableForm = result.ToNewCString();
|
||||
nsCAutoString buildingCapString(streamableForm);
|
||||
mCapabilities->Enumerate(AppendCapability, (void*)&buildingCapString);
|
||||
streamableForm = buildingCapString.ToNewCString();
|
||||
}
|
||||
if (!mPrefName) {
|
||||
nsCAutoString s("security.principal.X");
|
||||
s.AppendInt(mCapabilitiesOrdinal++);
|
||||
mPrefName = s.ToNewCString();
|
||||
}
|
||||
nsresult rv = aPref->SetCharPref(mPrefName, streamableForm);
|
||||
Recycle(streamableForm);
|
||||
return rv;
|
||||
*aData = streamableForm;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -38,24 +38,25 @@ NSBASEPRINCIPALS_RELEASE(nsCertificatePrincipal);
|
|||
// Methods implementing nsICertificatePrincipal //
|
||||
//////////////////////////////////////////////////
|
||||
NS_IMETHODIMP
|
||||
nsCertificatePrincipal::GetIssuerName(char ** issuerName)
|
||||
nsCertificatePrincipal::GetCertificateID(char** aCertificateID)
|
||||
{
|
||||
*issuerName = nsCRT::strdup(mIssuerName);
|
||||
return *issuerName ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
*aCertificateID = nsCRT::strdup(mCertificateID);
|
||||
return *mCertificateID ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCertificatePrincipal::GetSerialNumber(char ** serialNumber)
|
||||
nsCertificatePrincipal::GetCommonName(char** aCommonName)
|
||||
{
|
||||
*serialNumber = nsCRT::strdup(mSerialNumber);
|
||||
return *serialNumber ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
*aCommonName = nsCRT::strdup(mCommonName);
|
||||
return *aCommonName ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCertificatePrincipal::GetCompanyName(char ** companyName)
|
||||
nsCertificatePrincipal::SetCommonName(const char* aCommonName)
|
||||
{
|
||||
*companyName = nsCRT::strdup(mCompanyName);
|
||||
return * companyName ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
PR_FREEIF(mCommonName);
|
||||
mCommonName = nsCRT::strdup(aCommonName);
|
||||
return * mCommonName ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
|
@ -76,52 +77,54 @@ nsCertificatePrincipal::CanEnableCapability(const char *capability,
|
|||
NS_IMETHODIMP
|
||||
nsCertificatePrincipal::ToString(char **result)
|
||||
{
|
||||
// STRING USE WARNING: perhaps |str| should be an |nsCAutoString|? -- scc
|
||||
nsAutoString str;
|
||||
str.AppendWithConversion("[Certificate ");
|
||||
str.AppendWithConversion(mIssuerName);
|
||||
str.AppendWithConversion(' ');
|
||||
str.AppendWithConversion(mSerialNumber);
|
||||
str.AppendWithConversion(']');
|
||||
*result = str.ToNewCString();
|
||||
return (*result) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
return GetCertificateID(result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCertificatePrincipal::ToUserVisibleString(char **result)
|
||||
{
|
||||
return GetCompanyName(result);
|
||||
return GetCommonName(result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCertificatePrincipal::ToStreamableForm(char** aName, char** aData)
|
||||
{
|
||||
if (!mPrefName) {
|
||||
nsCAutoString s("security.principal.certificate");
|
||||
s += mCapabilitiesOrdinal++;
|
||||
mPrefName = s.ToNewCString();
|
||||
}
|
||||
*aName = nsCRT::strdup(mPrefName);
|
||||
if (!*aName)
|
||||
return NS_ERROR_FAILURE;
|
||||
return nsBasePrincipal::ToStreamableForm(aName, aData);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCertificatePrincipal::Equals(nsIPrincipal * other, PRBool * result)
|
||||
{
|
||||
*result = PR_FALSE;
|
||||
if (this == other) {
|
||||
*result = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
if (!other) {
|
||||
*result = PR_FALSE;
|
||||
if (!other)
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICertificatePrincipal> otherCertificate =
|
||||
do_QueryInterface(other, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
*result = PR_FALSE;
|
||||
return NS_OK;
|
||||
//-- Compare cert ID's
|
||||
char* otherID;
|
||||
rv = otherCertificate->GetCertificateID(&otherID);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
PR_FREEIF(otherID);
|
||||
return rv;
|
||||
}
|
||||
//-- Compare issuer name and serial number;
|
||||
// these comprise the unique id of the cert
|
||||
char* otherIssuer;
|
||||
otherCertificate->GetIssuerName(&otherIssuer);
|
||||
char* otherSerial;
|
||||
otherCertificate->GetSerialNumber(&otherSerial);
|
||||
*result = ( (PL_strcmp(mIssuerName, otherIssuer) == 0) &&
|
||||
(PL_strcmp(mSerialNumber, otherSerial) == 0) );
|
||||
PR_FREEIF(otherIssuer);
|
||||
PR_FREEIF(otherSerial);
|
||||
*result = (PL_strcmp(mCertificateID, otherID) == 0);
|
||||
PR_FREEIF(otherID);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -142,59 +145,46 @@ NS_IMETHODIMP
|
|||
nsCertificatePrincipal::InitFromPersistent(const char *name, const char* data)
|
||||
{
|
||||
// Parses preference strings of the form
|
||||
// "[Certificate Issuer Serial#] capabilities string"
|
||||
// ie. "[Certificate CertCo 12:34:AB:CD] UniversalBrowserRead=1"
|
||||
// <certificateID><space><capabilities list>"
|
||||
// ie. "AB:CD:12:34 UniversalBrowserRead=Granted"
|
||||
|
||||
if (!data)
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
|
||||
data = PL_strchr(data, ' '); // Jump to issuer
|
||||
NS_ASSERTION(data, "Malformed security.principal preference");
|
||||
data += 1;
|
||||
char* idEnd = PL_strchr(data, ' '); // Find end of certID
|
||||
if (idEnd)
|
||||
*idEnd = '\0';
|
||||
|
||||
char* wordEnd = PL_strchr(data, ' '); // Find end of issuer
|
||||
NS_ASSERTION(wordEnd, "Malformed security.principal preference");
|
||||
*wordEnd = '\0';
|
||||
const char* issuer = data;
|
||||
|
||||
data = wordEnd+1; // Jump to serial#
|
||||
wordEnd = PL_strchr(data, ']'); // Find end of serial#
|
||||
NS_ASSERTION(wordEnd, "Malformed security.principal preference");
|
||||
*wordEnd = '\0';
|
||||
const char* serial = data;
|
||||
|
||||
if (NS_FAILED(Init(issuer, serial, nsnull)))
|
||||
if (NS_FAILED(Init(data)))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (wordEnd[1] != '\0') {
|
||||
data = wordEnd+2; // Jump to beginning of caps data
|
||||
return nsBasePrincipal::InitFromPersistent(name, data);
|
||||
|
||||
if (idEnd)
|
||||
{
|
||||
data = idEnd+1;
|
||||
while (*data == ' ')
|
||||
data++;
|
||||
if (data)
|
||||
return nsBasePrincipal::InitFromPersistent(name, data);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCertificatePrincipal::Init(const char* aIssuerName, const char* aSerialNumber,
|
||||
const char* aCompanyName)
|
||||
nsCertificatePrincipal::Init(const char* aCertificateID)
|
||||
{
|
||||
mIssuerName = nsCRT::strdup(aIssuerName);
|
||||
mSerialNumber = nsCRT::strdup(aSerialNumber);
|
||||
mCompanyName = nsCRT::strdup(aCompanyName);
|
||||
if (!mIssuerName || !mSerialNumber ||
|
||||
!mCompanyName) return NS_ERROR_OUT_OF_MEMORY;
|
||||
mCertificateID = nsCRT::strdup(aCertificateID);
|
||||
if (!mCertificateID) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCertificatePrincipal::nsCertificatePrincipal() : mIssuerName(nsnull),
|
||||
mSerialNumber(nsnull),
|
||||
mCompanyName(nsnull)
|
||||
nsCertificatePrincipal::nsCertificatePrincipal() : mCertificateID(nsnull),
|
||||
mCommonName(nsnull)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsCertificatePrincipal::~nsCertificatePrincipal()
|
||||
{
|
||||
PR_FREEIF(mIssuerName);
|
||||
PR_FREEIF(mSerialNumber);
|
||||
PR_FREEIF(mCompanyName);
|
||||
PR_FREEIF(mCertificateID);
|
||||
PR_FREEIF(mCommonName);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Norris Boyd
|
||||
* Mitch Stoltz
|
||||
*/
|
||||
|
||||
/* Describes principals by their orginating uris */
|
||||
|
@ -62,6 +63,20 @@ nsCodebasePrincipal::ToUserVisibleString(char **result)
|
|||
return GetOrigin(result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCodebasePrincipal::ToStreamableForm(char** aName, char** aData)
|
||||
{
|
||||
if (!mPrefName) {
|
||||
nsCAutoString s("security.principal.codebase");
|
||||
s += mCapabilitiesOrdinal++;
|
||||
mPrefName = s.ToNewCString();
|
||||
}
|
||||
*aName = nsCRT::strdup(mPrefName);
|
||||
if (!*aName)
|
||||
return NS_ERROR_FAILURE;
|
||||
return nsBasePrincipal::ToStreamableForm(aName, aData);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCodebasePrincipal::HashValue(PRUint32 *result)
|
||||
{
|
||||
|
@ -255,28 +270,30 @@ nsresult
|
|||
nsCodebasePrincipal::InitFromPersistent(const char *name, const char* data)
|
||||
{
|
||||
// Parses preference strings of the form
|
||||
// "[Codebase URL] capabilities string"
|
||||
// ie. "[Codebase http://www.mozilla.org] UniversalBrowserRead=1"
|
||||
// "<codebase URL><space><capabilities string>"
|
||||
// ie. "http://www.mozilla.org UniversalBrowserRead=Granted"
|
||||
if (!data)
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
|
||||
data = PL_strchr(data, ' '); // Jump to URL
|
||||
if (!data)
|
||||
return NS_ERROR_FAILURE;
|
||||
data += 1;
|
||||
char* urlEnd = PL_strchr(data, ' '); // Find end of URL
|
||||
if (urlEnd)
|
||||
*urlEnd = '\0';
|
||||
|
||||
char* urlEnd = PL_strchr(data, ']'); // Find end of URL
|
||||
NS_ASSERTION(urlEnd, "Malformed security.principal preference.");
|
||||
*urlEnd = '\0'; // XXX modification of const char *
|
||||
|
||||
if (NS_FAILED(NS_NewURI(&mURI, data, nsnull))) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), data, nsnull))) {
|
||||
NS_ASSERTION(PR_FALSE, "Malformed URI in security.principal preference.");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (NS_FAILED(Init(uri))) return NS_ERROR_FAILURE;
|
||||
|
||||
if (urlEnd[1] != '\0') {
|
||||
data = urlEnd+2; // Jump to beginning of caps data
|
||||
return nsBasePrincipal::InitFromPersistent(name, data);
|
||||
if (urlEnd)
|
||||
{
|
||||
// Jump to beginning of capabilities list
|
||||
data = urlEnd+1;
|
||||
while (*data == ' ')
|
||||
data++;
|
||||
if (data)
|
||||
return nsBasePrincipal::InitFromPersistent(name, data);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,10 @@
|
|||
#include "nsIIOService.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsINetSupportDialogService.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsSpecialSystemDirectory.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIZipReader.h"
|
||||
|
||||
static NS_DEFINE_CID(kNetSupportDialogCID, NS_NETSUPPORTDIALOG_CID);
|
||||
static NS_DEFINE_IID(kIIOServiceIID, NS_IIOSERVICE_IID);
|
||||
|
@ -61,6 +65,7 @@ static NS_DEFINE_IID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
|
|||
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
||||
static NS_DEFINE_CID(kCScriptNameSetRegistryCID,
|
||||
NS_SCRIPT_NAMESET_REGISTRY_CID);
|
||||
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
|
||||
|
||||
enum {
|
||||
SCRIPT_SECURITY_UNDEFINED_ACCESS,
|
||||
|
@ -131,9 +136,9 @@ nsSecurityNameSet::~nsSecurityNameSet()
|
|||
NS_IMPL_ISUPPORTS(nsSecurityNameSet, NS_GET_IID(nsIScriptExternalNameSet));
|
||||
|
||||
static char *
|
||||
getStringArgument(JSContext *cx, JSObject *obj, uintN argc, jsval *argv)
|
||||
getStringArgument(JSContext *cx, JSObject *obj, PRUint16 argNum, uintN argc, jsval *argv)
|
||||
{
|
||||
if (argc == 0 || !JSVAL_IS_STRING(argv[0])) {
|
||||
if (argc <= argNum || !JSVAL_IS_STRING(argv[argNum])) {
|
||||
JS_ReportError(cx, "String argument expected");
|
||||
return nsnull;
|
||||
}
|
||||
|
@ -141,7 +146,7 @@ getStringArgument(JSContext *cx, JSObject *obj, uintN argc, jsval *argv)
|
|||
* 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[0]);
|
||||
JSString *str = JSVAL_TO_STRING(argv[argNum]);
|
||||
if (!str)
|
||||
return nsnull;
|
||||
|
||||
|
@ -153,7 +158,7 @@ netscape_security_isPrivilegeEnabled(JSContext *cx, JSObject *obj, uintN argc,
|
|||
jsval *argv, jsval *rval)
|
||||
{
|
||||
JSBool result = JS_FALSE;
|
||||
char *cap = getStringArgument(cx, obj, argc, argv);
|
||||
char *cap = getStringArgument(cx, obj, 0, argc, argv);
|
||||
if (cap) {
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
|
||||
|
@ -174,7 +179,7 @@ PR_STATIC_CALLBACK(JSBool)
|
|||
netscape_security_enablePrivilege(JSContext *cx, JSObject *obj, uintN argc,
|
||||
jsval *argv, jsval *rval)
|
||||
{
|
||||
char *cap = getStringArgument(cx, obj, argc, argv);
|
||||
char *cap = getStringArgument(cx, obj, 0, argc, argv);
|
||||
if (!cap)
|
||||
return JS_FALSE;
|
||||
nsresult rv;
|
||||
|
@ -192,7 +197,7 @@ PR_STATIC_CALLBACK(JSBool)
|
|||
netscape_security_disablePrivilege(JSContext *cx, JSObject *obj, uintN argc,
|
||||
jsval *argv, jsval *rval)
|
||||
{
|
||||
char *cap = getStringArgument(cx, obj, argc, argv);
|
||||
char *cap = getStringArgument(cx, obj, 0, argc, argv);
|
||||
if (!cap)
|
||||
return JS_FALSE;
|
||||
nsresult rv;
|
||||
|
@ -210,7 +215,7 @@ PR_STATIC_CALLBACK(JSBool)
|
|||
netscape_security_revertPrivilege(JSContext *cx, JSObject *obj, uintN argc,
|
||||
jsval *argv, jsval *rval)
|
||||
{
|
||||
char *cap = getStringArgument(cx, obj, argc, argv);
|
||||
char *cap = getStringArgument(cx, obj, 0, argc, argv);
|
||||
if (!cap)
|
||||
return JS_FALSE;
|
||||
nsresult rv;
|
||||
|
@ -224,11 +229,55 @@ netscape_security_revertPrivilege(JSContext *cx, JSObject *obj, uintN argc,
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
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);
|
||||
char *cap = getStringArgument(cx, obj, 1, argc, argv);
|
||||
if (!principalID || !cap)
|
||||
return JS_FALSE;
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
|
||||
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return JS_FALSE;
|
||||
NS_ASSERTION(cx == GetCurrentContext(), "unexpected context");
|
||||
if (NS_FAILED(securityManager->SetCanEnableCapability(principalID, cap,
|
||||
nsIPrincipal::ENABLE_GRANTED)))
|
||||
return JS_FALSE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
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)
|
||||
return JS_FALSE;
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
|
||||
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return JS_FALSE;
|
||||
NS_ASSERTION(cx == GetCurrentContext(), "unexpected context");
|
||||
if (NS_FAILED(securityManager->SetCanEnableCapability(principalID,
|
||||
nsBasePrincipal::Invalid,
|
||||
nsIPrincipal::ENABLE_GRANTED)))
|
||||
return JS_FALSE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSFunctionSpec PrivilegeManager_static_methods[] = {
|
||||
{ "isPrivilegeEnabled", netscape_security_isPrivilegeEnabled, 1},
|
||||
{ "enablePrivilege", netscape_security_enablePrivilege, 1},
|
||||
{ "disablePrivilege", netscape_security_disablePrivilege, 1},
|
||||
{ "revertPrivilege", netscape_security_revertPrivilege, 1},
|
||||
//-- System Cert Functions
|
||||
{ "setCanEnablePrivilege", netscape_security_setCanEnablePrivilege, 2},
|
||||
{ "invalidate", netscape_security_invalidate, 1},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -545,9 +594,7 @@ nsScriptSecurityManager::GetSystemPrincipal(nsIPrincipal **result)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetCertificatePrincipal(const char* aIssuerName,
|
||||
const char* aSerialNumber,
|
||||
const char* aCompanyName,
|
||||
nsScriptSecurityManager::GetCertificatePrincipal(const char* aCertID,
|
||||
nsIPrincipal **result)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -556,7 +603,7 @@ nsScriptSecurityManager::GetCertificatePrincipal(const char* aIssuerName,
|
|||
if (!certificate)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(certificate);
|
||||
if (NS_FAILED(certificate->Init(aIssuerName, aSerialNumber, aCompanyName)))
|
||||
if (NS_FAILED(certificate->Init(aCertID)))
|
||||
{
|
||||
NS_RELEASE(certificate);
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -756,6 +803,14 @@ nsScriptSecurityManager::IsCapabilityEnabled(const char *capability,
|
|||
*result = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
// If this capability check is being called as a result of the security
|
||||
// manager accessing a security preference, allow execution.
|
||||
if (mIsAccessingPrefs &&
|
||||
(PL_strcmp(capability, "SecurityPreferencesAccess") == 0))
|
||||
{
|
||||
*result = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
do {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
if (NS_FAILED(GetFramePrincipal(cx, fp, getter_AddRefs(principal)))) {
|
||||
|
@ -978,18 +1033,7 @@ nsScriptSecurityManager::EnableCapability(const char *capability)
|
|||
//-- Save principal to prefs and to mPrincipals
|
||||
if (NS_FAILED(principal->SetCanEnableCapability(capability, canEnable)))
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!mPrincipals) {
|
||||
mPrincipals = new nsSupportsHashtable(31);
|
||||
if (!mPrincipals)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mIsWritingPrefs = PR_TRUE;
|
||||
if (NS_FAILED(principal->Save(mPrincipals, mPrefs))) {
|
||||
mIsWritingPrefs = PR_FALSE;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mIsWritingPrefs = PR_FALSE;
|
||||
if (NS_FAILED(mPrefs->SavePrefFile()))
|
||||
if (NS_FAILED(SavePrincipal(principal)))
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -1038,6 +1082,64 @@ nsScriptSecurityManager::DisableCapability(const char *capability)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::SetCanEnableCapability(const char* certificateID,
|
||||
const char* capability,
|
||||
PRInt16 canEnable)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrincipal> subjectPrincipal;
|
||||
rv = GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
//-- Get the system certificate
|
||||
if (!mSystemCertificate)
|
||||
{
|
||||
nsCOMPtr<nsIFile> systemCertFile;
|
||||
rv = NS_GetSpecialDirectory("xpcom.currentProcess.componentDirectory",
|
||||
getter_AddRefs(systemCertFile));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
systemCertFile->Append("systemSignature.jar");
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIZipReader> systemCertJar;
|
||||
rv = nsComponentManager::CreateInstance(kZipReaderCID, nsnull,
|
||||
NS_GET_IID(nsIZipReader),
|
||||
getter_AddRefs(systemCertJar));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
systemCertJar->Init(systemCertFile);
|
||||
rv = systemCertJar->Open();
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
rv = systemCertJar->GetCertificatePrincipal(nsnull,
|
||||
getter_AddRefs(mSystemCertificate));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
//-- Make sure the caller's principal is the system certificate
|
||||
PRBool isEqual = PR_FALSE;
|
||||
if (mSystemCertificate)
|
||||
{
|
||||
rv = mSystemCertificate->Equals(subjectPrincipal, &isEqual);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!isEqual)
|
||||
{
|
||||
JSContext* cx = GetCurrentContext();
|
||||
if (!cx) return NS_ERROR_FAILURE;
|
||||
static const char msg1[] = "Only code signed by the system certificate may call SetCanEnableCapability or Invalidate";
|
||||
static const char msg2[] = "Attempt to call SetCanEnableCapability or Invalidate when no system certificate has been established";
|
||||
JS_SetPendingException(cx, STRING_TO_JSVAL(JS_NewStringCopyZ(cx,
|
||||
mSystemCertificate ? msg1 : msg2)));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
//-- Get the target principal
|
||||
nsCOMPtr<nsIPrincipal> objectPrincipal;
|
||||
rv = GetCertificatePrincipal(certificateID, getter_AddRefs(objectPrincipal));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
rv = objectPrincipal->SetCanEnableCapability(capability, canEnable);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
return SavePrincipal(objectPrincipal);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Methods implementing nsIXPCSecurityManager //
|
||||
|
@ -1109,7 +1211,7 @@ nsScriptSecurityManager::nsScriptSecurityManager(void)
|
|||
mSystemPrincipal(nsnull), mPrincipals(nsnull),
|
||||
mIsJavaScriptEnabled(PR_FALSE),
|
||||
mIsMailJavaScriptEnabled(PR_FALSE),
|
||||
mIsWritingPrefs(PR_FALSE)
|
||||
mIsAccessingPrefs(PR_FALSE)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
memset(hasPolicyVector, 0, sizeof(hasPolicyVector));
|
||||
|
@ -1196,6 +1298,40 @@ nsScriptSecurityManager::GetObjectPrincipal(JSContext *aCx, JSObject *aObj,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::SavePrincipal(nsIPrincipal* aToSave)
|
||||
{
|
||||
NS_ASSERTION(mPrefs, "nsScriptSecurityManager::mPrefs not initialized");
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrincipal> persistent = aToSave;
|
||||
nsCOMPtr<nsIAggregatePrincipal> aggregate = do_QueryInterface(aToSave, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_FAILED(aggregate->GetPrimaryChild(getter_AddRefs(persistent))))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
//-- Save to mPrincipals
|
||||
if (!mPrincipals)
|
||||
{
|
||||
mPrincipals = new nsSupportsHashtable(31);
|
||||
if (!mPrincipals)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
nsIPrincipalKey key(persistent);
|
||||
mPrincipals->Put(&key, persistent);
|
||||
|
||||
//-- Save to prefs
|
||||
nsXPIDLCString prefName;
|
||||
nsXPIDLCString prefData;
|
||||
rv = persistent->ToStreamableForm(getter_Copies(prefName),
|
||||
getter_Copies(prefData));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
mIsAccessingPrefs = PR_TRUE;
|
||||
rv = mPrefs->SetCharPref(prefName, prefData);
|
||||
mIsAccessingPrefs = PR_FALSE;
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
return mPrefs->SavePrefFile();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CheckPermissions(JSContext *aCx, JSObject *aObj,
|
||||
const char *aCapability)
|
||||
|
@ -1269,7 +1405,9 @@ nsScriptSecurityManager::GetSecurityLevel(nsIPrincipal *principal,
|
|||
PRInt32 secLevel;
|
||||
char *secLevelString;
|
||||
nsresult rv;
|
||||
mIsAccessingPrefs = PR_TRUE;
|
||||
rv = mPrefs->CopyCharPref(prefName, &secLevelString);
|
||||
mIsAccessingPrefs = PR_FALSE;
|
||||
if (NS_FAILED(rv)) {
|
||||
prefName += (isWrite ? ".write" : ".read");
|
||||
rv = mPrefs->CopyCharPref(prefName, &secLevelString);
|
||||
|
@ -1294,7 +1432,6 @@ nsScriptSecurityManager::GetSecurityLevel(nsIPrincipal *principal,
|
|||
return SCRIPT_SECURITY_UNDEFINED_ACCESS;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CheckXPCPermissions(JSContext *aJSContext)
|
||||
{
|
||||
|
@ -1351,7 +1488,6 @@ struct nsDomainEntry {
|
|||
nsCString mPolicy;
|
||||
};
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetPrefName(nsIPrincipal *principal,
|
||||
nsDOMProp domProp, nsCString &result)
|
||||
|
@ -1563,19 +1699,11 @@ nsScriptSecurityManager::EnumeratePrincipalsCallback(const char *prefName,
|
|||
if (NS_FAILED(info->prefs->CopyCharPref(prefName, &data)))
|
||||
return;
|
||||
|
||||
static char codebaseName[] = "[Codebase ";
|
||||
static char certificateName[] = "[Certificate ";
|
||||
static const char certificateName[] = "security.principal.certificate";
|
||||
static const char codebaseName[] = "security.principal.codebase";
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
if (PL_strncasecmp(data, codebaseName, sizeof(codebaseName)-1) == 0) {
|
||||
nsCodebasePrincipal *codebase = new nsCodebasePrincipal();
|
||||
if (codebase) {
|
||||
NS_ADDREF(codebase);
|
||||
if (NS_SUCCEEDED(codebase->InitFromPersistent(prefName, data)))
|
||||
principal = do_QueryInterface((nsBasePrincipal*)codebase);
|
||||
NS_RELEASE(codebase);
|
||||
}
|
||||
} else if (PL_strncasecmp(data, certificateName,
|
||||
sizeof(certificateName)-1) == 0)
|
||||
if (PL_strncmp(prefName, certificateName,
|
||||
sizeof(certificateName)-1) == 0)
|
||||
{
|
||||
nsCertificatePrincipal *certificate = new nsCertificatePrincipal();
|
||||
if (certificate) {
|
||||
|
@ -1584,6 +1712,16 @@ nsScriptSecurityManager::EnumeratePrincipalsCallback(const char *prefName,
|
|||
principal = do_QueryInterface((nsBasePrincipal*)certificate);
|
||||
NS_RELEASE(certificate);
|
||||
}
|
||||
} else if(PL_strncmp(prefName, codebaseName,
|
||||
sizeof(codebaseName)-1) == 0)
|
||||
{
|
||||
nsCodebasePrincipal *codebase = new nsCodebasePrincipal();
|
||||
if (codebase) {
|
||||
NS_ADDREF(codebase);
|
||||
if (NS_SUCCEEDED(codebase->InitFromPersistent(prefName, data)))
|
||||
principal = do_QueryInterface((nsBasePrincipal*)codebase);
|
||||
NS_RELEASE(codebase);
|
||||
}
|
||||
}
|
||||
nsCRT::free(data);
|
||||
if (principal) {
|
||||
|
@ -1621,7 +1759,7 @@ int
|
|||
nsScriptSecurityManager::PrincipalPrefChanged(const char *pref, void *data)
|
||||
{
|
||||
nsScriptSecurityManager *secMgr = (nsScriptSecurityManager *) data;
|
||||
if (secMgr->mIsWritingPrefs)
|
||||
if (secMgr->mIsAccessingPrefs)
|
||||
return 0;
|
||||
EnumeratePrincipalsInfo info;
|
||||
info.ht = secMgr->mPrincipals;
|
||||
|
|
|
@ -44,7 +44,6 @@ NSBASEPRINCIPALS_RELEASE(nsSystemPrincipal);
|
|||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::ToString(char **result)
|
||||
{
|
||||
// STRING USE WARNING: perhaps |buf| should be an |nsCAutoString|? -- scc
|
||||
nsAutoString buf;
|
||||
buf.AssignWithConversion("[System]");
|
||||
|
||||
|
@ -58,6 +57,13 @@ nsSystemPrincipal::ToUserVisibleString(char **result)
|
|||
return ToString(result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::ToStreamambleForm(char** aName, char** aData)
|
||||
{
|
||||
// The system principal should never be streamed out
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::Equals(nsIPrincipal *other, PRBool *result)
|
||||
{
|
||||
|
@ -117,14 +123,6 @@ nsSystemPrincipal::DisableCapability(const char *capability, void **annotation)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::Save(nsSupportsHashtable* aPrincipals, nsIPref* prefs)
|
||||
{
|
||||
// The system principal should never be streamed out
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Constructor, Destructor, initialization //
|
||||
/////////////////////////////////////////////
|
||||
|
|
|
@ -4435,13 +4435,14 @@ HTMLContentSink::OnStreamComplete(nsIStreamLoader* aLoader,
|
|||
//-- Merge the principal of the script file with that of the document
|
||||
nsCOMPtr<nsISupports> owner;
|
||||
aLoader->GetOwner(getter_AddRefs(owner));
|
||||
nsCOMPtr<nsIPrincipal> prin;
|
||||
if (owner)
|
||||
{
|
||||
nsCOMPtr<nsIPrincipal> prin = do_QueryInterface(owner, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = mDocument->AddPrincipal(prin);
|
||||
prin = do_QueryInterface(owner, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
rv = mDocument->AddPrincipal(prin);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = EvaluateScript(jsUnicodeBuffer, mScriptURI, 1, mScriptLanguageVersion);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "nsISecureBrowserUI.h"
|
||||
#include "nsIDocumentLoaderObserver.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsICertificatePrincipal.h"
|
||||
|
||||
#define PSM_VERSION_REG_KEY "/Netscape/Personal Security Manager"
|
||||
|
||||
|
@ -745,29 +746,57 @@ nsPSMComponent::CreatePrincipalFromCert(PRUint32 aCertID, nsIPrincipal** aPrinci
|
|||
if (NS_FAILED(GetControlConnection( &controlConnection )))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
//-- Read cert info
|
||||
//-- Read cert ID
|
||||
CMTStatus result;
|
||||
CMTItem issuerItem;
|
||||
|
||||
CMTItem fingerprint;
|
||||
result = CMT_GetStringAttribute(controlConnection, aCertID,
|
||||
SSM_FID_CERT_COMMON_NAME, &issuerItem);
|
||||
SSM_FID_CERT_FINGERPRINT, &fingerprint);
|
||||
if (result != CMTSuccess) return NS_ERROR_FAILURE;
|
||||
CMTItemStr serialNumberItem;
|
||||
result = CMT_GetStringAttribute(controlConnection, aCertID,
|
||||
SSM_FID_CERT_SERIAL_NUMBER, &serialNumberItem);
|
||||
if (result != CMTSuccess) return NS_ERROR_FAILURE;
|
||||
CMTItemStr companyNameItem;
|
||||
result = CMT_GetStringAttribute(controlConnection, aCertID,
|
||||
SSM_FID_CERT_ORG_NAME, &companyNameItem);
|
||||
if (result != CMTSuccess) return NS_ERROR_FAILURE;
|
||||
|
||||
//-- Get a principal
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
|
||||
NS_SCRIPTSECURITYMANAGER_PROGID, &rv)
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
rv = secMan->GetCertificatePrincipal((char*)issuerItem.data,
|
||||
(char*)serialNumberItem.data,
|
||||
(char*)companyNameItem.data,
|
||||
rv = secMan->GetCertificatePrincipal((char*)fingerprint.data,
|
||||
aPrincipal);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
//-- Get common name and store it in the principal.
|
||||
// Using common name + organizational unit as the user-visible certificate name
|
||||
nsCOMPtr<nsICertificatePrincipal> certificate = do_QueryInterface(*aPrincipal, &rv);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
CMTItem common;
|
||||
result = CMT_GetStringAttribute(controlConnection, aCertID,
|
||||
SSM_FID_CERT_COMMON_NAME, &common);
|
||||
if (result != CMTSuccess) return NS_ERROR_FAILURE;
|
||||
CMTItem subject;
|
||||
result = CMT_GetStringAttribute(controlConnection, aCertID,
|
||||
SSM_FID_CERT_SUBJECT_NAME, &subject);
|
||||
if (result != CMTSuccess) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCAutoString commonName;
|
||||
commonName = (char*)common.data;
|
||||
static const char orgUnitTag[] = " OU=";
|
||||
char* orgUnitPos = PL_strstr((char*)subject.data, orgUnitTag);
|
||||
if (orgUnitPos)
|
||||
{
|
||||
orgUnitPos += sizeof(orgUnitTag)-1;
|
||||
char* orgUnitEnd = PL_strchr(orgUnitPos, ',');
|
||||
PRInt32 orgUnitLen;
|
||||
if(orgUnitEnd)
|
||||
orgUnitLen = orgUnitEnd - orgUnitPos;
|
||||
else
|
||||
orgUnitLen = PL_strlen(orgUnitPos);
|
||||
commonName.Append(' ');
|
||||
commonName.Append(orgUnitPos, orgUnitLen);
|
||||
}
|
||||
char* commonChar = commonName.ToNewCString();
|
||||
if (!commonChar) return NS_ERROR_OUT_OF_MEMORY;
|
||||
rv = certificate->SetCommonName(commonChar);
|
||||
Recycle(commonChar);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -4435,13 +4435,14 @@ HTMLContentSink::OnStreamComplete(nsIStreamLoader* aLoader,
|
|||
//-- Merge the principal of the script file with that of the document
|
||||
nsCOMPtr<nsISupports> owner;
|
||||
aLoader->GetOwner(getter_AddRefs(owner));
|
||||
nsCOMPtr<nsIPrincipal> prin;
|
||||
if (owner)
|
||||
{
|
||||
nsCOMPtr<nsIPrincipal> prin = do_QueryInterface(owner, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = mDocument->AddPrincipal(prin);
|
||||
prin = do_QueryInterface(owner, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
rv = mDocument->AddPrincipal(prin);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = EvaluateScript(jsUnicodeBuffer, mScriptURI, 1, mScriptLanguageVersion);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
|
|
@ -99,8 +99,7 @@ interface nsIZipReader : nsISupports
|
|||
* stored in the jar, verifyExternalFile (not yet implemented) must
|
||||
* be called before getPrincipal.
|
||||
*/
|
||||
void getCertificatePrincipal(in string aEntryName, out nsIPrincipal aPrincipal,
|
||||
out short result);
|
||||
void getCertificatePrincipal(in string aEntryName, out nsIPrincipal aPrincipal);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsJARInputStream.h"
|
||||
#include "nsJAR.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "plbase64.h"
|
||||
#include "nsIConsoleService.h"
|
||||
|
||||
#ifndef XP_MAC
|
||||
#include "nsIPSMComponent.h"
|
||||
|
@ -105,9 +105,6 @@ class nsJARManifestItem
|
|||
public:
|
||||
JARManifestItemType mType;
|
||||
|
||||
// the entity which signed this item
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
|
||||
// True if the second step of verification (VerifyEntry)
|
||||
// has taken place:
|
||||
PRBool step2Complete;
|
||||
|
@ -152,9 +149,9 @@ DeleteManifestEntry(nsHashKey* aKey, void* aData, void* closure)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// The following initialization makes a guess of 25 entries per jarfile.
|
||||
nsJAR::nsJAR(): mManifestData(nsnull, nsnull, DeleteManifestEntry, nsnull, 25),
|
||||
mParsedManifest(PR_FALSE)
|
||||
// The following initialization makes a guess of 10 entries per jarfile.
|
||||
nsJAR::nsJAR(): mManifestData(nsnull, nsnull, DeleteManifestEntry, nsnull, 10),
|
||||
mParsedManifest(PR_FALSE), mGlobalStatus(nsIZipReader::NOT_SIGNED)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
@ -298,137 +295,54 @@ nsJAR::GetInputStream(const char *aFilename, nsIInputStream **result)
|
|||
return CreateInputStream(aFilename, PR_TRUE, result);
|
||||
}
|
||||
|
||||
//-- The following #defines are used by ParseManifest()
|
||||
// and ParseOneFile(). The header strings are defined in the JAR specification.
|
||||
#define JAR_MF 1
|
||||
#define JAR_SF 2
|
||||
#define JAR_MF_SEARCH_STRING "(M|/M)ETA-INF/(M|m)(ANIFEST|anifest).(MF|mf)$"
|
||||
#define JAR_SF_SEARCH_STRING "(M|/M)ETA-INF/*.(SF|sf)$"
|
||||
#define JAR_MF_HEADER (const char*)"Manifest-Version: 1.0"
|
||||
#define JAR_SF_HEADER (const char*)"Signature-Version: 1.0"
|
||||
|
||||
nsresult
|
||||
nsJAR::ParseManifest()
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
return NS_OK;
|
||||
#else
|
||||
//-- Verification Step 1
|
||||
if (mParsedManifest)
|
||||
return NS_OK;
|
||||
mParsedManifest = PR_TRUE;
|
||||
|
||||
//-- (1)Manifest (MF) file
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISimpleEnumerator> files;
|
||||
rv = FindEntries(JAR_MF_SEARCH_STRING, getter_AddRefs(files));
|
||||
if (!files) rv = NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
//-- Load the file into memory
|
||||
nsCOMPtr<nsJARItem> file;
|
||||
rv = files->GetNext(getter_AddRefs(file));
|
||||
if (NS_FAILED(rv) || !file) return rv;
|
||||
PRBool more;
|
||||
rv = files->HasMoreElements(&more);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (more) return NS_ERROR_FILE_CORRUPTED; // More than one MF file
|
||||
nsXPIDLCString manifestFilename;
|
||||
rv = file->GetName(getter_Copies(manifestFilename));
|
||||
if (!manifestFilename || NS_FAILED(rv)) return rv;
|
||||
nsXPIDLCString manifestBuffer;
|
||||
rv = LoadEntry(manifestFilename, getter_Copies(manifestBuffer));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
//-- Parse it
|
||||
rv = ParseOneFile(manifestBuffer, JAR_MF, nsnull, 0);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
DumpMetadata("PM Pass 1 End");
|
||||
|
||||
//-- (2)Signature (SF) file
|
||||
// If there are multiple signatures, we select one at random.
|
||||
rv = FindEntries(JAR_SF_SEARCH_STRING, getter_AddRefs(files));
|
||||
if (!files) rv = NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
//-- Get an SF file
|
||||
rv = files->GetNext(getter_AddRefs(file));
|
||||
if (NS_FAILED(rv) || !file) return rv;
|
||||
rv = file->GetName(getter_Copies(manifestFilename));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRUint32 manifestLen;
|
||||
rv = LoadEntry(manifestFilename, getter_Copies(manifestBuffer), &manifestLen);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
//-- Get its corresponding signature file
|
||||
nsCAutoString sigFilename;
|
||||
sigFilename = manifestFilename;
|
||||
PRInt32 extension = sigFilename.RFindChar('.') + 1;
|
||||
NS_ASSERTION(extension != 0, "Manifest Parser: Missing file extension.");
|
||||
(void)sigFilename.Cut(extension, 2);
|
||||
nsXPIDLCString sigBuffer;
|
||||
PRUint32 sigLen;
|
||||
rv = LoadEntry(sigFilename+"rsa", getter_Copies(sigBuffer), &sigLen);
|
||||
if (NS_FAILED(rv))
|
||||
rv = LoadEntry(sigFilename+"RSA", getter_Copies(sigBuffer), &sigLen);
|
||||
if (NS_FAILED(rv))
|
||||
rv = LoadEntry(sigFilename+"dsa", getter_Copies(sigBuffer), &sigLen);
|
||||
if (NS_FAILED(rv))
|
||||
rv = LoadEntry(sigFilename+"DSA", getter_Copies(sigBuffer), &sigLen);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
//-- Verify that the signature file is a valid signature of the SF file
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
PRInt16 preStatus;
|
||||
rv = VerifySignature(manifestBuffer, manifestLen,
|
||||
sigBuffer, sigLen, getter_AddRefs(principal), &preStatus);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
//-- Parse the SF file. If the verification above failed, principal
|
||||
// is null, and ParseOneFile will mark the relevant entries as invalid.
|
||||
// if ParseOneFile fails, then it has no effect, and we can safely
|
||||
// continue to the next SF file, or return.
|
||||
ParseOneFile(manifestBuffer, JAR_SF, principal, preStatus);
|
||||
DumpMetadata("PM Pass 2 End");
|
||||
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJAR::GetCertificatePrincipal(const char* aFilename, nsIPrincipal** aPrincipal,
|
||||
PRInt16* result)
|
||||
nsJAR::GetCertificatePrincipal(const char* aFilename, nsIPrincipal** aPrincipal)
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#else
|
||||
//-- Parameter check
|
||||
if (!aFilename)
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
if (!aPrincipal)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
*aPrincipal = nsnull;
|
||||
|
||||
DumpMetadata("GetPrincipal");
|
||||
//-- Find the item
|
||||
nsStringKey key(aFilename);
|
||||
nsJARManifestItem* manItem = (nsJARManifestItem*)mManifestData.Get(&key);
|
||||
if (manItem)
|
||||
NS_ASSERTION(manItem->step2Complete,
|
||||
"Attempt to get principal before verifying signature.");
|
||||
if(!manItem || !manItem->step2Complete)
|
||||
{
|
||||
*result = nsIZipReader::NOT_SIGNED;
|
||||
return NS_OK;
|
||||
}
|
||||
if (!mParsedManifest)
|
||||
ParseManifest();
|
||||
|
||||
*result = manItem->status;
|
||||
if (manItem->status == nsIZipReader::VALID)
|
||||
PRInt16 requestedStatus;
|
||||
if (aFilename)
|
||||
{
|
||||
*aPrincipal = manItem->mPrincipal;
|
||||
//-- Find the item
|
||||
nsStringKey key(aFilename);
|
||||
nsJARManifestItem* manItem = (nsJARManifestItem*)mManifestData.Get(&key);
|
||||
if (!manItem)
|
||||
{
|
||||
ReportError(aFilename, nsIZipReader::NOT_SIGNED);
|
||||
return NS_OK;
|
||||
}
|
||||
if (!manItem->step2Complete)
|
||||
{
|
||||
//-- Creating an input stream causes step 2 of verification
|
||||
nsCOMPtr<nsIInputStream> tempStream;
|
||||
if (NS_FAILED(CreateInputStream(aFilename, PR_TRUE, getter_AddRefs(tempStream))))
|
||||
return NS_ERROR_FAILURE;
|
||||
NS_ASSERTION(manItem->step2Complete, "Verification step 2 is not complete");
|
||||
if (!manItem->step2Complete)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
requestedStatus = manItem->status;
|
||||
}
|
||||
else // User wants identity of signer w/o verifying any entries
|
||||
requestedStatus = mGlobalStatus;
|
||||
|
||||
if (requestedStatus != nsIZipReader::VALID)
|
||||
ReportError(aFilename, requestedStatus);
|
||||
else // Valid signature
|
||||
{
|
||||
*aPrincipal = mPrincipal;
|
||||
NS_IF_ADDREF(*aPrincipal);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
@ -507,9 +421,99 @@ nsJAR::ReadLine(const char** src)
|
|||
return length;
|
||||
}
|
||||
|
||||
//-- The following #defines are used by ParseManifest()
|
||||
// and ParseOneFile(). The header strings are defined in the JAR specification.
|
||||
#define JAR_MF 1
|
||||
#define JAR_SF 2
|
||||
#define JAR_MF_SEARCH_STRING "(M|/M)ETA-INF/(M|m)(ANIFEST|anifest).(MF|mf)$"
|
||||
#define JAR_SF_SEARCH_STRING "(M|/M)ETA-INF/*.(SF|sf)$"
|
||||
#define JAR_MF_HEADER (const char*)"Manifest-Version: 1.0"
|
||||
#define JAR_SF_HEADER (const char*)"Signature-Version: 1.0"
|
||||
|
||||
nsresult
|
||||
nsJAR::ParseOneFile(const char* filebuf, PRInt16 aFileType,
|
||||
nsIPrincipal* aPrincipal, PRInt16 aPreStatus)
|
||||
nsJAR::ParseManifest()
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
return NS_OK;
|
||||
#else
|
||||
//-- Verification Step 1
|
||||
if (mParsedManifest)
|
||||
return NS_OK;
|
||||
mParsedManifest = PR_TRUE;
|
||||
|
||||
//-- (1)Manifest (MF) file
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISimpleEnumerator> files;
|
||||
rv = FindEntries(JAR_MF_SEARCH_STRING, getter_AddRefs(files));
|
||||
if (!files) rv = NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
//-- Load the file into memory
|
||||
nsCOMPtr<nsJARItem> file;
|
||||
rv = files->GetNext(getter_AddRefs(file));
|
||||
if (NS_FAILED(rv) || !file) return rv;
|
||||
PRBool more;
|
||||
rv = files->HasMoreElements(&more);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (more) return NS_ERROR_FILE_CORRUPTED; // More than one MF file
|
||||
nsXPIDLCString manifestFilename;
|
||||
rv = file->GetName(getter_Copies(manifestFilename));
|
||||
if (!manifestFilename || NS_FAILED(rv)) return rv;
|
||||
nsXPIDLCString manifestBuffer;
|
||||
rv = LoadEntry(manifestFilename, getter_Copies(manifestBuffer));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
//-- Parse it
|
||||
rv = ParseOneFile(manifestBuffer, JAR_MF);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
DumpMetadata("PM Pass 1 End");
|
||||
|
||||
//-- (2)Signature (SF) file
|
||||
// If there are multiple signatures, we select one.
|
||||
rv = FindEntries(JAR_SF_SEARCH_STRING, getter_AddRefs(files));
|
||||
if (!files) rv = NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
//-- Get an SF file
|
||||
rv = files->GetNext(getter_AddRefs(file));
|
||||
if (NS_FAILED(rv) || !file) return rv;
|
||||
rv = file->GetName(getter_Copies(manifestFilename));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRUint32 manifestLen;
|
||||
rv = LoadEntry(manifestFilename, getter_Copies(manifestBuffer), &manifestLen);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
//-- Get its corresponding signature file
|
||||
nsCAutoString sigFilename;
|
||||
sigFilename = manifestFilename;
|
||||
PRInt32 extension = sigFilename.RFindChar('.') + 1;
|
||||
NS_ASSERTION(extension != 0, "Manifest Parser: Missing file extension.");
|
||||
(void)sigFilename.Cut(extension, 2);
|
||||
nsXPIDLCString sigBuffer;
|
||||
PRUint32 sigLen;
|
||||
rv = LoadEntry(sigFilename+"rsa", getter_Copies(sigBuffer), &sigLen);
|
||||
if (NS_FAILED(rv))
|
||||
rv = LoadEntry(sigFilename+"RSA", getter_Copies(sigBuffer), &sigLen);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
//-- Verify that the signature file is a valid signature of the SF file
|
||||
rv = VerifySignature(manifestBuffer, manifestLen,
|
||||
sigBuffer, sigLen, getter_AddRefs(mPrincipal), &mGlobalStatus);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
//-- Parse the SF file. If the verification above failed, principal
|
||||
// is null, and ParseOneFile will mark the relevant entries as invalid.
|
||||
// if ParseOneFile fails, then it has no effect, and we can safely
|
||||
// continue to the next SF file, or return.
|
||||
ParseOneFile(manifestBuffer, JAR_SF);
|
||||
DumpMetadata("PM Pass 2 End");
|
||||
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJAR::ParseOneFile(const char* filebuf, PRInt16 aFileType)
|
||||
{
|
||||
//-- Check file header
|
||||
const char* nextLineStart = filebuf;
|
||||
|
@ -600,7 +604,7 @@ nsJAR::ParseOneFile(const char* filebuf, PRInt16 aFileType,
|
|||
{
|
||||
NS_ASSERTION(curItemSF->status == nsJAR::NOT_SIGNED,
|
||||
"SECURITY ERROR: nsJARManifestItem not correctly initialized");
|
||||
curItemSF->status = aPreStatus;
|
||||
curItemSF->status = mGlobalStatus;
|
||||
if (curItemSF->status == nsIZipReader::VALID)
|
||||
{ // Compare digests
|
||||
if (storedSectionDigest.Length() == 0)
|
||||
|
@ -610,8 +614,6 @@ nsJAR::ParseOneFile(const char* filebuf, PRInt16 aFileType,
|
|||
if (storedSectionDigest !=
|
||||
(const char*)curItemSF->calculatedSectionDigest)
|
||||
curItemSF->status = nsIZipReader::INVALID_MANIFEST;
|
||||
else
|
||||
curItemSF->mPrincipal = aPrincipal;
|
||||
JAR_NULLFREE(curItemSF->calculatedSectionDigest)
|
||||
storedSectionDigest = "";
|
||||
}
|
||||
|
@ -692,9 +694,7 @@ nsresult
|
|||
nsJAR::VerifyEntry(const char* aEntryName, char* aEntryData,
|
||||
PRUint32 aLen)
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
return NS_OK;
|
||||
#else
|
||||
#ifndef XP_MAC
|
||||
//-- Verification Step 2
|
||||
// Check that verification is supported and step 1 has been done
|
||||
|
||||
|
@ -724,9 +724,6 @@ nsJAR::VerifyEntry(const char* aEntryName, char* aEntryData,
|
|||
JAR_NULLFREE(calculatedEntryDigest)
|
||||
JAR_NULLFREE(manItem->storedEntryDigest)
|
||||
}
|
||||
|
||||
if(manItem->status != nsIZipReader::VALID)
|
||||
manItem->mPrincipal = null_nsCOMPtr();
|
||||
}
|
||||
|
||||
manItem->step2Complete = PR_TRUE;
|
||||
|
@ -735,6 +732,58 @@ nsJAR::VerifyEntry(const char* aEntryName, char* aEntryData,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsJAR::ReportError(const char* aFilename, PRInt16 errorCode)
|
||||
{
|
||||
//-- Generate error message
|
||||
nsAutoString message("Signature Verification Error: the signature on ");
|
||||
if (aFilename)
|
||||
message += aFilename;
|
||||
else
|
||||
message += "this .jar archive";
|
||||
message += " is invalid because ";
|
||||
switch(errorCode)
|
||||
{
|
||||
case nsIZipReader::NOT_SIGNED:
|
||||
message += "the archive did not contain a valid PKCS7 signature.";
|
||||
break;
|
||||
case nsIZipReader::INVALID_SIG:
|
||||
message += "the digital signature (*.RSA) file is not a valid signature of ";
|
||||
message += "the signature instruction file (*.SF).";
|
||||
break;
|
||||
case nsIZipReader::INVALID_UNKNOWN_CA:
|
||||
message += "the certificate used to sign this file has an unrecognized issuer.";
|
||||
break;
|
||||
case nsIZipReader::INVALID_MANIFEST:
|
||||
message += "the signature instruction file (*.SF) does not contain a valid hash ";
|
||||
message += "of the MANIFEST.MF file.";
|
||||
break;
|
||||
case nsIZipReader::INVALID_ENTRY:
|
||||
message += "the MANIFEST.MF file does not contain a valid hash of the file ";
|
||||
message += "being verified.";
|
||||
break;
|
||||
default:
|
||||
message += "of an unknown problem.";
|
||||
}
|
||||
|
||||
// Report error in JS console
|
||||
nsCOMPtr<nsIConsoleService> console
|
||||
(do_GetService("mozilla.consoleservice.1"));
|
||||
if (console)
|
||||
{
|
||||
PRUnichar* messageUni = message.ToNewUnicode();
|
||||
if (!messageUni) return;
|
||||
console->LogStringMessage(messageUni);
|
||||
nsAllocator::Free(messageUni);
|
||||
}
|
||||
else // If JS console reporting failed, print to stderr.
|
||||
{
|
||||
char* messageCstr = message.ToNewCString();
|
||||
if (!messageCstr) return;
|
||||
fprintf(stderr, "%s\n", messageCstr);
|
||||
nsAllocator::Free(messageCstr);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJAR::RestoreModTime(nsZipItem *aItem, nsIFile *aExtractedFile)
|
||||
{
|
||||
|
@ -789,7 +838,7 @@ nsresult nsJAR::CalculateDigest(const char* aInBuf, PRUint32 aLen,
|
|||
if (!(*digest)) { PR_FREEIF(rawDigest); return NS_ERROR_OUT_OF_MEMORY; }
|
||||
|
||||
PR_FREEIF(rawDigest);
|
||||
#endif
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,9 +49,9 @@
|
|||
#include "nsIZipReader.h"
|
||||
#include "nsZipArchive.h"
|
||||
#include "zipfile.h"
|
||||
#include "nsIPrincipal.h"
|
||||
|
||||
class nsIInputStream;
|
||||
class nsIPrincipal;
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Class nsJAR declaration.
|
||||
|
@ -79,20 +79,22 @@ class nsJAR : public nsIZipReader
|
|||
|
||||
protected:
|
||||
//-- Private data members
|
||||
nsCOMPtr<nsIFile> mZipFile; // The zip/jar file on disk
|
||||
nsZipArchive mZip; // The underlying zip archive
|
||||
nsObjectHashtable mManifestData; // Stores metadata for each entry
|
||||
nsCOMPtr<nsIFile> mZipFile; // The zip/jar file on disk
|
||||
nsZipArchive mZip; // The underlying zip archive
|
||||
nsObjectHashtable mManifestData; // Stores metadata for each entry
|
||||
PRBool mParsedManifest; // True if manifest has been parsed
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal; // The entity which signed this file
|
||||
PRInt16 mGlobalStatus; // Global signature verification status
|
||||
|
||||
//-- Private functions
|
||||
nsresult ParseManifest();
|
||||
void ReportError(const char* aFilename, PRInt16 errorCode);
|
||||
nsresult CreateInputStream(const char* aFilename, PRBool verify,
|
||||
nsIInputStream** result);
|
||||
nsresult LoadEntry(const char* aFilename, char** aBuf,
|
||||
PRUint32* aBufLen = nsnull);
|
||||
PRInt32 ReadLine(const char** src);
|
||||
nsresult ParseOneFile(const char* filebuf, PRInt16 aFileType,
|
||||
nsIPrincipal* aPrincipal, PRInt16 aPreStatus);
|
||||
nsresult ParseOneFile(const char* filebuf, PRInt16 aFileType);
|
||||
nsresult VerifyEntry(const char* aEntryName, char* aEntryData,
|
||||
PRUint32 aLen);
|
||||
nsresult RestoreModTime(nsZipItem *aItem, nsIFile *aExtractedFile);
|
||||
|
|
|
@ -790,10 +790,8 @@ nsJARChannel::GetOwner(nsISupports* *aOwner)
|
|||
if (!mOwner)
|
||||
{
|
||||
nsCOMPtr<nsIPrincipal> certificate;
|
||||
PRInt16 result;
|
||||
nsresult rv = mJAR->GetCertificatePrincipal(mJAREntry,
|
||||
getter_AddRefs(certificate),
|
||||
&result);
|
||||
getter_AddRefs(certificate));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
if (certificate)
|
||||
{ // Get the codebase principal
|
||||
|
|
|
@ -79,12 +79,6 @@
|
|||
#define PREFS_HEADER_LINE_2 "// This is a generated file!"
|
||||
|
||||
#define INITIAL_MAX_DEFAULT_PREF_FILES 10
|
||||
|
||||
// Preferences that start with this string are subject to a security check
|
||||
#define PREF_SECURITY_PREFIX "security."
|
||||
// Cabability which must be enabled to access preferences starting with PREF_SECURITY_PREFIX
|
||||
#define PREF_SECURITY_ACCESS_CAPABILITY "SecurityPreferenceAccess"
|
||||
|
||||
#include "prefapi_private_data.h"
|
||||
|
||||
#if defined(DEBUG_mcafee)
|
||||
|
@ -275,8 +269,7 @@ nsPref* nsPref::GetInstance()
|
|||
nsresult nsPref::SecurePrefCheck(const char* aPrefName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
/* This will be uncommented very soon. For now, leave it alone. -mstoltz
|
||||
static const char securityPrefix[] = PREF_SECURITY_PREFIX;
|
||||
static const char securityPrefix[] = "security.";
|
||||
if (PL_strnstr(aPrefName, securityPrefix, sizeof(securityPrefix)) == 0)
|
||||
return NS_OK;
|
||||
|
||||
|
@ -285,10 +278,9 @@ nsresult nsPref::SecurePrefCheck(const char* aPrefName)
|
|||
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan, kSecurityManagerCID, &rv);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
PRBool enabled;
|
||||
rv = secMan->IsCapabilityEnabled(PREF_SECURITY_ACCESS_CAPABILITY, &enabled);
|
||||
rv = secMan->IsCapabilityEnabled("SecurityPreferencesAccess", &enabled);
|
||||
if (NS_FAILED(rv) || !enabled)
|
||||
return NS_ERROR_FAILURE;
|
||||
*/
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -790,10 +790,8 @@ nsJARChannel::GetOwner(nsISupports* *aOwner)
|
|||
if (!mOwner)
|
||||
{
|
||||
nsCOMPtr<nsIPrincipal> certificate;
|
||||
PRInt16 result;
|
||||
nsresult rv = mJAR->GetCertificatePrincipal(mJAREntry,
|
||||
getter_AddRefs(certificate),
|
||||
&result);
|
||||
getter_AddRefs(certificate));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
if (certificate)
|
||||
{ // Get the codebase principal
|
||||
|
|
Загрузка…
Ссылка в новой задаче