// === Http =================================================================================================== // ============================================================================================================ public void ReceiveHttp(INetState ns, byte[] buffer, int length) { string request = Encoding.UTF8.GetString(buffer, 0, length); HttpRequest http = new HttpRequest(ns, request); try { byte[] response = HandleHttpRequest(http); ns.Send(response, response.Length); if (Config.DebugShowHttpRequests) { Kernel.WriteLine(TypeName, $"{ns} req({http.RequestHost}{http.RequestPage}) => {response.Length} bytes"); if (Config.DebugShowHttpResponses) { Console.WriteLine(response); } } } catch (Exception e) { Console.WriteLine($"{TypeName}: {ns} failed to receive ({e.Message})"); Console.WriteLine(request); } if (!http.ParamConnectionKeepAlive) { ns.DisposeAfterNextFlush(); } }
private void ReceiveApplicationData(INetState ns, byte[] buffer, int length) { string request = Encoding.UTF8.GetString(buffer, 0, length); HttpRequest http = new HttpRequest(ns, request); try { byte[] response = _OnHttpReceive?.Invoke(http); HttpsSmsgApplicationData packet = new HttpsSmsgApplicationData(ns.Https, response); ns.Send(packet); if (Config.DebugShowHttpRequests) { Kernel.WriteLine(TypeName, $"{ns} req({http.RequestHost}{http.RequestPage}) => {packet.Length} encrypted bytes"); if (Config.DebugShowHttpResponses) { Console.WriteLine(response); } } // string decrypted = packet.DebugDecryptSentPacket(ns, ns.Https.SequenceNumberSent - 1); } catch (Exception e) { Console.WriteLine($"{TypeName}: {ns} failed to receive ({e.Message})"); Console.WriteLine(request); } if (!http.ParamConnectionKeepAlive) { ns.DisposeAfterNextFlush(); } }
internal void Receive(ICertificateProvider certProvider, INetState ns, HttpsReader reader) { RecordHandshake(reader.Buffer, reader.Length, !reader.IsDecrypted); EHandshake handshakeType = (EHandshake)reader.ReadByte(); int handshakeMsgLength = reader.Read24BitInt(); HttpsReader.VerifyLengthRemaining(reader, handshakeMsgLength, "Ssl handshake"); switch (handshakeType) { case EHandshake.ClientHello: ReceiveClientHello(certProvider, ns, reader); break; case EHandshake.ClientKeyExchange: ReceiveClientKeyExchange(certProvider, ns, reader); break; case EHandshake.Finished: ReceiveClientFinished(ns, reader); break; default: ns.Send(new HttpsSmsgAlert(ns.Https, 2, 10)); throw new HttpsException($"sent unknown handshake 0x{handshakeType:X}", reader); } }
public CommandEventArgs(INetState mobile, string command, string argString, string[] arguments) { Mobile = mobile; Command = command; ArgString = argString; Arguments = arguments; }
public static bool Handle(INetState from, string text) { int indexOf = text.IndexOf(' '); string command; string[] args; string argString; if (indexOf >= 0) { argString = text.Substring(indexOf + 1); command = text.Substring(0, indexOf); args = Split(argString); } else { argString = ""; command = text.ToLower(); args = new string[0]; } CommandEntry entry = null; Entries.TryGetValue(command, out entry); if (entry != null) { if (from.Mobile.AccessLevel >= entry.AccessLevel) { if (entry.Handler != null) { CommandEventArgs e = new CommandEventArgs(from, command, argString, args); entry.Handler(e); } } else { if (from.Mobile.AccessLevel <= BadCommandIgnoreLevel) { return(false); } from.SendMessage("You do not have access to that command."); } } else { if (from.Mobile.AccessLevel <= BadCommandIgnoreLevel) { return(false); } from.SendMessage("That is not a valid command."); } return(true); }
// --- Https Handshake --- internal void ReceiveHandshake(ICertificateProvider certProvider, INetState ns, HttpsReader reader) { if (_Handshake == null) { _Handshake = new HttpsHandshakeSession(); } _Handshake.Receive(certProvider, ns, reader); }
private static string NicknameOrIP(INetState user) { if (user.User != null) return user.User.Nickname; if (user is NetState) return ((NetState)user).EndPoint.ToString(); return "Unknown"; }
private static string NicknameOrIP(INetState user) { if (user.User != null) { return(user.User.Nickname); } if (user is NetState) { return(((NetState)user).EndPoint.ToString()); } return("Unknown"); }
// === Https ================================================================================================== // ============================================================================================================ public void ReceiveHttps(INetState ns, byte[] buffer, int length) { if (_Https != null) { _Https.ReceiveHttps(ns, buffer, length); } else { ns.Dispose(); throw new Exception($"{TypeName}: {ns} sent https packet but no https handler exists."); } }
protected override void BeforeCompile(INetState ns) { if (ns?.Https.IsServerEncrypting ?? false) { EncryptAndAddHash(ns); } FixupLength16Bit(3, (int)Length - 5); if (Config.DebugShowHttpsPackets) { Console.WriteLine($"Sent:"); Console.Write(BufferFormat.AsHexString(this.UnderlyingStream.GetBuffer(), (int)Length)); } }
private void SendServerFinished(INetState ns, byte[] allHandshakes) { KeyedHashAlgorithm verify = CipherSuite.GetHMAC(_MasterSecret); verify.Initialize(); verify.TransformBlock(allHandshakes, 0, allHandshakes.Length, allHandshakes, 0); if (ns.Https.Protocol == EProtocol.SSLv30) { verify.TransformFinalBlock(SslBlocks.SenderServer, 0, SslBlocks.SenderServer.Length); Send(ns, new HttpSmsgFinished(ns.Https, verify.Hash)); } else { throw new HttpsException($"Unknown protocol {ns.Https.Protocol}"); } }
// === Https ================================================================================================== // ============================================================================================================ public void ReceiveHttps(INetState ns, byte[] buffer, int length) { if (Config.DebugShowHttpsPackets) { Console.WriteLine($"Received from {ns}:"); Console.Write(BufferFormat.AsHexString(buffer, length)); } try { while (length > 0) { if (ns.Https == null) { ns.Https = new HttpsSession(EProtocol.SSLv30); } if (TryGetReader(ns.Https, ref buffer, ref length, out HttpsReader reader)) { switch (reader.RecordType) { case ERecordType.ChangeCipherSpec: ns.Https.ReceiveChangeCipherSpec(ns, reader); break; case ERecordType.Handshake: ns.Https.ReceiveHandshake(this, ns, reader); break; case ERecordType.ApplicationData: ReceiveApplicationData(ns, reader.Buffer, reader.Length); break; default: throw new HttpsException($"sent unknown TlsRecord type 0x{reader.RecordType:X}", reader); } } else { // save fragment ?? throw new HttpsException($"Did not save fragment!"); } } } catch (Exception e) { Console.WriteLine($"{TypeName}: {ns} {e.Message}"); ns.DisposeAfterNextFlush(); return; } }
// --- Https Change Cipher Spec --- internal void ReceiveChangeCipherSpec(INetState ns, HttpsReader reader) { byte payload = reader.ReadByte(); HttpsReader.VerifyLengthRemaining(reader, 0, "ChangeClientSpec"); if (payload != 0x01) { throw new HttpsException($"sent ChangeCipherSpec with wrong payload.", reader); } SessionIdentifier = _Handshake.SessionIdentifier; SequenceNumberReceived = 0; SequenceNumberSent = 0; CipherSuite = _Handshake.CipherSuite; _KeyBlock = _Handshake.GetKeyBlock(); Decryptor = CipherSuite.GetTransform(_KeyBlock.ClientWriteKey); Encryptor = CipherSuite.GetTransform(_KeyBlock.ServerWriteKey); // DeMAC = CipherSuite.GetMAC(_KeyBlock.ClientWriteMACKey); // EnMAC = CipherSuite.GetMAC(_KeyBlock.ServerWriteMACKey); IsClientEncrypting = true; }
public HttpRequest(INetState ns, string request) { NetState = ns; HttpRequestSplitter lines = new HttpRequestSplitter(request); // read request line: if (!TryReadRequestLine(lines.GetLine())) { throw new Exception($"{TypeName}: {ClientName} sent request with unknown type {request[0]}"); } // read request parameters: Parameters = new Dictionary <string, string>(); while (!lines.IsEOF) { string line = lines.GetLine().Trim(); if (string.IsNullOrEmpty(line)) { break; } if (!TryReadParamLine(line)) { throw new Exception($"{TypeName}: {ClientName} sent request with unknown parameter {line}"); } } // read request body: if (lines.IsEOF) { Body = new NullBody(); } else if (Parameters.TryGetValue("content-type", out string contentType)) { Body = ReadBodyByContentType(contentType, lines.GetRemaining()); } else { Body = new TextBody(lines.GetRemaining()); } }
private void ReceiveClientFinished(INetState ns, HttpsReader reader) { HttpsCmsgFinished packet = new HttpsCmsgFinished(reader); byte[] allHandshakes = _AllHandshakes.ToArray(); KeyedHashAlgorithm verify = CipherSuite.GetHMAC(_MasterSecret); verify.Initialize(); verify.TransformBlock(allHandshakes, 0, allHandshakes.Length - reader.Length, allHandshakes, 0); if (ns.Https.Protocol == EProtocol.SSLv30) { verify.TransformFinalBlock(SslBlocks.SenderClient, 0, SslBlocks.SenderClient.Length); if (!ByteArrayEquality(packet.Verification, 0, verify.Hash, 0, packet.Verification.Length)) { throw new HttpsException("ClientFinished hash did not match computed hash.", reader); } } else { throw new HttpsException($"Unknown protocol {ns.Https.Protocol}", reader); } ns.Https.SendChangeCipherSpec(ns, 0x01); SendServerFinished(ns, allHandshakes); }
// --- Handshake Packets ------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------- private void ReceiveClientHello(ICertificateProvider certProvider, INetState ns, HttpsReader reader) { HttpsCmsgHello packet = new HttpsCmsgHello(reader); if (packet.SessionID != null) { throw new HttpsException($"provided a sessionID (unsupported)", reader); } if (!SupportedCiphers.Select(packet.Ciphers, out CipherSuiteInfo cipherSelected)) { throw new HttpsException("does not support any of our cipher suites", reader); } CipherSuite = cipherSelected; _ClientRandom = packet.ClientRandom; _ServerRandom = new byte[32]; Randoms.NextBytesUnixTimePrefix(_ServerRandom); HttpsWriter serverHello = new HttpsSmsgHello(ns.Https, CipherSuite.CipherSuite, SessionIdentifier, _ServerRandom); HttpsWriter serverCerts = new HttpsSmsgCertificate(ns.Https, certProvider.HttpsGetCerts()); HttpsWriter serverHelloDone = new HttpsSmsgHelloDone(ns.Https); Send(ns, serverHello); Send(ns, serverCerts); Send(ns, serverHelloDone); }
public UserConnected(INetState ns) { Ns = ns; }
protected static void AddClient(INetState client) { _clients.Add(client); }
internal void SendChangeCipherSpec(INetState ns, byte payload) { ns.Send(new HttpsSmsgChangeCipher(ns.Https, payload)); IsServerEncrypting = true; }
protected static void RemoveClient(INetState client) { _clients.Remove(client); }
private void Send(INetState ns, HttpsWriter packet) { ns.Send(packet, RecordHandshake); }
public UserMessageReceived(INetState ns, MessageCreateEventArgs args) { Ns = ns; Args = args; }
public void OnUserDisconnected(INetState user) { telNetState.SendInfoLine(" {0} disconnected.", NicknameOrIP(user)); }
public OnLoginLogoutEventArgs(INetState client) { this.State = client; }
/// <summary> /// Throws an exception with message format ns message<br/>buffer. /// </summary> public NetStateMsgException(INetState ns, string message, byte[] buffer, int length) : base($"{(ns?.ToString() ?? "unknown")} {message}{Environment.NewLine}{BufferFormat.AsString(buffer, length)}") { }
public void OnChat(INetState user, string text) { string line = string.Format(" {0} says: {1}", NicknameOrIP(user), text); telNetState.SendInfoLine(line); }
private void EncryptAndAddHash(INetState ns) { byte[] bufferUnencrypted = UnderlyingStream.ToArray(); // this is where we would add postfix padding if we were using a block cipher if (!Cryptor.CreateMAC(ns.Https.CipherSuite, ns.Https.EnMAC, ns.Https.SequenceNumberSent, RecordType, bufferUnencrypted, 5, out byte[] mac))
/// <summary> /// Gets the entire stream content as a byte array. /// </summary> public byte[] Compile(INetState ns) { BeforeCompile(ns); return(_Stream.ToArray()); }
/// <summary> /// Throws an exception with message format ns message<br/>buffer. /// </summary> public NetStateMsgException(INetState ns, string message, PacketReader reader) : base($"{(ns?.ToString() ?? "unknown")} {message}{Environment.NewLine}{BufferFormat.AsString(reader.Buffer, reader.Length)}") { }
protected virtual void BeforeCompile(INetState ns) { }
private void ReceiveClientKeyExchange(ICertificateProvider certProvider, INetState ns, HttpsReader reader) { HttpsCmsgKeyExchange packet = new HttpsCmsgKeyExchange(reader); _PreMasterSecret = certProvider.HttpsCertDecrypt(packet.EncryptedPreMasterSecret); }