void KPRPCReceiveJSONRPC(JSONRPCContainer jsonrpcEncrypted, KeePassRPCService service)
        {
            string        jsonrpc = Decrypt(jsonrpcEncrypted);
            StringBuilder sb      = new StringBuilder();

            JsonRpcDispatcher dispatcher = JsonRpcDispatcherFactory.CreateDispatcher(service);

            dispatcher.Process(new StringReader(jsonrpc),
                               new StringWriter(sb), Authorised);
            string output = sb.ToString();

            KPRPCMessage data2client = new KPRPCMessage();

            data2client.protocol = "jsonrpc";
            data2client.version  = ProtocolVersion;
            data2client.jsonrpc  = Encrypt(output);

            // If there was a problem encrypting our message, respond to the
            // client with a non-encrypted error message
            if (data2client.jsonrpc == null)
            {
                data2client          = new KPRPCMessage();
                data2client.protocol = "error";
                data2client.version  = ProtocolVersion;
                data2client.error    = new Error(ErrorCode.AUTH_RESTART, new string[] { "Encryption error" });
                this.Authorised      = false;
                if (KPRPC.logger != null)
                {
                    KPRPC.logger.WriteLine("Encryption error when trying to reply to client message");
                }
            }
            _webSocketConnection.Send(Jayrock.Json.Conversion.JsonConvert.ExportToString(data2client));
        }
Exemple #2
0
        protected override void ProcessRequest()
        {
            if (!CaselessString.Equals(Request.RequestType, "POST"))
            {
                throw new JsonRpcException(string.Format("HTTP {0} is not supported for RPC execution. Use HTTP POST only.", Request.RequestType));
            }

            //
            // Sets the "Cache-Control" header value to "no-cache".
            // NOTE: It does not send the common HTTP 1.0 request directive
            // "Pragma" with the value "no-cache".
            //

            Response.Cache.SetCacheability(HttpCacheability.NoCache);

            //
            // Response will be plain text, though it would have been nice to
            // be more specific, like text/json.
            //

            Response.ContentType = "text/plain";

            //
            // Delegate rest of the work to JsonRpcServer.
            //

            JsonRpcDispatcher dispatcher = new JsonRpcDispatcher(Service);

            if (HttpRequestSecurity.IsLocal(Request))
                dispatcher.SetLocalExecution();

            using (TextReader reader = GetRequestReader())
                dispatcher.Process(reader, Response.Output);
        }
Exemple #3
0
        public bool AddService(IService service)
        {
            // check duplicate method names
            foreach (var method in service.GetClass().GetMethods())
            {
                if (mInternalRpcMethods.ContainsKey(method.Name))
                {
                    return(false);
                }
            }

            var dispatcher = new JsonRpcDispatcher(service);

            foreach (var method in service.GetClass().GetMethods())
            {
                //if (!method.Name.Contains("system."))
                mInternalRpcMethods.TryAdd(method.Name, dispatcher);
            }

            if (OnListChanged != null)
            {
                OnListChanged(Methods());
            }

            // debug
            PrintInernalMethods();
            return(true);
        }
Exemple #4
0
        protected override void ProcessRequest()
        {
            if (!CaselessString.Equals(Request.RequestType, "POST"))
            {
                throw new JsonRpcException(string.Format("HTTP {0} is not supported for RPC execution. Use HTTP POST only.", Request.RequestType));
            }

            //
            // Sets the "Cache-Control" header value to "no-cache".
            // NOTE: It does not send the common HTTP 1.0 request directive
            // "Pragma" with the value "no-cache".
            //

            Response.Cache.SetCacheability(HttpCacheability.NoCache);

            //
            // Response will be plain text, though it would have been nice to
            // be more specific, like text/json.
            //

            Response.ContentType = "application/json";

            //
            // Delegate rest of the work to JsonRpcServer.
            //

            JsonRpcDispatcher dispatcher = JsonRpcDispatcherFactory.CreateDispatcher(Service);

            using (new JsonRpcDispatchScope(dispatcher, Context))
                using (TextReader reader = GetRequestReader())
                    dispatcher.Process(reader, Response.Output);
        }
        protected override void ProcessRequest()
        {
            //
            // Sets the "Cache-Control" header value to "no-cache".
            // NOTE: It does not send the common HTTP 1.0 request directive
            // "Pragma" with the value "no-cache".
            //

            Response.Cache.SetCacheability(HttpCacheability.NoCache);

            //
            // Response will be plain text, though it would have been nice to 
            // be more specific, like text/json.
            //

            Response.ContentType = "text/plain";

            //
            // Delegate rest of the work to JsonRpcServer.
            //

            JsonRpcDispatcher dispatcher = new JsonRpcDispatcher(TargetService);
            
            if (HttpRequestSecurity.IsLocal(Request))
                dispatcher.SetLocalExecution();

            using (StreamReader reader = new StreamReader(Request.InputStream, Request.ContentEncoding))
                dispatcher.Process(reader, Response.Output);
        }
        public JsonRpcDispatchScope(JsonRpcDispatcher dispatcher, HttpContext context)
        {
            Debug.Assert(dispatcher != null);
            Debug.Assert(context != null);

            //
            // Setup for local execution if client request is from the same
            // machine. The dispatcher uses this to determine whether to
            // emit a detailed stack trace or not in the event of an error.
            //

            if (HttpRequestSecurity.IsLocal(context.Request))
            {
                dispatcher.LocalExecution = true;
            }

            //
            // Initialize the import and export contexts, which are pooled
            // per-application instance.
            //

            IDictionary appVars = AppVars.Get(context.ApplicationInstance);

            ExportContext expctx = (ExportContext)appVars[typeof(ExportContext)];

            if (expctx == null)
            {
                expctx = JsonConvert.CreateExportContext();
                appVars.Add(typeof(ExportContext), expctx);
            }

            dispatcher.JsonExporter = new JsonExportHandler(expctx.Export);

            ImportContext impctx = (ImportContext)appVars[typeof(ImportContext)];

            if (impctx == null)
            {
                impctx = JsonConvert.CreateImportContext();
                appVars.Add(typeof(ImportContext), impctx);
            }

            dispatcher.JsonImporter = new JsonImportHandler(impctx.Import);

            _impctx = impctx;
            _expctx = expctx;
        }
        public JsonRpcDispatchScope(JsonRpcDispatcher dispatcher, HttpContext context)
        {
            Debug.Assert(dispatcher != null);
            Debug.Assert(context != null);

            //
            // Setup for local execution if client request is from the same
            // machine. The dispatcher uses this to determine whether to
            // emit a detailed stack trace or not in the event of an error.
            //

            if (HttpRequestSecurity.IsLocal(context.Request))
                dispatcher.LocalExecution = true;

            //
            // Initialize the import and export contexts, which are pooled
            // per-application instance.
            //

            IDictionary appVars = AppVars.Get(context.ApplicationInstance);

            ExportContext expctx = (ExportContext) appVars[typeof(ExportContext)];

            if (expctx == null)
            {
                expctx = JsonConvert.CreateExportContext();
                appVars.Add(typeof(ExportContext), expctx);
            }

            dispatcher.JsonExporter = new JsonExportHandler(expctx.Export);

            ImportContext impctx = (ImportContext) appVars[typeof(ImportContext)];

            if (impctx == null)
            {
                impctx = JsonConvert.CreateImportContext();
                appVars.Add(typeof(ImportContext), impctx);
            }

            dispatcher.JsonImporter = new JsonImportHandler(impctx.Import);

            _impctx = impctx;
            _expctx = expctx;
        }
Exemple #8
0
        /// <summary>
        /// Добавить json сервис в обработчик
        /// </summary>
        /// <param name="aService"></param>
        /// <returns></returns>
        public bool AddService(IService aService)
        {
            // check duplicate method names
            foreach (var method in aService.GetClass().GetMethods())
            {
                if (mRpcMethods.ContainsKey(method.Name))
                {
                    return(false);
                }
            }

            var dispatcher = new JsonRpcDispatcher(aService);

            foreach (var method in aService.GetClass().GetMethods())
            {
                mRpcMethods.Add(method.Name, dispatcher);
            }

            //Debug.WriteLine(aService.GetClass() + " succefully registered");
            return(true);
        }
        protected override void ProcessRequest()
        {
            string httpMethod = Request.RequestType;

            if (!CaselessString.Equals(httpMethod, "GET") &&
                !CaselessString.Equals(httpMethod, "HEAD"))
            {
                throw new JsonRpcException(string.Format("HTTP {0} is not supported for RPC execution. Use HTTP GET or HEAD only.", httpMethod));
            }

            string callback = Mask.NullString(Request.QueryString["jsonp"]);
            bool padded = callback.Length > 0;
            
            //
            // The response type depends on whether JSONP (JSON with 
            // Padding) is in effect or not.
            //

            Response.ContentType = padded ? "text/javascript" : "application/json";
            
            //
            // Validate that the JSONP callback method conforms to the 
            // allowed syntax. If not, issue a client-side exception
            // that will certainly help to bring problem to light, even if
            // a little too aggressively.
            //
            
            if (padded)
            {
                if (!_jsonpex.IsMatch(callback))
                {
                    Response.Write("throw new Error('Invalid JSONP callback parameter value.');");
                    Response.End();
                }
            }
            
            //
            // Convert the query string into a call object.
            //

            JsonWriter writer = new JsonTextWriter();
            
            writer.WriteStartObject();
            
            writer.WriteMember("id");
            writer.WriteNumber(-1);
            
            writer.WriteMember("method");
            
            string methodName = Mask.NullString(Request.PathInfo);
            
            if (methodName.Length == 0)
            {
                writer.WriteNull();
            }
            else
            {
                //
                // If the method name contains periods then we replace it
                // with dashes to mean the one and same thing. This is
                // done to provide dashes as an alternative to some periods
                // since some web servers may block requests (for security
                // reasons) if a path component of the URL contains more
                // than one period.
                //
                
                writer.WriteString(methodName.Substring(1).Replace('-', '.'));
            }
            
            writer.WriteMember("params");
            NameValueCollection query = new NameValueCollection(Request.QueryString);
            query.Remove(string.Empty);
            JsonConvert.Export(Request.QueryString, writer);
            
            writer.WriteEndObject();
            
            //
            // Delegate rest of the work to JsonRpcDispatcher.
            //

            JsonRpcDispatcher dispatcher = new JsonRpcDispatcher(Service);
            using (new JsonRpcDispatchScope(dispatcher, Context))
            {
                dispatcher.RequireIdempotency = true;

                if (padded)
                {
                    //
                    // For JSONP, see details here:
                    // http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/
                    //

                    Response.Write(callback);
                    Response.Write('(');
                }

                dispatcher.Process(new StringReader(writer.ToString()), Response.Output);

                if (padded)
                    Response.Write(')');
            }
        }
Exemple #10
0
        protected override void ProcessRequest()
        {
            string httpMethod = Request.RequestType;

            if (!CaselessString.Equals(httpMethod, "GET") &&
                !CaselessString.Equals(httpMethod, "HEAD"))
            {
                throw new JsonRpcException(string.Format("HTTP {0} is not supported for RPC execution. Use HTTP GET or HEAD only.", httpMethod));
            }

            string callback = Mask.NullString(Request.QueryString["jsonp"]);
            bool   padded   = callback.Length > 0;

            //
            // The response type depends on whether JSONP (JSON with
            // Padding) is in effect or not.
            //

            Response.ContentType = padded ? "text/javascript" : "application/json";

            //
            // Validate that the JSONP callback method conforms to the
            // allowed syntax. If not, issue a client-side exception
            // that will certainly help to bring problem to light, even if
            // a little too aggressively.
            //

            if (padded)
            {
                if (!_jsonpex.IsMatch(callback))
                {
                    Response.Write("throw new Error('Invalid JSONP callback parameter value.');");
                    Response.End();
                }
            }

            //
            // Convert the query string into a call object.
            //

            StringWriter sw     = new StringWriter();
            JsonWriter   writer = JsonText.CreateWriter(sw);

            writer.WriteStartObject();

            writer.WriteMember("id");
            writer.WriteNumber(-1);

            writer.WriteMember("method");

            string methodName = Mask.NullString(Request.PathInfo);

            if (methodName.Length == 0)
            {
                writer.WriteNull();
            }
            else
            {
                //
                // If the method name contains periods then we replace it
                // with dashes to mean the one and same thing. This is
                // done to provide dashes as an alternative to some periods
                // since some web servers may block requests (for security
                // reasons) if a path component of the URL contains more
                // than one period.
                //

                writer.WriteString(methodName.Substring(1).Replace('-', '.'));
            }

            writer.WriteMember("params");
            NameValueCollection query = new NameValueCollection(Request.QueryString);

            query.Remove(string.Empty);
            JsonConvert.Export(Request.QueryString, writer);

            writer.WriteEndObject();

            //
            // Delegate rest of the work to JsonRpcDispatcher.
            //

            JsonRpcDispatcher dispatcher = JsonRpcDispatcherFactory.CreateDispatcher(Service);

            using (new JsonRpcDispatchScope(dispatcher, Context))
            {
                dispatcher.RequireIdempotency = true;

                if (padded)
                {
                    //
                    // For JSONP, see details here:
                    // http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/
                    //

                    Response.Write(callback);
                    Response.Write('(');
                }

                dispatcher.Process(new StringReader(sw.ToString()), Response.Output, true);

                if (padded)
                {
                    Response.Write(')');
                }
            }
        }
Exemple #11
0
        /// <summary>
        /// Does some basic authentication checks and then
        /// dispatches to the JayRock RPC system.
        /// </summary>
        /// <param name="message">The JSON-RPC formatted message.</param>
        /// <param name="keePassRPCClient">The client we're communicating with.</param>
        private void DispatchToRPCService(string message, KeePassRPCClientConnection keePassRPCClientConnection)
        {
            if (KeePassRPCPlugin.logger != null)
            {
                KeePassRPCPlugin.logger.WriteLine("Preparing to dispatch: " + message);
            }
            StringBuilder sb = new StringBuilder();
            string        requiredResultRegex    = "";
            long          authorisationAttemptId = -1;

            if (!keePassRPCClientConnection.Authorised && _authorisationRequired)
            {
                Match match = Regex.Match(message,
                                          "^\\{.*?\\\"method\\\"\\:\\\"Idle\\\".*?,.*?\\\"id\\\"\\:(\\d+).*?\\}$");
                if (match.Success)
                {
                    if (KeePassRPCPlugin.logger != null)
                    {
                        KeePassRPCPlugin.logger.WriteLine("Got Idle method- ignoring.");
                    }
                    // Do nothing
                    return;
                }
                else   // Check for alternative Idle message structure
                {
                    match = Regex.Match(message,
                                        "^\\{.*?\\\"id\\\"\\:(\\d+).*?,.*?\\\"method\\\"\\:\\\"Idle\\\".*?\\}$");
                    if (match.Success)
                    {
                        if (KeePassRPCPlugin.logger != null)
                        {
                            KeePassRPCPlugin.logger.WriteLine("Got Idle method- ignoring.");
                        }
                        // Do nothing
                        return;
                    }
                }
            }

            if (!keePassRPCClientConnection.Authorised && _authorisationRequired)
            {
                // We only accept one type of request if the client has not
                // already authenticated. Maybe it's not nice having to do this
                // outside of the main JayRockJsonRpc library but it'll be good enough

                Match match = Regex.Match(message,
                                          "^\\{.*?\\\"method\\\"\\:\\\"Authenticate\\\".*?,.*?\\\"id\\\"\\:(\\d+).*?\\}$");
                if (!match.Success)
                {
                    match = Regex.Match(message,
                                        "^\\{.*?\\\"id\\\"\\:(\\d+).*?,.*?\\\"method\\\"\\:\\\"Authenticate\\\".*?\\}$");
                    if (!match.Success)
                    {
                        throw new AuthorisationException("Authentication required. You must send a properly formed JSON Authenticate request before using this connection.", -1, 1);
                    }
                }

                authorisationAttemptId = int.Parse(match.Groups[1].Value);
                requiredResultRegex    = "^\\{\\\"id\\\"\\:" + authorisationAttemptId + ",\\\"result\\\"\\:\\{\\\"result\\\"\\:0,\\\"name\\\"\\:\\\"(.*)\\\"\\}\\}$";
            }

            //Stream clientStream = keePassRPCClientConnection.ConnectionStream;

            //TODO2: is this Jayrock stuff thread-safe or do I need new instances of the Service each time?
            JsonRpcDispatcher dispatcher = JsonRpcDispatcherFactory.CreateDispatcher(Service);

            dispatcher.Process(new StringReader(message),
                               new StringWriter(sb), keePassRPCClientConnection.Authorised);
            string output = sb.ToString();

            //MessageBox.Show("result: " + output);
            if (_authorisationRequired && !keePassRPCClientConnection.Authorised)
            {
                string authenticatedClientName;

                // Process the output from the JsonRpcDispatcher which
                // should tell us if the authorisation was successful
                Match match = Regex.Match(output, requiredResultRegex);
                if (match.Success)
                {
                    authenticatedClientName = match.Groups[1].Value;
                    keePassRPCClientConnection.Authorised = true;
                    KeePassRPCPlugin.PromoteNullRPCClient(keePassRPCClientConnection, authenticatedClientName);
                }
                else
                {
                    // If the result follows an accepted syntax we will send
                    // it back to the client so they know why it failed but otherwise...
                    if (!Regex.IsMatch(output,
                                       "^\\{\\\"id\\\"\\:(\\d+),\\\"result\\\"\\:\\{\\\"result\\\"\\:(\\d+),\\\"name\\\"\\:\\\".*\\\"\\}\\}$"))
                    {
                        MessageBox.Show("ERROR! Please click on this box, press CTRL-C on your keyboard and paste into a new post on the KeeFox forum (http://keefox.org/help/forum). Doing this will help other people to use KeeFox without any unexpected error messages like this. Please briefly describe what you were doing when the problem occurred, which version of KeeFox, KeePass and Firefox you use and what other security software you run on your machine. Thanks! Technical detail follows: " + output);
                        return; // maybe could return a proper result indicating failure
                        //but user might get annoyed with this popup appearing every 10 seconds!
                    }
                }
            }

            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(output);
            keePassRPCClientConnection.ConnectionStreamWrite(bytes);
        }
        protected override void ProcessRequest()
        {
            string httpMethod = Request.RequestType;

            if (!CaselessString.Equals(httpMethod, "GET") &&
                !CaselessString.Equals(httpMethod, "HEAD"))
            {
                throw new JsonRpcException(string.Format("HTTP {0} is not supported for RPC execution. Use HTTP GET or HEAD only.", httpMethod));
            }

            //
            // Response will be plain text, though it would have been nice to
            // be more specific, like text/json.
            //

            Response.ContentType = "text/plain";

            //
            // Convert the query string into a call object.
            //

            JsonWriter writer = new JsonTextWriter();

            writer.WriteStartObject();

            writer.WriteMember("id");
            writer.WriteNumber(-1);

            writer.WriteMember("method");

            string methodName = Mask.NullString(Request.PathInfo);

            if (methodName.Length == 0)
            {
                writer.WriteNull();
            }
            else
            {
                //
                // If the method name contains periods then we replace it
                // with dashes to mean the one and same thing. This is
                // done to provide dashes as an alternative to some periods
                // since some web servers may block requests (for security
                // reasons) if a path component of the URL contains more
                // than one period.
                //

                writer.WriteString(methodName.Substring(1).Replace('-', '.'));
            }

            writer.WriteMember("params");
            NameValueCollection query = new NameValueCollection(Request.QueryString);
            query.Remove(string.Empty);
            JsonConvert.Export(Request.QueryString, writer);

            writer.WriteEndObject();

            //
            // Delegate rest of the work to JsonRpcDispatcher.
            //

            JsonRpcDispatcher dispatcher = new JsonRpcDispatcher(Service);

            dispatcher.RequireIdempotency = true;

            if (HttpRequestSecurity.IsLocal(Request))
                dispatcher.SetLocalExecution();

            dispatcher.Process(new StringReader(writer.ToString()), Response.Output);
        }
        protected override void ProcessRequest()
        {
            string httpMethod = Request.RequestType;

            if (!CaselessString.Equals(httpMethod, "GET") &&
                !CaselessString.Equals(httpMethod, "HEAD"))
            {
                throw new JsonRpcException(string.Format("HTTP {0} is not supported for RPC execution. Use HTTP GET or HEAD only.", httpMethod));
            }

            //
            // Response will be plain text, though it would have been nice to 
            // be more specific, like text/json.
            //

            Response.ContentType = "text/plain";
            
            //
            // Convert the query string into a call object.
            //

            JsonWriter writer = new JsonTextWriter();
            
            writer.WriteStartObject();
            
            writer.WriteMember("id");
            writer.WriteNumber(0);
            
            writer.WriteMember("method");
            string methodName = Mask.NullString(Request.PathInfo);
            if (methodName.Length == 0)
                writer.WriteNull();
            else
                writer.WriteString(methodName.Substring(1));
            
            writer.WriteMember("params");
            writer.WriteStartObject();

            NameValueCollection query = Request.QueryString;
            
            if (query.HasKeys())
            {
                foreach (string name in query)
                {
                    if (Mask.NullString(name).Length == 0)
                        continue;
                
                    writer.WriteMember(name);

                    string[] values = query.GetValues(name);                    
                    
                    if (values.Length == 0)
                        writer.WriteNull();
                    else if (values.Length == 1)
                        writer.WriteString(values[0]);
                    else 
                        writer.WriteArray(values);
                }
            }
            
            writer.WriteEndObject();
            
            writer.WriteEndObject();
            
            //
            // Delegate rest of the work to JsonRpcDispatcher.
            //

            JsonRpcDispatcher dispatcher = new JsonRpcDispatcher(Service);
            
            if (HttpRequestSecurity.IsLocal(Request))
                dispatcher.SetLocalExecution();
            
            dispatcher.Process(new StringReader(writer.ToString()), Response.Output);
        }
        public void Dispose()
        {
            if (_dispatcher == null)
                return;

            //
            // Clear the import and export contexts so that they may be 
            // reused for another request.
            //

            _dispatcher.ExportContext.Items.Clear();
            _dispatcher.ImportContext.Items.Clear();
            _dispatcher = null;
        }