Back to index

lightning-sunbird  0.9+nobinonly
nsCSecurityContext.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 /*
00038  *
00039  * It contains the implementation providing nsISecurityCOntext XP-COM interface.
00040  * This file snapshots a JS frame before entering into java.
00041  *
00042  */
00043 
00044 
00045 #include <stdlib.h>
00046 #include <string.h>
00047 #include "prtypes.h"
00048 #include "jscntxt.h"
00049 #include "jsdbgapi.h"
00050 #include "nsCSecurityContext.h"
00051 #include "nsIScriptContext.h"
00052 #include "jvmmgr.h"
00053 #include "jsjava.h"
00054 
00055 // For GetOrigin()
00056 
00057 #include "nsIScriptSecurityManager.h"
00058 #include "nsIServiceManager.h"
00059 #include "nsCRT.h"
00060 
00061 #include "nsTraceRefcnt.h"
00062 
00063 static NS_DEFINE_IID(kISecurityContextIID, NS_ISECURITYCONTEXT_IID);
00064 static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
00065 
00066 
00068 // nsISupports 
00069 
00070 NS_IMPL_ISUPPORTS1(nsCSecurityContext, nsISecurityContext)
00071 
00072 
00073 // nsISecurityContext
00074 
00075 NS_METHOD 
00076 nsCSecurityContext::Implies(const char* target, const char* action, PRBool *bAllowedAccess)
00077 {
00078     if(!bAllowedAccess) {
00079         return NS_ERROR_FAILURE;
00080     }
00081   
00082     if(!nsCRT::strcmp(target,"UniversalBrowserRead")) {
00083         // XXX we lie to the applet and say we have UniversalBrowserRead
00084         // even if we don't so that we can bypass the Java plugin's broken
00085         // origin checks.  Note that this only affects the plugin's perception
00086         // of our script's capabilities, and has no bearing on the script's
00087         // real capabilities. This code should be changed to assign
00088         // |m_HasUniversalBrowserReadCapability| into the out parameter
00089         // once Java's origin checking code is fixed.
00090         // See bug 146458 for details.
00091         if (JSJ_IsJSCallApplet()) {
00092             *bAllowedAccess = PR_TRUE;
00093         }
00094         else {
00095             *bAllowedAccess = m_HasUniversalBrowserReadCapability;
00096         }
00097     } else if(!nsCRT::strcmp(target,"UniversalJavaPermission")) {
00098         *bAllowedAccess = m_HasUniversalJavaCapability;
00099     } else {
00100         *bAllowedAccess = PR_FALSE;
00101     }
00102 
00103     return NS_OK;
00104 }
00105 
00106 
00107 NS_METHOD 
00108 nsCSecurityContext::GetOrigin(char* buf, int buflen)
00109 {
00110     if (!m_pPrincipal) {
00111         // Get the Script Security Manager.
00112         nsresult rv = NS_OK;
00113         nsCOMPtr<nsIScriptSecurityManager> secMan =
00114              do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
00115         if (NS_FAILED(rv) || !secMan) {
00116             return NS_ERROR_FAILURE;
00117         }
00118 
00119         secMan->GetSubjectPrincipal(getter_AddRefs(m_pPrincipal));
00120         if (!m_pPrincipal) {
00121             return NS_ERROR_FAILURE;
00122         }
00123     }
00124 
00125     nsXPIDLCString origin;
00126     m_pPrincipal->GetOrigin(getter_Copies(origin));
00127 
00128     PRInt32 originlen = origin.Length();
00129     if (origin.IsEmpty() || originlen > buflen - 1) {
00130         return NS_ERROR_FAILURE;
00131     }
00132 
00133     // Copy the string into to user supplied buffer. Is there a better
00134     // way to do this?
00135 
00136     memcpy(buf, origin, originlen);
00137     buf[originlen] = nsnull; // Gotta terminate it.
00138 
00139     return NS_OK;
00140 }
00141 
00142 NS_METHOD 
00143 nsCSecurityContext::GetCertificateID(char* buf, int buflen)
00144 {
00145     nsCOMPtr<nsIPrincipal> principal;
00146   
00147     // Get the Script Security Manager.
00148 
00149     nsresult rv      = NS_OK;
00150     nsCOMPtr<nsIScriptSecurityManager> secMan = 
00151              do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
00152     if (NS_FAILED(rv) || !secMan) return NS_ERROR_FAILURE;
00153 
00154     secMan->GetSubjectPrincipal(getter_AddRefs(principal));
00155     if (!principal) {
00156         return NS_ERROR_FAILURE;
00157     }
00158 
00159     nsCAutoString certificate;
00160     principal->GetFingerprint(certificate);
00161 
00162     PRInt32 certlen = certificate.Length();
00163     if (buflen <= certlen) {
00164         return NS_ERROR_FAILURE;
00165     }
00166 
00167     memcpy(buf, certificate.get(), certlen);
00168     buf[certlen] = nsnull;
00169 
00170     return NS_OK;
00171 }
00172 
00174 // from nsCSecurityContext:
00175 extern PRUintn tlsIndex3_g;
00176 
00177 MOZ_DECL_CTOR_COUNTER(nsCSecurityContext)
00178 
00179 nsCSecurityContext::nsCSecurityContext(JSContext* cx)
00180                    : m_pJStoJavaFrame(NULL), m_pJSCX(cx),
00181                      m_pPrincipal(NULL),
00182                      m_HasUniversalJavaCapability(PR_FALSE),
00183                      m_HasUniversalBrowserReadCapability(PR_FALSE)
00184 {
00185     MOZ_COUNT_CTOR(nsCSecurityContext);
00186 
00187       // Get the Script Security Manager.
00188 
00189     nsresult rv = NS_OK;
00190     nsCOMPtr<nsIScriptSecurityManager> secMan = 
00191              do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
00192     if (NS_FAILED(rv) || !secMan) return;
00193 
00194     
00195     nsCOMPtr<nsIPrincipal> principal;
00196     if (NS_FAILED(secMan->GetSubjectPrincipal(getter_AddRefs(principal))))
00197         // return;
00198         ; // Don't return here because the security manager returns 
00199           // NS_ERROR_FAILURE when there is no subject principal. In
00200           // that case we are not done.
00201 
00202     nsCOMPtr<nsIPrincipal> sysprincipal;
00203     if (NS_FAILED(secMan->GetSystemPrincipal(getter_AddRefs(sysprincipal))))
00204         return;
00205 
00206     // Do early evaluation of "UniversalJavaPermission" capability.
00207 
00208     PRBool equals;
00209     if (!principal || 
00210         NS_SUCCEEDED(principal->Equals(sysprincipal, &equals)) && equals) {
00211         // We have native code or the system principal: just allow general access
00212         m_HasUniversalBrowserReadCapability = PR_TRUE;
00213         m_HasUniversalJavaCapability = PR_TRUE;
00214     }
00215     else {
00216         // Otherwise, check with the js security manager.
00217         secMan->IsCapabilityEnabled("UniversalBrowserRead",&m_HasUniversalBrowserReadCapability);
00218         secMan->IsCapabilityEnabled("UniversalJavaPermission",&m_HasUniversalJavaCapability);
00219     }
00220 }
00221 
00222 nsCSecurityContext::nsCSecurityContext(nsIPrincipal *principal)
00223                    : m_pJStoJavaFrame(NULL), m_pJSCX(NULL),
00224                      m_pPrincipal(principal),
00225                      m_HasUniversalJavaCapability(PR_FALSE),
00226                      m_HasUniversalBrowserReadCapability(PR_FALSE)
00227 {
00228     MOZ_COUNT_CTOR(nsCSecurityContext);
00229 
00230       // Get the Script Security Manager.
00231 
00232     nsresult rv = NS_OK;
00233     nsCOMPtr<nsIScriptSecurityManager> secMan = 
00234              do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
00235     if (NS_FAILED(rv) || !secMan) return;
00236 
00237     nsCOMPtr<nsIPrincipal> sysprincipal;
00238     if (NS_FAILED(secMan->GetSystemPrincipal(getter_AddRefs(sysprincipal))))
00239         return;
00240 
00241     // Do early evaluation of "UniversalJavaPermission" capability.
00242 
00243     if (!m_pPrincipal || m_pPrincipal == sysprincipal) {
00244         // We have native code or the system principal: just allow general access
00245         m_HasUniversalBrowserReadCapability = PR_TRUE;
00246         m_HasUniversalJavaCapability = PR_TRUE;
00247     }
00248     else {
00249         // Otherwise, check with the js security manager.
00250         secMan->IsCapabilityEnabled("UniversalBrowserRead",&m_HasUniversalBrowserReadCapability);
00251         secMan->IsCapabilityEnabled("UniversalJavaPermission",&m_HasUniversalJavaCapability);
00252     }
00253 }
00254 
00255 nsCSecurityContext::~nsCSecurityContext()
00256 {
00257   MOZ_COUNT_DTOR(nsCSecurityContext);
00258 }
00259