//--- Class Constructor ---
        static DekiScriptRuntime() {

            // register built-in functions
            _commonFunctions = new Dictionary<XUri, DekiScriptInvocationTargetDescriptor>();
            foreach(MethodInfo method in typeof(DekiScriptLibrary).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)) {

                // check if it has the DekiScriptFunction attribute
                DekiScriptFunctionAttribute functionAttribute = (DekiScriptFunctionAttribute)Attribute.GetCustomAttribute(method, typeof(DekiScriptFunctionAttribute));
                if(functionAttribute != null) {
                    var parameters = from param in method.GetParameters()
                                     let attr = (DekiScriptParamAttribute[])param.GetCustomAttributes(typeof(DekiScriptParamAttribute), false)
                                     select ((attr != null) && (attr.Length > 0)) ? new DekiScriptNativeInvocationTarget.Parameter(attr[0].Hint, attr[0].Optional) : null;
                    var target = new DekiScriptNativeInvocationTarget(null, method, parameters.ToArray());
                    var function = new DekiScriptInvocationTargetDescriptor(target.Access, functionAttribute.IsProperty, functionAttribute.IsIdempotent, functionAttribute.Name ?? method.Name, target.Parameters, target.ReturnType, functionAttribute.Description, functionAttribute.Transform, target);
                    _commonFunctions[new XUri("native:///").At(function.SystemName)] = function;
                }
            }

            // build common env
            DekiScriptMap common = new DekiScriptMap();

            // add global constants
            common.AddNativeValueAt("num.e", Math.E);
            common.AddNativeValueAt("num.pi", Math.PI);
            common.AddNativeValueAt("num.epsilon", double.Epsilon);
            common.AddNativeValueAt("num.positiveinfinity", double.PositiveInfinity);
            common.AddNativeValueAt("num.negativeinfinity", double.NegativeInfinity);
            common.AddNativeValueAt("num.nan", double.NaN);

            // add global functions & properties
            foreach(var function in _commonFunctions) {
                common.AddNativeValueAt(function.Value.Name, function.Key);
            }
            _commonEnv = new DekiScriptEnv(common);
        }
Exemple #2
0
        //--- Class Constructor ---
        static DekiScriptRuntime()
        {
            // register built-in functions
            _commonFunctions = new Dictionary <XUri, DekiScriptInvocationTargetDescriptor>();
            foreach (MethodInfo method in typeof(DekiScriptLibrary).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy))
            {
                // check if it has the DekiScriptFunction attribute
                DekiScriptFunctionAttribute functionAttribute = (DekiScriptFunctionAttribute)Attribute.GetCustomAttribute(method, typeof(DekiScriptFunctionAttribute));
                if (functionAttribute != null)
                {
                    var parameters = from param in method.GetParameters()
                                     let attr = (DekiScriptParamAttribute[])param.GetCustomAttributes(typeof(DekiScriptParamAttribute), false)
                                                select((attr != null) && (attr.Length > 0)) ? new DekiScriptNativeInvocationTarget.Parameter(attr[0].Hint, attr[0].Optional) : null;
                    var target   = new DekiScriptNativeInvocationTarget(null, method, parameters.ToArray());
                    var function = new DekiScriptInvocationTargetDescriptor(target.Access, functionAttribute.IsProperty, functionAttribute.IsIdempotent, functionAttribute.Name ?? method.Name, target.Parameters, target.ReturnType, functionAttribute.Description, functionAttribute.Transform, target);
                    _commonFunctions[new XUri("native:///").At(function.SystemName)] = function;
                }
            }

            // build common env
            DekiScriptMap common = new DekiScriptMap();

            // add global constants
            common.AddNativeValueAt("num.e", Math.E);
            common.AddNativeValueAt("num.pi", Math.PI);
            common.AddNativeValueAt("num.epsilon", double.Epsilon);
            common.AddNativeValueAt("num.positiveinfinity", double.PositiveInfinity);
            common.AddNativeValueAt("num.negativeinfinity", double.NegativeInfinity);
            common.AddNativeValueAt("num.nan", double.NaN);

            // add global functions & properties
            foreach (var function in _commonFunctions)
            {
                common.AddNativeValueAt(function.Value.Name, function.Key);
            }
            _commonEnv = new DekiScriptEnv(common);
        }
        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);
        }