/// <summary> /// コピーコンストラクタ /// </summary> /// <param name="info"></param> public NegotiationInfomation(NegotiationInfomation info) { this.IAC = info.IAC; this.Command = info.Command; this.Option = info.Option; this.Stream = info.Stream; }
void EndSequence(TelnetOption option) { try { if (option == TelnetOption.TerminalType) { if (!Properties.ContainsKey("TerminalType")) Properties["TerminalType"] = string.Empty; var name = Properties["TerminalType"] as string ?? string.Empty; if (name.Length > 0) name += " "; name += Encoding.ASCII.GetString(_sequence.ToArray()); Properties["TerminalType"] = name; } if (option == TelnetOption.WindowSize) { Properties["Width"] = (short)_sequence[0]; Properties["Height"] = (short)_sequence[1]; } } catch (Exception ex) { _logger.LogError(ex.ToString()); } _sequence.Clear(); _telnetCommand = null; }
public static Tuple <int, byte[], TelnetLogList> ProcessTelnetCommand( TelnetCommand TelnetCmd, NegotiateSettings NegotiateSettings, bool doLog = false) { TelnetLogList logList = null; if (doLog == true) { logList = new TelnetLogList(); } int cx = 0; var writeStream = new ByteArrayBuilder(); // write to the run log. if (logList != null) { logList.AddItem(Direction.Read, TelnetCmd.ToString()); } if (TelnetCmd.CmdCode == Enums.CommandCode.DO) { var replyStmt = TelnetCmd.BuildReply(NegotiateSettings); writeStream.Append(replyStmt.ToBytes()); } else if (TelnetCmd is NewEnvironCommand) { var envStmt = TelnetCmd as NewEnvironCommand; cx = ProcessNewEnvironStatement(envStmt, writeStream, NegotiateSettings); } else if (TelnetCmd is TerminalTypeCommand) { var ttStmt = TelnetCmd as TerminalTypeCommand; cx = ProcessTerminalTypeStatement(ttStmt, writeStream, NegotiateSettings); } else if ((TelnetCmd is EndOfRecordStatement) || (TelnetCmd is TransmitBinaryCommand)) { if (TelnetCmd.CmdCode == Enums.CommandCode.DO) { var replyStmt = TelnetCmd.BuildReply(NegotiateSettings); writeStream.Append(replyStmt.ToBytes()); if ((replyStmt.CmdCode == Enums.CommandCode.DO) && (replyStmt.Subject.IsEqual(TelnetSubject.TRANSMIT_BINARY))) { } } else if (TelnetCmd.CmdCode == Enums.CommandCode.WILL) { var replyStmt = TelnetCmd.BuildDoReply(); writeStream.Append(replyStmt.ToBytes()); } } return(new Tuple <int, byte[], TelnetLogList>(cx, writeStream.ToByteArray(), logList)); }
/// <summary> /// 応答送信 /// </summary> /// <param name="command"></param> /// <param name="option"></param> private MemoryStream SendBack(TelnetCommand command, TelnetOption option) { // 送信メモリオブジェクト生成 MemoryStream sendStream = new MemoryStream(); sendStream.WriteByte((byte)TelnetCommand.IAC); sendStream.WriteByte((byte)command); sendStream.WriteByte((byte)option); return(sendStream); }
public byte Receive() { byte In = ReceiveRaw(); if (IsCtrlChar(In) && In == 255) { TelnetCommand Cmd = (TelnetCommand)ReceiveRaw(); TelnetCommand Option = (TelnetCommand)ReceiveRaw(); bool Unimplemented = false; if (Cmd == TelnetCommand.IAC && Option == TelnetCommand.IAC) { throw new Exception("Invalid control code"); } if (Option == TelnetCommand.SuppressGoAhead) { Send(TelnetCommand.IAC, TelnetCommand.WILL, TelnetCommand.SuppressGoAhead); } else if (Option == TelnetCommand.Echo) { if (Cmd == TelnetCommand.DO) { Echo = true; } else if (Cmd == TelnetCommand.DONT) { Echo = false; } else { Unimplemented = true; } Send(TelnetCommand.IAC, Echo ? TelnetCommand.WILL : TelnetCommand.WONT, TelnetCommand.Echo); } else { Unimplemented = true; } if (Unimplemented) { Console.WriteLine("Unsupported: IAC {0} {1}", Cmd, Option); } return(Receive()); } if (In == 127) { In = (byte)'\b'; } return(In); }
private void SendIAC(TelnetCommand command, byte option) { if (Connected) { if (!_TelnetOptions[option]) { _TelnetOptions[option] = true; base.WriteRaw(new byte[] { (byte)TelnetCommand.IAC, (byte)command, option }); } } }
public static TelnetCommand AsNegative(this TelnetCommand command) { if (!command.IsPositive()) { return(command); } else { return(command.Negate()); } }
public async Task Handle(TelnetCommand command, TelnetOption option, ITelnetChannel channel) { TelnetCommand response = command.Reciprocal().AsNegative(); //if (option == TelnetOption.SuppressGoAhead && command.IsPositive()) //{ // response = response.AsPositive(); //} await channel.SendCommandAsync(response, option); }
public static bool IsImperative(this TelnetCommand command) { switch (command) { case TelnetCommand.DO: case TelnetCommand.DONT: return(true); default: return(false); } }
public static bool IsPositive(this TelnetCommand command) { switch (command) { case TelnetCommand.WILL: case TelnetCommand.DO: return(true); default: return(false); } }
/// <summary> /// 応答送信 /// </summary> /// <param name="command"></param> /// <param name="option"></param> private void SendBack(TelnetCommand command, TelnetOption option) { // 送信メモリオブジェクト生成 MemoryStream sendStream = new MemoryStream(); sendStream.WriteByte((byte)TelnetCommand.IAC); sendStream.WriteByte((byte)command); sendStream.WriteByte((byte)option); // 送信 this.Parse(sendStream.ToArray()); this.Send(sendStream); }
private static int ProcessNewEnvironStatement( NewEnvironCommand Stmt, ByteArrayBuilder WriteStream, NegotiateSettings NegotiateSettings) { int sendStmtCx = 0; // got the stmt with the SEND parm. Send back the NEW_ENVIRON stmt with the IS parm. if ((Stmt.SubOption != null) && (Stmt.SubOption.Value == TelnetOptionParm.SEND)) { var neSend = new NewEnvironCommand(Enums.CommandCode.SB, TelnetOptionParm.IS); foreach (var newEnv in NegotiateSettings.SendNewEnvironList) { var optnVar = newEnv.ToOptionVariable(NegotiateSettings.SbsValuesDict); neSend.AddOptionVar(optnVar); } int xx = 25; if (xx == 26) { neSend.AddOptionVar(EnvironVarCode.VAR, "USER", "SRICHTER"); neSend.AddOptionVar(EnvironVarCode.VAR, "DEVNAME", "STEVE25"); // reply to newEnviron IBMRSEED stmt SEND statement. if (Stmt.ContainsUserVar_IBMRSEED() == true) { byte[] clientSeed = new byte[8] { 0x55, 0x56, 0x59, 0x5a, 0x5b, 0x5c, 0x4c, 0x48 }; string passWord = "******"; string userName = "******"; var serverSeed = Stmt.IBMRSEED_SeedValue(); var substitutionPassword = CipherCommon.EncryptPassword(passWord, userName, serverSeed, clientSeed); neSend.AddOptionVar(EnvironVarCode.USERVAR, "IBMRSEED", clientSeed); neSend.AddOptionVar(EnvironVarCode.USERVAR, "IBMSUBSPW", substitutionPassword); } } WriteStream.Append(neSend.ToBytes()); // send the SE command immed after NEW-ENVIRON { var ts = new TelnetCommand(Enums.CommandCode.SE); WriteStream.Append(ts.ToBytes()); } } return(sendStmtCx); }
public static bool IsNegotiation(this TelnetCommand command) { switch (command) { case TelnetCommand.WILL: case TelnetCommand.WONT: case TelnetCommand.DO: case TelnetCommand.DONT: return(true); default: return(false); } }
public static TelnetCommand Negate(this TelnetCommand command) { switch (command) { case TelnetCommand.WILL: return(TelnetCommand.WONT); case TelnetCommand.WONT: return(TelnetCommand.WILL); case TelnetCommand.DO: return(TelnetCommand.DONT); case TelnetCommand.DONT: return(TelnetCommand.DO); default: return(command); } }
/// <summary> /// Handles a Telnet command. /// </summary> /// <param name="e">Information about the data received.</param> private void HandleCommand(SocketAsyncEventArgs e) { Connection c = e.UserToken as Connection; if (c == null || e.BytesTransferred < 3) { return; } for (int i = 0; i < e.BytesTransferred; i += 3) { if (e.BytesTransferred - i < 3) { break; } if (e.Buffer[i] == (int)TelnetCommand.IAC) { TelnetCommand command = (TelnetCommand)e.Buffer[i + 1]; TelnetOption option = (TelnetOption)e.Buffer[i + 2]; switch (command) { case TelnetCommand.DO: if (option == TelnetOption.Echo) { // ECHO } break; case TelnetCommand.WILL: if (option == TelnetOption.Echo) { // ECHO } break; } c.ReceiveBuffer.Remove(i, 3); } } }
async Task ParseBytes(byte[] data) { using (var ms = new MemoryStream(data)) { using (var reader = new BinaryReader(ms)) { while (reader.BaseStream.Position < reader.BaseStream.Length) { var input = reader.ReadByte(); if (_telnetCommand != null) { if (_telnetCommand.Verb == null) { _telnetCommand.Verb = (TelnetVerb)input; continue; } if (_telnetCommand.Option == null) { _telnetCommand.Option = (TelnetOption)input; } var verb = _telnetCommand.Verb.Value; var option = _telnetCommand.Option.Value; switch (verb) { case TelnetVerb.SB: // Sub-negotiation // Grab bytes until IAC|SE is reached. if (input == (byte)option) continue; if (input == 0x0) continue; if (input == (byte)TelnetVerb.IAC) continue; if (input == (byte)TelnetVerb.SE) { EndSequence(option); continue; } _sequence.Add(input); break; case TelnetVerb.SE: // End of a sequence EndSequence(option); break; case TelnetVerb.WILL: switch (option) { case TelnetOption.TerminalType: await SendRaw(new TelnetCommandBuilder() .Add(TelnetVerb.DO, TelnetOption.TerminalType) .AddSequence(TelnetOption.TerminalType, 1) .Build()); break; case TelnetOption.WindowSize: await SendRaw(new TelnetCommandBuilder() .Add(TelnetVerb.DO, TelnetOption.WindowSize) .Build()); break; default: await SendRaw(new TelnetCommandBuilder() .Add(TelnetVerb.DONT, option) .Build()); break; } _telnetCommand = null; break; case TelnetVerb.WONT: _telnetCommand = null; break; case TelnetVerb.DO: switch (option) { case TelnetOption.SupressGoAhead: await SendRaw(new TelnetCommandBuilder() .Add(TelnetVerb.WILL, TelnetOption.SupressGoAhead) .Build()); break; default: await SendRaw(new TelnetCommandBuilder() .Add(TelnetVerb.WONT, option) .Build()); break; } _telnetCommand = null; break; case TelnetVerb.DONT: _telnetCommand = null; break; case TelnetVerb.IAC: // Probably not a telnet command... _buffer.Add(input); _telnetCommand = null; break; default: _telnetCommand = null; break; } continue; } switch (input) { case (byte)TelnetVerb.IAC: _telnetCommand = new TelnetCommand(); break; case 0x7f: // Backspace // Remove the last character entered. _buffer.RemoveAt(_buffer.Count - 1); break; case 0x0A: // New Line \n case 0x0D: // Carriage Return \r await Context?.ProcessInput(Encoding.ASCII.GetString(_buffer.ToArray())); _buffer.Clear(); return; default: _buffer.Add(input); break; } } } } }
/// <summary> /// parse the 5250 data stream that is sent from the client to the server. /// </summary> /// <param name="LogFile"></param> /// <param name="ToServerStream"></param> /// <returns></returns> public static Tuple <ResponseItemList, string> ParseResponseStream( InputByteArray InputArray, ResponseHeader ResponseHeader = null) { var responseItemList = new ResponseItemList(); string errmsg = null; var writeStream = new ByteArrayBuilder(); DataStreamHeader dsHeader = null; ResponseHeader responseHeader = ResponseHeader; // stream starts with data stream header. if (responseHeader == null) { var rv = DataStreamHeader.Factory(InputArray); dsHeader = rv.Item1; responseItemList.Add(dsHeader); errmsg = dsHeader.Errmsg; // next is the response header. if (errmsg == null) { responseHeader = new ResponseHeader(InputArray); responseItemList.Add(responseHeader); errmsg = responseHeader.Errmsg; } } // look for 5250 query reply. if ((errmsg == null) && (responseHeader.AidKey != null) && (responseHeader.AidKey.Value == AidKey.Query5250Reply)) { var queryResp = new Query5250Response(InputArray); if (queryResp.Errmsg == null) { responseItemList.Add(queryResp); } } // repeating instances of sbaOrder, textDataOrder pairs. while (true) { var telCmd = TelnetCommand.Factory(InputArray); if (telCmd != null) { continue; } // check that an SBA order is starting. Leave loop when it is not. if (SetBufferAddressOrder.CheckOrder(InputArray) != null) { break; } var orderPair = new LocatedTextDataOrderPair(InputArray); if (orderPair.Errmsg != null) { break; } responseItemList.Add(orderPair); } return(new Tuple <ResponseItemList, string>(responseItemList, errmsg)); }
private static void WriteToHost( TelnetLogList LogList, TelnetCommand Stmt, NetworkStream NetStream) { WriteToHost(LogList, Stmt.ToBytes(), NetStream); }
private void SendIAC(TelnetCommand command, TelnetOption option) { SendIAC(command, (byte)option); }
/// <summary> /// write buffer contents to log file. /// </summary> /// <param name="Direction"></param> /// <param name="Buffer"></param> /// <param name="Length"></param> public void Write(string Direction, byte[] Buffer, int Length) { var lines = new List <string>(); this.Counter += 1; var inputArray = new InputByteArray(Buffer, Length); while (inputArray.IsEof() == false) { // peek to see if the current byte is a telnet command. var escapeCmd = inputArray.PeekNextByte().ToTelnetCommandCode(); // peek to see if the current bytes are an IBM5250 datastream header. DataStreamHeader dsh = null; string errmsg = null; { var rv = DataStreamHeader.Factory(inputArray); dsh = rv.Item1; errmsg = rv.Item2; } // current bytes are an ibm5250 datastream header. ( page 2-4 of rfc 1205 ) // store this header as the "current datastream header". When there is a // current data stream header the code will match the current bytes against // ibm5250 data stream commands. if (errmsg == null) { lines.Add( Direction + " " + this.Counter.ToString() + " " + dsh.ToString()); this.CurrentDataStreamHeader = dsh; continue; } // currently in a 5250 data stream header. if (this.CurrentDataStreamHeader != null) { var dataStreamCommand = WorkstationCommandBase.ParseFactory(inputArray); if (dataStreamCommand != null) { lines.Add( Direction + " " + this.Counter.ToString() + " " + dataStreamCommand.ToString()); // all the data stream command ToString methods provide enough info. // But for the WriteToDisplayCommand, list out the ToString contents of // the WtdOrders of that command. if (dataStreamCommand is WriteToDisplayCommand) { var wtdCommand = dataStreamCommand as WriteToDisplayCommand; foreach (var order in wtdCommand.OrderList) { lines.Add(order.ToString()); } } continue; } } { var stmt = TelnetCommand.Factory(inputArray); if (stmt != null) { lines.Add( Direction + " " + this.Counter.ToString() + " " + stmt.ToString()); continue; } } if ((escapeCmd != null) && (escapeCmd.Value == CommandCode.ESCAPE)) { var rv = TerminalVt100Statement.Factory(inputArray); var vtStmt = rv.Item1; var otStmt = rv.Item2; lines.Add( Direction + " " + this.Counter.ToString() + " " + vtStmt.ToString()); if (otStmt != null) { lines.Add( Direction + " " + this.Counter.ToString() + " " + otStmt.ToString()); } continue; } { var remBytes = inputArray.GetBytesToEnd(); lines.Add(Direction + " " + this.Counter.ToString() + " Raw bytes follow:"); LogFile_WriteRawBytes(remBytes, lines); } } WriteTextLines(lines); }
private void ParseTelnetNegData() { byte[] negBuffer = tnNegCommands.ToArray(); tnNegCommands.Clear(); for (int i = 0; i < negBuffer.Length; i += 3) { if (negBuffer.Length - i < 3) { break; } if (negBuffer[i] == (int)TelnetCommand.IAC) { TelnetCommand command = (TelnetCommand)negBuffer[i + 1]; TelnetOption option = (TelnetOption)negBuffer[i + 2]; Console.WriteLine("CLIENT {0} {1}", command, option); switch (command) { case TelnetCommand.WONT: if (!ClientOptionNegociated((byte)option) || GetClientOption((byte)option)) { server.Send(new byte[] { 255, (byte)TelnetCommand.DONT, (byte)option }, this); } Console.WriteLine("SERVER {0} {1}", TelnetCommand.DONT, option); AddClientOption((byte)option, false); this.sender.SendFailMessage(string.Format("Negotiating Client Option '{0}'", option), "OFF"); break; case TelnetCommand.DONT: if (!ServerOptionNegociated((byte)option) || GetServerOption((byte)option)) { server.Send(new byte[] { 255, (byte)TelnetCommand.WONT, (byte)option }, this); } Console.WriteLine("SERVER {0} {1}", TelnetCommand.WONT, option); AddServerOption((byte)option, false); this.sender.SendFailMessage(string.Format("Negotiating Server Option '{0}'", option), "OFF"); if (option == TelnetOption.SuppressGoAhead) { //I WILL DISCONNECT ECHO ALSO!!! server.Send(new byte[] { (byte)TelnetCommand.IAC, (byte)TelnetCommand.WONT, (byte)TelnetOption.Echo }, this); AddServerOption((byte)TelnetOption.Echo, false); this.sender.SendFailMessage(string.Format("Negotiating Server Option '{0}'", option), "OFF"); Console.WriteLine("SERVER {0} {1}", TelnetCommand.WONT, TelnetOption.Echo); } break; case TelnetCommand.DO: switch (option) { case TelnetOption.Echo: if (!ServerOptionNegociated((byte)option) || !GetServerOption((byte)option)) { server.Send(new byte[] { (byte)TelnetCommand.IAC, (byte)TelnetCommand.WILL, (byte)TelnetOption.Echo }, this); } Console.WriteLine("SERVER {0} {1}", TelnetCommand.WILL, TelnetOption.Echo); AddServerOption((byte)option, true); this.sender.SendSucessMessage(string.Format("Negotiating Server Option '{0}'", option), "ON"); break; case TelnetOption.SuppressGoAhead: if (!ServerOptionNegociated((byte)option) || !GetServerOption((byte)option)) { server.Send(new byte[] { (byte)TelnetCommand.IAC, (byte)TelnetCommand.WILL, (byte)TelnetOption.SuppressGoAhead }, this); } Console.WriteLine("SERVER {0} {1}", TelnetCommand.WILL, TelnetOption.SuppressGoAhead); AddServerOption((byte)option, true); this.sender.SendSucessMessage(string.Format("Negotiating Server Option '{0}'", option), "ON"); break; } break; case TelnetCommand.WILL: switch (option) { case TelnetOption.SuppressGoAhead: server.Send(new byte[] { (byte)TelnetCommand.IAC, (byte)TelnetCommand.DO, (byte)TelnetOption.SuppressGoAhead }, this); Console.WriteLine("SERVER {0} {1}", TelnetCommand.DO, TelnetOption.SuppressGoAhead); AddClientOption((byte)option, true); this.sender.SendSucessMessage(string.Format("Negotiating Client Option '{0}'", option), "ON"); break; case TelnetOption.Echo: server.Send(new byte[] { (byte)TelnetCommand.IAC, (byte)TelnetCommand.DO, (byte)TelnetOption.Echo }, this); Console.WriteLine("SERVER {0} {1}", TelnetCommand.DO, TelnetOption.Echo); AddClientOption((byte)option, true); this.sender.SendSucessMessage(string.Format("Negotiating Client Option '{0}'", option), "ON"); break; case TelnetOption.WindowSize: server.Send(new byte[] { (byte)TelnetCommand.IAC, (byte)TelnetCommand.DO, (byte)TelnetOption.WindowSize }, this); Console.WriteLine("SERVER {0} {1}", TelnetCommand.DO, TelnetOption.WindowSize); AddClientOption((byte)option, true); this.sender.SendSucessMessage(string.Format("Negotiating Client Option '{0}'", option), "ON"); //server.Send(new byte[] { // (byte)TelnetCommand.IAC, // (byte)TelnetCommand.DO, // (byte)TelnetOption.DataEntryTerminal}, this); //Console.WriteLine("SERVER {0} {1}", TelnetCommand.DO, TelnetOption.DataEntryTerminal); break; case TelnetOption.TerminalType: server.Send(new byte[] { (byte)TelnetCommand.IAC, (byte)TelnetCommand.SB, (byte)TelnetOption.TerminalType, 0x1, (byte)TelnetCommand.IAC, (byte)TelnetCommand.SE }, this); Console.WriteLine("SERVER {0} {1}", TelnetCommand.SB, TelnetOption.TerminalType); AddClientOption((byte)option, true); this.sender.SendSucessMessage(string.Format("Negotiating Client Option '{0}'", option), "ON"); break; case TelnetOption.Charset: server.Send(new byte[] { (byte)TelnetCommand.IAC, (byte)TelnetCommand.SB, (byte)TelnetOption.Charset, 0x1, (byte)'U', (byte)'T', (byte)'F', (byte)'-', (byte)'8', (byte)TelnetCommand.IAC, (byte)TelnetCommand.SE }, this); Console.WriteLine("SERVER {0} {1}", TelnetCommand.SB, TelnetOption.TerminalType); AddClientOption((byte)option, true); this.sender.SendSucessMessage(string.Format("Negotiating Client Option '{0}'", option), "ON"); break; } break; case TelnetCommand.SB: switch (option) { case TelnetOption.WindowSize: int w = negBuffer[i + 3] << 4 | negBuffer[i + 4]; int h = negBuffer[i + 5] << 4 | negBuffer[i + 6]; this.terminalHeight = h; this.terminalWidth = w; Console.WriteLine("Window Size: {0} {1}", w, h); i = i + 6; if (this.player == null || this.player.PlayerState != ioPlayer.PlayerStateEnum.WaitingForCommand) { this.sender.SendMessage(string.Format("Got Terminal Size: '{0}x{1}'", w, h)); } break; case TelnetOption.TerminalType: byte Opt = negBuffer[i + 3]; List <byte> tType = new List <byte>(); bool isValid = false; for (int ct = i + 4; ct < negBuffer.Length; ct++) { i = ct; if (negBuffer[ct] == (byte)TelnetCommand.IAC && ct + 1 < negBuffer.Length && negBuffer[ct + 1] == (byte)TelnetCommand.SE) { isValid = true; break; } else { tType.Add(negBuffer[ct]); } } string tt = Encoding.UTF8.GetString( Encoding.Convert(encoding, Encoding.UTF8, tType.ToArray())).ToUpper(); if (isValid) { if (!terminalTypes.Contains(tt)) { terminalTypes.Add(tt); terminalType = tt; VerifyTerminalType(); Console.WriteLine("Got known terminal type: {0}", tt); if (this.player == null || this.player.PlayerState != ioPlayer.PlayerStateEnum.WaitingForCommand) { this.sender.SendSucessMessage("Got known terminal type", tt); } } else { VerifyTerminalType(); Console.WriteLine("Got unknown Terminal type: {0}", tt); if (this.player == null || this.player.PlayerState != ioPlayer.PlayerStateEnum.WaitingForCommand) { this.sender.SendFailMessage("Got unknown terminal type", tt); } } } else { Console.WriteLine("Terminal type: {0}", tt); Console.WriteLine("WTF!!!!"); if (this.player == null || this.player.PlayerState != ioPlayer.PlayerStateEnum.WaitingForCommand) { this.sender.SendFailMessage("Unable to decode terminal type", tt); } } break; case TelnetOption.Charset: Console.WriteLine("Charset"); break; } break; } } } //Console.WriteLine("----------------"); }