private void ProcessClient(TcpClient client) { // A client has connected. Create the // SslStream using the client's network stream. SslStream sslStream = new SslStream(client.GetStream(), false); // Authenticate the server but don't require the client to authenticate. sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls, true); try { // Set timeouts for the read and write to 5 seconds. sslStream.ReadTimeout = 5000; sslStream.WriteTimeout = 5000; // Read a message from the client. Console.WriteLine("Waiting for client message..."); CollectionAgentMessage caMsg = ReadMessage(sslStream); if (null != caMsg) { Console.WriteLine("Received: {0}", caMsg.ToJSON()); // We have a valid query, process it CollectionAgentMessage caResp = processClientQuery(caMsg); Console.WriteLine("Sending response message."); sslStream.Write(Encoding.UTF8.GetBytes(caResp.ToJSON())); } else { // Write a response message to the client. CollectionAgentErrorMessage caResp = new CollectionAgentErrorMessage(caMsg.requestID, "ERROR parsing JSON request."); Console.WriteLine("Sending ERROR response message."); sslStream.Write(Encoding.UTF8.GetBytes(caResp.ToJSON())); } } catch (AuthenticationException e) { Console.WriteLine("Exception: {0}", e.Message); if (e.InnerException != null) { Console.WriteLine("Inner exception: {0}", e.InnerException.Message); } Console.WriteLine("Authentication failed - closing the connection."); sslStream.Close(); client.Close(); return; } finally { // The client stream will be closed with the sslStream // because we specified this behavior when creating // the sslStream. sslStream.Close(); client.Close(); } }
private static void SendMessage(SslStream sslStream, CollectionAgentMessage message) { Console.WriteLine(message.ToJSON()); // Send hello message to the server. sslStream.Write(Encoding.UTF8.GetBytes(message.ToJSON())); sslStream.Flush(); }
public static void RunClient(string machineName, string serverName) { // Create a TCP/IP client socket. // machineName is the host running the server application. TcpClient client = new TcpClient(machineName, 12345); Console.WriteLine("Client connected."); // Create an SSL stream that will close the client's stream. SslStream sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null ); // The server name must match the name on the server certificate. try { sslStream.AuthenticateAsClient(serverName); } catch (AuthenticationException e) { Console.WriteLine("Exception: {0}", e.Message); if (e.InnerException != null) { Console.WriteLine("Inner exception: {0}", e.InnerException.Message); } Console.WriteLine("Authentication failed - closing the connection."); client.Close(); return; } GetRegistryKeyRequestMessage msg = new GetRegistryKeyRequestMessage(1, RootKey.HKEY_CURRENT_USER, "Software\\CollectionAgentTest"); //CollectionAgentMessage msg = new CollectionAgentMessage(1); // Send the message to the CollectionAgent SendMessage(sslStream, msg); // Read message from the server. CollectionAgentMessage caMsg = ReadMessage(sslStream); Console.WriteLine("Server says: {0}", caMsg.ToJSON()); // Close the client connection. client.Close(); Console.WriteLine("Client closed."); }
// This method is responsible for processing a query based on a message passed // by a client. // For now, this is a skeleton function only. As reall queries are created, this function // will be populated with calls to code that will actually process and respond to the // queries. private CollectionAgentMessage processClientQuery(CollectionAgentMessage caMsg) { // Write a response message to the client. CollectionAgentMessage caResp = null; // Get the appropriate ICommandProcessor object based on the request type. ICommandProcessor processor = processorMap[caMsg.requestType]; // If the object is not null, then call processCommand() if (null != processor) { caResp = processor.processCommand(caMsg); } else { caResp = new CollectionAgentErrorMessage(caMsg.requestID, "ERROR: Invalid request type."); } return(caResp.isValid() ? caResp : null); }
public CollectionAgentMessage processCommand(CollectionAgentMessage msg) { CollectionAgentMessage responseMsg = null; GetRegistryKeyRequestMessage requestMessage = null; if (typeof(GetRegistryKeyRequestMessage) != msg.GetType()) { responseMsg = new CollectionAgentErrorMessage(msg.requestID, "Invalid request type."); } else { RegistryKey regKey = null; requestMessage = (GetRegistryKeyRequestMessage)msg; // Open the key from the appropriate root key switch (requestMessage.root) { case RootKey.HKEY_CLASSES_ROOT: regKey = Registry.ClassesRoot.OpenSubKey(requestMessage.keyPath, false); break; case RootKey.HKEY_CURRENT_CONFIG: regKey = Registry.CurrentConfig.OpenSubKey(requestMessage.keyPath, false); break; case RootKey.HKEY_CURRENT_USER: regKey = Registry.CurrentUser.OpenSubKey(requestMessage.keyPath, false); break; case RootKey.HKEY_LOCAL_MACHINE: regKey = Registry.LocalMachine.OpenSubKey(requestMessage.keyPath, false); break; case RootKey.HKEY_USERS: regKey = Registry.Users.OpenSubKey(requestMessage.keyPath, false); break; } // If we found the key, then read the values and if (null != regKey) { GetRegistryKeyResponseMessage regResponse = new GetRegistryKeyResponseMessage(requestMessage.requestID); // Set the path on the Registry key regResponse.regKey.path = requestMessage.keyPath; // Populate the Registry key with values and subkeys populateRegistrykey(regResponse.regKey, regKey); // Set the return value responseMsg = regResponse; } else // send an error message instead { responseMsg = new CollectionAgentErrorMessage(requestMessage.requestID, "Registry key not found"); } } return(responseMsg); }
private CollectionAgentMessage ReadMessage(SslStream sslStream) { CollectionAgentMessage deserializedMsg = null; // Read the message sent by the client. // The client signals the end of the message using the // "<EOF>" marker. byte[] buffer = new byte[2048]; StringBuilder messageData = new StringBuilder(); int bytes = -1; do { // Read the client's test message. bytes = sslStream.Read(buffer, 0, buffer.Length); // Use Decoder class to convert from bytes to UTF8 // in case a character spans two buffers. Decoder decoder = Encoding.UTF8.GetDecoder(); char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)]; decoder.GetChars(buffer, 0, bytes, chars, 0); messageData.Append(chars); if (messageData.ToString().IndexOf("<EOF>") != -1) { break; } } while (bytes != 0); String strJSON = messageData.ToString(); // If there is a trailing <EOF> character, strip it so that JSON // deserialization will work correctly int index = (strJSON.IndexOf("<EOF>")); if (index != -1) { strJSON = strJSON.Substring(0, index); } // Read String data into a MemoryStream so it can be deserialized MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(strJSON)); // Deserialize the stream into an object DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(CollectionAgentMessage)); CollectionAgentMessage baseMsg = ser.ReadObject(ms) as CollectionAgentMessage; ms.Close(); if (null != baseMsg) { ICommandMessageFactory factory = msgFactoryMap[baseMsg.requestType]; if (null != factory) { deserializedMsg = factory.constructMessageFromJSON(baseMsg.requestType, strJSON); } } // Return the new object return(deserializedMsg); }