/// <summary> /// Performs a series of check to ensure the call is legal, and return a Command object /// </summary> /// <param name="httpRequest"></param> /// <returns></returns> private Tuple <Command, HttpStatusCode> GetCommandFromRequest(HttpRequest httpRequest) { //Check the authentication if (!httpRequest.Headers.ContainsKey("authorization") || httpRequest.Headers["authorization"] != SecretManager.PortalPasswordBase64) { return(new Tuple <Command, HttpStatusCode>(Command.CreateErrorCommand("Unauthorized."), HttpStatusCode.Unauthorized)); } //if Encryption is enabled, the device will expect a request with encrypted header if (SecretManager.IsEncryptionEnabled && !httpRequest.Headers.ContainsKey(EdisonEncryptHeader)) { return(new Tuple <Command, HttpStatusCode>(Command.CreateErrorCommand("Encryption is enabled on the device."), HttpStatusCode.Unauthorized)); } //Listen to /edison/ endpoints only if (!httpRequest.Query.ToLower().StartsWith("/edison/")) { return(new Tuple <Command, HttpStatusCode>(Command.CreateErrorCommand("Not found."), HttpStatusCode.NotFound)); } //Retrieve the command from the endpoint string commandString = httpRequest.Query.Replace("/edison/", ""); if (!Enum.TryParse(typeof(CommandsEnum), commandString, true, out object commandResult)) { return(new Tuple <Command, HttpStatusCode>(Command.CreateErrorCommand($"The command '{commandString}' was not found."), HttpStatusCode.NotFound)); } //Decrypt the message if (httpRequest.Headers.ContainsKey(EdisonEncryptHeader)) { httpRequest.Body = CommandParserHelper.DecryptMessage(httpRequest.Body, SecretManager.EncryptionKey); } //Generate the command object CommandsEnum command = (CommandsEnum)commandResult; if (httpRequest.Method == "GET" && commandString.StartsWith("get")) { return(new Tuple <Command, HttpStatusCode>(new Command() { BaseCommand = command }, HttpStatusCode.OK)); } else if (httpRequest.Method == "POST" && !commandString.StartsWith("get")) { //If the request is POST, ensure that the content-type header is application/json if (httpRequest.Headers.ContainsKey("content-type") && httpRequest.Headers["content-type"] == "application/json") { return(new Tuple <Command, HttpStatusCode>(new Command() { BaseCommand = command, Data = httpRequest.Body }, HttpStatusCode.OK)); } return(new Tuple <Command, HttpStatusCode>(Command.CreateErrorCommand($"The body content must be a json string."), HttpStatusCode.BadRequest)); } //Method is not GET or POST, return unsupported error return(new Tuple <Command, HttpStatusCode>(Command.CreateErrorCommand($"Method {httpRequest.Method} {command} not supported."), HttpStatusCode.BadRequest)); }
private async Task <Command> ReceiveCommand(DataReader reader, string passkey) { //Get message size length uint uintSizeLoad = await reader.LoadAsync(sizeof(uint)); if (uintSizeLoad != sizeof(uint)) { return(null); } uint responseSize = reader.ReadUInt32(); //Load message uint responseSizeLoad = await reader.LoadAsync(responseSize); if (responseSize != responseSizeLoad) { return(null); } //Read message string responseString = reader.ReadString(responseSizeLoad); if (responseString.Length != 0) { Command msg = CommandParserHelper.DeserializeAndDecryptCommand(responseString, passkey); DebugHelper.LogInformation($"Incoming: {msg.BaseCommand}, {msg.Data}"); return(msg); } return(null); }
private async Task <bool> SendRequest(Command command, string passkey) { string requestData = CommandParserHelper.SerializeAndEncryptCommand(command, passkey); try { //First byte is the size of the message _writer.WriteUInt32(_writer.MeasureString(requestData)); //Next is the actual message _writer.WriteString(requestData); //Send the message await _writer.StoreAsync(); await _writer.FlushAsync(); //Log Debug.WriteLine($"Sent: {command.BaseCommand}, {command.Data}"); return(true); } catch (Exception e) { Debug.WriteLine($"SendRequest: {e.Message}"); return(false); } }
private async Task SendResponse(Command response, DataWriter writer, string passkey) { using (var stream = new MemoryStream()) { // Send request string requestData = CommandParserHelper.SerializeAndEncryptCommand(response, passkey); writer.WriteUInt32(writer.MeasureString(requestData)); writer.WriteString(requestData); await writer.StoreAsync(); DebugHelper.LogInformation($"Sent: {response.BaseCommand}, {response.Data}"); } }
/// <summary> /// Send Response /// </summary> /// <param name="command"></param> /// <param name="writer"></param> /// <param name="encrypt"></param> /// <param name="statusCode"></param> /// <returns></returns> private async Task SendResponse(Command command, DataWriter writer, bool encrypt, HttpStatusCode statusCode = HttpStatusCode.OK) { var json = CommandParserHelper.SerializeCommand(command); string encryptHeader = string.Empty; if (encrypt) { json = CommandParserHelper.EncryptMessage(json, SecretManager.EncryptionKey); encryptHeader = $"{EdisonEncryptHeader}: true\r\n"; } var message = $"HTTP/1.1 {(int)statusCode} {statusCode}\r\nContent-Length: {json.Length}\r\ncontent-type: application/json\r\n{encryptHeader}Connection: close\r\n\r\n" + json; writer.WriteString(message); await writer.StoreAsync(); DebugHelper.LogInformation($"Sent: {command.BaseCommand}, {command.Data}"); }
/// <summary> /// Send Response /// </summary> /// <param name="command"></param> /// <param name="writer"></param> /// <param name="encrypt"></param> /// <param name="statusCode"></param> /// <returns></returns> private void SendResponse(Command command, HttpListenerResponse response, bool encrypt, HttpStatusCode statusCode = HttpStatusCode.OK) { var json = CommandParserHelper.SerializeCommand(command); //Headers response.StatusCode = (int)statusCode; response.ContentType = "application/json"; response.ContentLength64 = json.Length; //Encrypt if (encrypt) { json = CommandParserHelper.EncryptMessage(json, SecretManager.EncryptionKey); response.AddHeader(EdisonEncryptHeader, "true"); } response.AddHeader("Connection", "close"); response.OutputStream.Write(Encoding.UTF8.GetBytes(json)); DebugHelper.LogInformation($"Sent: {command.BaseCommand}, {command.Data}"); }
private async Task <Command> ReadResponse(string passkey) { try { while (true) { //Get message size length uint uintSizeLoad = await _reader.LoadAsync(sizeof(uint)); if (uintSizeLoad != sizeof(uint)) { return(null); } uint responseSize = _reader.ReadUInt32(); //Load message uint responseSizeLoad = await _reader.LoadAsync(responseSize); if (responseSize != responseSizeLoad) { return(null); } //Read message string responseString = _reader.ReadString(responseSizeLoad); Command response = CommandParserHelper.DeserializeAndDecryptCommand(responseString, passkey); Debug.WriteLine($"Incoming: {response.BaseCommand}, {response.Data}"); return(response); } } catch (Exception e) { Debug.WriteLine($"ReadResponse: {e.Message}"); return(null); } }
public static void Main(string[] args) { if (args.Count() != 2) { LogError(@"Error: command line arguments incorrect. Format: Frank.ConsoleDrawingTool c:\path\to\input.txt c:\path\to\output.txt"); } string fileInputPath = args[0]; string fileOutputPath = args[1]; //check if file input exists if (System.IO.File.Exists(fileInputPath) == false) { LogError(string.Format(@"Error: '{0}' could not be found", fileInputPath)); } try { //process input var commandTextLines = System.IO.File.ReadAllLines(fileInputPath); // cleanup input var sanitizedCommandLines = CommandParserHelper.SanitizeInput(commandTextLines).ToList(); var ctx = new ExecutionContext(); var commands = sanitizedCommandLines.Select(s => CommandParserHelper.GetCommandFromCommandLine(ctx, s)).ToList(); if (commands.Any() == false) { LogError(string.Format("Error: no commands to execute in file '{0}'", fileInputPath)); } // extract commands from input //make sure first command is creating Canvas IList <string> outputScreens = new List <string>(); var firstCmd = commands.FirstOrDefault(); if ((firstCmd is CreateCanvasCommand) == false) { LogError("Error: first command must be to create canvas"); Console.ReadLine(); } //Write to file string gfxBufferStr = null; foreach (var command in commands) { command.Execute(); gfxBufferStr = ctx.Canvas.DumpBufferToString(); outputScreens.Add(gfxBufferStr); Console.WriteLine(gfxBufferStr); } System.IO.File.WriteAllText(fileOutputPath, string.Join(Environment.NewLine, outputScreens)); } catch (Exception e) { LogError(e.Message); } }