protected override Yield Start(XDoc config, Result result) { yield return(Coroutine.Invoke(base.Start, config, new Result())); // loop over all resources Type type = GetType(); string assembly = type.Assembly.FullName.Split(new char[] { ',' }, 2)[0]; foreach (DekiExtLibraryFilesAttribute files in Attribute.GetCustomAttributes(type, typeof(DekiExtLibraryFilesAttribute))) { string prefix = files.Prefix ?? type.Namespace; foreach (string filename in files.Filenames) { MimeType mime = MimeType.FromFileExtension(filename); _files[filename] = Plug.New(string.Format("resource://{0}/{1}.{2}", assembly, prefix, filename)).With("dream.out.type", mime.FullType); } } // check if a public digital signature key was provided string dsaKey = config["deki-signature"].AsText ?? config["dekiwiki-signature"].AsText; if (dsaKey != null) { try { DSACryptoServiceProvider dsa = new DSACryptoServiceProvider(); dsa.ImportCspBlob(Convert.FromBase64String(dsaKey)); _publicDigitalSignature = dsa; } catch { throw new ArgumentException("invalid digital signature provided", "deki-signature"); } } // loop over all instance methods foreach (MethodInfo method in type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { // check if it has the DekiExtFunction attriute DekiExtFunctionAttribute ext = (DekiExtFunctionAttribute)Attribute.GetCustomAttribute(method, typeof(DekiExtFunctionAttribute)); if (ext != null) { // check if function has an associated script XDekiScript script = null; DekiExtFunctionScriptAttribute scriptAttr = (DekiExtFunctionScriptAttribute)Attribute.GetCustomAttribute(method, typeof(DekiExtFunctionScriptAttribute)); if (scriptAttr != null) { DreamMessage scriptresource = Plug.New(string.Format("resource://{0}/{1}.{2}", assembly, scriptAttr.Prefix ?? type.Namespace, scriptAttr.Scriptname)).With("dream.out.type", MimeType.XML.FullType).GetAsync().Wait(); if (scriptresource.IsSuccessful) { script = new XDekiScript(scriptresource.ToDocument()); } if (script == null) { throw new InvalidOperationException(string.Format("method '{0}' is declard as script, but script could not be loaded", method.Name)); } } // add function Add(ext, method, script); } } // add configuration settings var context = DreamContext.Current; _scriptConfig = new DekiScriptMap(); foreach (KeyValuePair <string, string> entry in Config.ToKeyValuePairs()) { XUri local; if (XUri.TryParse(entry.Value, out local)) { local = context.AsPublicUri(local); _scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(local.ToString())); } else { _scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(entry.Value)); } } result.Return(); }
private void LoadScript() { _manifestPath = null; _resourcesPath = null; _manifestUri = null; _resourcesUri = null; _manifest = null; // read manifest _manifestPath = Config["manifest"].AsText; if(string.IsNullOrEmpty(_manifestPath)) { throw new ArgumentNullException("manifest"); } _manifestUri = XUri.TryParse(_manifestPath); if(_manifestUri != null) { _manifestPath = null; _manifest = Plug.New(_manifestUri).Get().ToDocument(); _resourcesUri = Config["resources"].AsUri ?? _manifestUri.WithoutLastSegment(); } else { _manifest = XDocFactory.LoadFrom(_manifestPath, MimeType.XML); _resourcesPath = Config["resources"].AsText ?? Path.GetDirectoryName(_manifestPath); } if(!_manifest.HasName("extension")) { throw new ArgumentException("invalid extension manifest"); } // initilize runtime _runtime = new DekiScriptRuntime(); // read manifest settings _title = _manifest["title"].AsText; _label = _manifest["label"].AsText; _copyright = _manifest["copyright"].AsText; _description = _manifest["description"].AsText; _help = _manifest["uri.help"].AsText; _logo = _manifest["uri.logo"].AsText; _namespace = _manifest["namespace"].AsText; // initialize evaluation environment _commonEnv = _runtime.CreateEnv(); // read functions _functions = new Dictionary<XUri, DekiScriptInvocationTargetDescriptor>(); foreach(var function in _manifest["function"]) { var descriptor = ConvertFunction(function); if(descriptor != null) { var uri = Self.At(descriptor.SystemName); DekiScriptInvocationTargetDescriptor old; if(_functions.TryGetValue(uri, out old)) { _log.WarnFormat("duplicate function name {0} in script {1}", descriptor.Name, _manifestUri); } _functions[uri] = descriptor; } } _runtime.RegisterExtensionFunctions(_functions); // add extension functions to env foreach(var function in _functions) { _commonEnv.Vars.AddNativeValueAt(function.Value.Name.ToLowerInvariant(), function.Key); } // add configuration settings DreamContext context = DreamContext.Current; DekiScriptMap scriptConfig = new DekiScriptMap(); foreach(KeyValuePair<string, string> entry in Config.ToKeyValuePairs()) { XUri local; if(XUri.TryParse(entry.Value, out local)) { local = context.AsPublicUri(local); scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(local.ToString())); } else { scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(entry.Value)); } } _commonEnv.Vars.Add("config", scriptConfig); }
public static DekiScriptMap GetImplicitEnvironment(DreamMessage message, DSACryptoServiceProvider publicDigitalSignature) { DekiScriptMap env = new DekiScriptMap(); // retrieve implicit arguments string[] headers = message.Headers.GetValues(IMPLICIT_ENVIRONMENT_HEADER); if (!ArrayUtil.IsNullOrEmpty(headers)) { env.AddAt("__implicit", new DekiScriptList(new ArrayList(headers))); foreach (string implicitArg in headers) { foreach (KeyValuePair <string, string> arg in HttpUtil.ParseNameValuePairs(implicitArg)) { env.AddNativeValueAt(arg.Key, arg.Value); } } } if (publicDigitalSignature != null) { bool valid = false; try { Dictionary <string, string> values = HttpUtil.ParseNameValuePairs(message.Headers[IMPLICIT_SIGNATURE_HEADER]); // verify date DateTime date = DateTime.Parse(values["date"]).ToUniversalTime(); double delta = DateTime.UtcNow.Subtract(date).TotalSeconds; if ((delta < -60) || (delta > 60)) { throw new DreamAbortException(DreamMessage.Forbidden("date in message signature is too far apart from server date")); } // verify message MemoryStream data = new MemoryStream(); byte[] bytes = null; // get message bytes bytes = message.AsBytes(); data.Write(bytes, 0, bytes.Length); // retrieve headers to verify if (!ArrayUtil.IsNullOrEmpty(headers)) { Array.Sort(headers, StringComparer.Ordinal); bytes = Encoding.UTF8.GetBytes(string.Join(",", headers)); data.Write(bytes, 0, bytes.Length); } // add request date bytes = Encoding.UTF8.GetBytes(values["date"]); data.Write(bytes, 0, bytes.Length); // verify signature byte[] signature = Convert.FromBase64String(values["dsig"]); valid = publicDigitalSignature.VerifyData(data.GetBuffer(), signature); } catch (Exception e) { if (e is DreamAbortException) { throw; } } if (!valid) { throw new DreamAbortException(DreamMessage.Forbidden("invalid or missing digital signature")); } } return(env); }
private void LoadScript() { _manifestPath = null; _resourcesPath = null; _manifestUri = null; _resourcesUri = null; _manifest = null; // read manifest _manifestPath = Config["manifest"].AsText; if (string.IsNullOrEmpty(_manifestPath)) { throw new ArgumentNullException("manifest"); } _manifestUri = XUri.TryParse(_manifestPath); if (_manifestUri != null) { _manifestPath = null; _manifest = Plug.New(_manifestUri).Get().ToDocument(); _resourcesUri = Config["resources"].AsUri ?? _manifestUri.WithoutLastSegment(); } else { _manifest = XDocFactory.LoadFrom(_manifestPath, MimeType.XML); _resourcesPath = Config["resources"].AsText ?? Path.GetDirectoryName(_manifestPath); } if (!_manifest.HasName("extension")) { throw new ArgumentException("invalid extension manifest"); } // initilize runtime _runtime = new DekiScriptRuntime(); // read manifest settings _title = _manifest["title"].AsText; _label = _manifest["label"].AsText; _copyright = _manifest["copyright"].AsText; _description = _manifest["description"].AsText; _help = _manifest["uri.help"].AsText; _logo = _manifest["uri.logo"].AsText; _namespace = _manifest["namespace"].AsText; // initialize evaluation environment _commonEnv = _runtime.CreateEnv(); // read functions _functions = new Dictionary <XUri, DekiScriptInvocationTargetDescriptor>(); foreach (var function in _manifest["function"]) { var descriptor = ConvertFunction(function); if (descriptor != null) { var uri = Self.At(descriptor.SystemName); DekiScriptInvocationTargetDescriptor old; if (_functions.TryGetValue(uri, out old)) { _log.WarnFormat("duplicate function name {0} in script {1}", descriptor.Name, _manifestUri); } _functions[uri] = descriptor; } } _runtime.RegisterExtensionFunctions(_functions); // add extension functions to env foreach (var function in _functions) { _commonEnv.Vars.AddNativeValueAt(function.Value.Name.ToLowerInvariant(), function.Key); } // add configuration settings DreamContext context = DreamContext.Current; DekiScriptMap scriptConfig = new DekiScriptMap(); foreach (KeyValuePair <string, string> entry in Config.ToKeyValuePairs()) { XUri local; if (XUri.TryParse(entry.Value, out local)) { local = context.AsPublicUri(local); scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(local.ToString())); } else { scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(entry.Value)); } } _commonEnv.Vars.Add("config", scriptConfig); }