Back to index

lightning-sunbird  0.9+nobinonly
nsJSConfigTriggers.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  *   Mitesh Shah <mitesh@netscape.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #ifdef MOZ_LOGGING
00040 // sorry, this has to be before the pre-compiled header
00041 #define FORCE_PR_LOG /* Allow logging in the release build */
00042 #endif
00043 #include "jsapi.h"
00044 #include "nsIXPCSecurityManager.h"
00045 #include "nsIXPConnect.h"
00046 #include "nsIJSRuntimeService.h"
00047 #include "nsCOMPtr.h"
00048 #include "nsIGenericFactory.h"
00049 #include "nsIServiceManager.h"
00050 #include "nsIComponentManager.h"
00051 #include "nsString.h"
00052 #include "nsIPrefService.h"
00053 #include "nsIJSContextStack.h"
00054 #include "nspr.h"
00055 
00056 extern PRLogModuleInfo *MCD;
00057 
00058 // Security Manager for new XPCONNECT enabled JS Context
00059 // Right now it allows all access
00060 
00061 class AutoConfigSecMan : public nsIXPCSecurityManager
00062 {
00063 public:
00064     NS_DECL_ISUPPORTS
00065     NS_DECL_NSIXPCSECURITYMANAGER
00066     AutoConfigSecMan();
00067 };
00068 
00069 NS_IMPL_ISUPPORTS1(AutoConfigSecMan, nsIXPCSecurityManager)
00070 
00071 AutoConfigSecMan::AutoConfigSecMan()
00072 {
00073 }
00074 
00075 NS_IMETHODIMP
00076 AutoConfigSecMan::CanCreateWrapper(JSContext *aJSContext, const nsIID & aIID, 
00077                                   nsISupports *aObj, nsIClassInfo *aClassInfo, 
00078                                   void **aPolicy)
00079 {
00080     return NS_OK;
00081 }
00082 
00083 NS_IMETHODIMP
00084 AutoConfigSecMan::CanCreateInstance(JSContext *aJSContext, const nsCID & aCID)
00085 {
00086     return NS_OK;
00087 }
00088 
00089 NS_IMETHODIMP
00090 AutoConfigSecMan::CanGetService(JSContext *aJSContext, const nsCID & aCID)
00091 {
00092     return NS_OK;
00093 }
00094 
00095 NS_IMETHODIMP 
00096 AutoConfigSecMan::CanAccess(PRUint32 aAction, 
00097                             nsIXPCNativeCallContext *aCallContext, 
00098                             JSContext *aJSContext, JSObject *aJSObject, 
00099                             nsISupports *aObj, nsIClassInfo *aClassInfo, 
00100                             jsval aName, void **aPolicy)
00101 {
00102     return NS_OK;
00103 }
00104 
00105 //*****************************************************************************
00106 
00107 static  JSContext *autoconfig_cx = nsnull;
00108 static  JSObject *autoconfig_glob;
00109 
00110 static JSClass global_class = {
00111     "autoconfig_global", 0,
00112     JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
00113     JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   JS_FinalizeStub
00114 };
00115 
00116 JS_STATIC_DLL_CALLBACK(void)
00117 autoConfigErrorReporter(JSContext *cx, const char *message, 
00118                         JSErrorReport *report)
00119 {
00120     NS_ERROR(message);
00121     PR_LOG(MCD, PR_LOG_DEBUG, ("JS error in js from MCD server: %s\n", message));
00122 } 
00123 
00124 nsresult CentralizedAdminPrefManagerInit()
00125 {
00126     nsresult rv;
00127     JSRuntime *rt;
00128 
00129     // If autoconfig_cx already created, no need to create it again
00130     if (autoconfig_cx) 
00131         return NS_OK;
00132 
00133     // We need the XPCONNECT service
00134     nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
00135     if (NS_FAILED(rv)) {
00136         return rv;
00137     }
00138 
00139     // Get the JS RunTime
00140     nsCOMPtr<nsIJSRuntimeService> rtsvc = 
00141         do_GetService("@mozilla.org/js/xpc/RuntimeService;1", &rv);
00142     if (NS_SUCCEEDED(rv))
00143         rv = rtsvc->GetRuntime(&rt);
00144 
00145     if (NS_FAILED(rv)) {
00146         NS_ERROR("Couldn't get JS RunTime");
00147         return rv;
00148     }
00149 
00150     // Create a new JS context for autoconfig JS script
00151     autoconfig_cx = JS_NewContext(rt, 1024);
00152     if (!autoconfig_cx)
00153         return NS_ERROR_OUT_OF_MEMORY;
00154 
00155     JS_SetErrorReporter(autoconfig_cx, autoConfigErrorReporter);
00156 
00157     // Create a new Security Manger and set it for the new JS context
00158     nsCOMPtr<nsIXPCSecurityManager> secman =
00159         NS_STATIC_CAST(nsIXPCSecurityManager*, new AutoConfigSecMan());
00160     xpc->SetSecurityManagerForJSContext(autoconfig_cx, secman, 0);
00161 
00162     autoconfig_glob = JS_NewObject(autoconfig_cx, &global_class, NULL, NULL);
00163     if (autoconfig_glob) {
00164         if (JS_InitStandardClasses(autoconfig_cx, autoconfig_glob)) {
00165             // XPCONNECT enable this JS context
00166             rv = xpc->InitClasses(autoconfig_cx, autoconfig_glob);
00167             if (NS_SUCCEEDED(rv)) 
00168                 return NS_OK;
00169         }
00170     }
00171 
00172     // failue exit... clean up the JS context
00173     JS_DestroyContext(autoconfig_cx);
00174     autoconfig_cx = nsnull;
00175     return NS_ERROR_FAILURE;
00176 }
00177 
00178 nsresult CentralizedAdminPrefManagerFinish()
00179 {
00180     if (autoconfig_cx)
00181         JS_DestroyContext(autoconfig_cx);
00182     return NS_OK;
00183 }
00184 
00185 nsresult EvaluateAdminConfigScript(const char *js_buffer, size_t length,
00186                                    const char *filename, PRBool bGlobalContext, 
00187                                    PRBool bCallbacks, PRBool skipFirstLine)
00188 {
00189     JSBool ok;
00190     jsval result;
00191 
00192     if (skipFirstLine) {
00193         /* In order to protect the privacy of the JavaScript preferences file 
00194          * from loading by the browser, we make the first line unparseable
00195          * by JavaScript. We must skip that line here before executing 
00196          * the JavaScript code.
00197          */
00198         unsigned int i = 0;
00199         while (i < length) {
00200             char c = js_buffer[i++];
00201             if (c == '\r') {
00202                 if (js_buffer[i] == '\n')
00203                     i++;
00204                 break;
00205             }
00206             if (c == '\n')
00207                 break;
00208         }
00209 
00210         length -= i;
00211         js_buffer += i;
00212     }
00213 
00214     nsresult rv;
00215     nsCOMPtr<nsIJSContextStack> cxstack = 
00216         do_GetService("@mozilla.org/js/xpc/ContextStack;1");
00217     rv = cxstack->Push(autoconfig_cx);
00218     if (NS_FAILED(rv)) {
00219         NS_ERROR("coudn't push the context on the stack");
00220         return rv;
00221     }
00222 
00223     JS_BeginRequest(autoconfig_cx);
00224     ok = JS_EvaluateScript(autoconfig_cx, autoconfig_glob,
00225                            js_buffer, length, filename, 0, &result);
00226     JS_EndRequest(autoconfig_cx);
00227 
00228     JS_MaybeGC(autoconfig_cx);
00229 
00230     JSContext *cx;
00231     cxstack->Pop(&cx);
00232     NS_ASSERTION(cx == autoconfig_cx, "AutoConfig JS contexts didn't match");
00233 
00234     if (ok)
00235         return NS_OK;
00236     return NS_ERROR_FAILURE;
00237 }
00238