public void Close(Cipher cipher, Random rnd, MAC mac, int sequence, DataFragment result) { if(!_is_open) throw new SSHException("internal state error"); int blocksize = cipher==null? 8 : cipher.BlockSize; int payload_length = _writer.Length - (SEQUENCE_MARGIN + LENGTH_MARGIN + PADDING_MARGIN); int r = 11 - payload_length % blocksize; while(r < 4) r += blocksize; _paddingLength = r; _packetLength = PADDING_MARGIN + payload_length + _paddingLength; int image_length = _packetLength + LENGTH_MARGIN; //fill padding for(int i=0; i<_paddingLength; i+=4) _writer.Write(rnd.Next()); //manipulate stream byte[] rawbuf = _writer.UnderlyingBuffer; SSHUtil.WriteIntToByteArray(rawbuf, 0, sequence); SSHUtil.WriteIntToByteArray(rawbuf, SEQUENCE_MARGIN, _packetLength); rawbuf[SEQUENCE_MARGIN + LENGTH_MARGIN] = (byte)_paddingLength; //mac if(mac!=null) { _mac = mac.ComputeHash(rawbuf, 0, _packetLength+LENGTH_MARGIN+SEQUENCE_MARGIN); Array.Copy(_mac, 0, rawbuf, _packetLength+LENGTH_MARGIN+SEQUENCE_MARGIN, _mac.Length); image_length += _mac.Length; } //encrypt if(cipher!=null) cipher.Encrypt(rawbuf, SEQUENCE_MARGIN, _packetLength+LENGTH_MARGIN, rawbuf, SEQUENCE_MARGIN); result.Init(rawbuf, SEQUENCE_MARGIN, image_length); _is_open = false; }
private int _requiredResponseCount; //for keyboard-interactive authentication internal SSH2Connection(SSHConnectionParameter param, AbstractGranadosSocket strm, ISSHConnectionEventReceiver r, string serverversion, string clientversion) : base(param, strm, r) { _cInfo = new SSH2ConnectionInfo(); _cInfo._serverVersionString = serverversion; _cInfo._clientVersionString = clientversion; _packetReceiver = new SynchronizedPacketReceiver(this); _packetBuilder = new SSH2PacketBuilder(_packetReceiver); _transmissionPacket = new SSH2TransmissionPacket(); _transmissionImage = new DataFragment(null, 0, 0); }
public void Append(DataFragment data) { if(_length==0) { AssureCapacity(RoundUp(data.Length)); Array.Copy(data.Data, data.Offset, _data, 0, data.Length); _offset = 0; _length = data.Length; } else { Append(data.Data, data.Offset, data.Length); } }
private void Init(DataFragment data) { _data = data.Data; _offset = data.Offset; _limit = _offset + data.Length; }
public void OnData(DataFragment data) { _connection.AsyncReceivePacket(data); }
private SSH1PacketType SneakPacketType(DataFragment data) { return (SSH1PacketType)data[0]; }
public void StartReceivingThread(Action<DataFragment> onDataCallback, Action onClosedCallback) { if (_socket == null || _receivingThread != null) { return; } _receivingThread = new Thread(() => { byte[] buffer = new byte[0x20000]; DataFragment dataFrag = new DataFragment(buffer, 0, 0); try { while (true) { int received = _socket.Receive(buffer, 0, buffer.Length, SocketFlags.None); if (received > 0) { dataFrag.SetLength(0, received); onDataCallback(dataFrag); } } } catch (Exception e) { if (!_shutdown) { System.Diagnostics.Debug.WriteLine(e.Message); System.Diagnostics.Debug.WriteLine(e.StackTrace); } if (!_socket.Connected && !_shutdown) { // closed by the peer onClosedCallback(); } } }); _receivingThread.Start(); }
public SSH2MsgNewKeys(DataFragment data, Handler onDequeued) : base(data.Data, data.Offset, data.Length) { _onDequeued = onDequeued; }
private bool IsMsgNewKeys(DataFragment packet) { return packet.Length >= 1 && packet.ByteAt(0) == (byte)PacketType.SSH_MSG_NEWKEYS; }
/// <summary> /// Handle data instead of the core handler. /// </summary> /// <param name="data">data</param> protected abstract void FilterData(DataFragment data);
/// <summary> /// Implements <see cref="IDataHandler"/> /// </summary> /// <param name="data"></param> public void OnData(DataFragment data) { FilterData(data); }
public void Write(DataFragment data) { Write(data.Data, data.Offset, data.Length); }
/// <summary> /// Make another view of this instance. /// </summary> /// <param name="startIndex">start index for the new view.</param> public DataFragment MakeView(int startIndex) { if (startIndex < 0 || startIndex > _length) { throw new ArgumentOutOfRangeException(); } DataFragment newInstance = new DataFragment(_data, _offset + startIndex, _length - startIndex); return newInstance; }
// for debug private void Dump(string caption, DataFragment data) { Dump(caption, data.Data, data.Offset, data.Length); }
public override void OnData(DataFragment data) { #if DUMP_PACKET Dump("SCP: OnData", data); #endif if (_dataHandler != null) { _dataHandler(data); } }
public SSH2PacketBuilder(IDataHandler handler) : base(handler) { _buffer = new DataFragment(0x1000); _packet = new DataFragment(_buffer.Capacity); _sequence = 0; _cipher = null; _mac = null; _head = null; }
public override void OnData(DataFragment data) { lock (_cipherSync) { try { if (!_keyError) { // key error detection if (_pending && DateTime.UtcNow > _keyErrorDetectionTimeout) { _keyError = true; // disable accepting data any more return; } _buffer.Append(data); if (!_pending) { ProcessBuffer(); } } } catch (Exception ex) { OnError(ex); } } }
/// <summary> /// Call OnData() of a core handler /// </summary> /// <param name="data"></param> protected void OnDataInternal(DataFragment data) { _innerHandler.OnData(data); }
public SSH2TransmissionPacket() { _writer = new SSH2DataWriter(); _dataFragment = new DataFragment(null, 0, 0); _isOpen = false; }
/// <summary> /// Write data to the socket /// </summary> /// <param name="sock">socket object</param> /// <param name="data">data to write</param> public static void Write(this IGranadosSocket sock, DataFragment data) { if (data.Length > 0) { sock.Write(data.Data, data.Offset, data.Length); } }
public bool Send(DataFragment data, int timeoutMillisec) { if (_socket == null) { return false; } return SendBytes(_socket, data.Data, data.Offset, data.Length, timeoutMillisec); }
public void OnData(DataFragment data) { }
internal void AsyncReceivePacket(DataFragment data) { try { SSH1DataReader re = new SSH1DataReader(data); SSH1PacketType pt = (SSH1PacketType)re.ReadByte(); switch (pt) { case SSH1PacketType.SSH_SMSG_STDOUT_DATA: { int len = re.ReadInt32(); DataFragment frag = re.GetRemainingDataView(len); _channel_collection.FindChannelEntry(_shellID).Receiver.OnData(frag.Data, frag.Offset, frag.Length); } break; case SSH1PacketType.SSH_SMSG_STDERR_DATA: { _channel_collection.FindChannelEntry(_shellID).Receiver.OnExtendedData((int)SSH1PacketType.SSH_SMSG_STDERR_DATA, re.ReadByteString()); } break; case SSH1PacketType.SSH_MSG_CHANNEL_DATA: { int channel = re.ReadInt32(); int len = re.ReadInt32(); DataFragment frag = re.GetRemainingDataView(len); _channel_collection.FindChannelEntry(channel).Receiver.OnData(frag.Data, frag.Offset, frag.Length); } break; case SSH1PacketType.SSH_MSG_PORT_OPEN: ProcessPortforwardingRequest(_eventReceiver, re); break; case SSH1PacketType.SSH_MSG_CHANNEL_CLOSE: { int channel = re.ReadInt32(); ISSHChannelEventReceiver r = _channel_collection.FindChannelEntry(channel).Receiver; _channel_collection.UnregisterChannelEventReceiver(channel); r.OnChannelClosed(); } break; case SSH1PacketType.SSH_MSG_CHANNEL_CLOSE_CONFIRMATION: { int channel = re.ReadInt32(); } break; case SSH1PacketType.SSH_MSG_DISCONNECT: _eventReceiver.OnConnectionClosed(); break; case SSH1PacketType.SSH_SMSG_EXITSTATUS: _channel_collection.FindChannelEntry(_shellID).Receiver.OnChannelClosed(); break; case SSH1PacketType.SSH_MSG_DEBUG: _eventReceiver.OnDebugMessage(false, re.ReadByteString()); break; case SSH1PacketType.SSH_MSG_IGNORE: _eventReceiver.OnIgnoreMessage(re.ReadByteString()); break; case SSH1PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION: { int local = re.ReadInt32(); int remote = re.ReadInt32(); _channel_collection.FindChannelEntry(local).Receiver.OnChannelReady(); } break; case SSH1PacketType.SSH_SMSG_SUCCESS: if (_executingShell) { ExecShell(); _channel_collection.FindChannelEntry(_shellID).Receiver.OnChannelReady(); _executingShell = false; } break; default: _eventReceiver.OnUnknownMessage((byte)pt, data.GetBytes()); break; } } catch (Exception ex) { _eventReceiver.OnError(ex); } }
/// <summary> /// Constructor /// </summary> /// <param name="socket">socket object (must be already connected)</param> /// <param name="handler">callback handler (can be null if no handler is specified)</param> public PlainSocket(Socket socket, IDataHandler handler) { _handler = handler ?? new NullDataHandler(); _socket = socket; Debug.Assert(_socket.Connected); _socketStatus = SocketStatus.Ready; _data = new DataFragment(0x1000); }
public override void OnData(DataFragment data) { try { while (_buffer.Length - _writeOffset < data.Length) ExpandBuffer(); Array.Copy(data.Data, data.Offset, _buffer, _writeOffset, data.Length); _writeOffset += data.Length; DataFragment p = ConstructPacket(); while (p != null) { _inner_handler.OnData(p); p = ConstructPacket(); } ReduceBuffer(); } catch (Exception ex) { _inner_handler.OnError(ex); } }
/// <summary> /// Implements <see cref="IDataHandler"/> /// </summary> /// <param name="data"></param> public void OnData(DataFragment data) { EnqueueDataFragment(data); }
public void Recycle(DataFragment data) { Init(data); }
/// <summary> /// Send a packet then receive a response. /// </summary> /// <param name="data">a packet to be sent</param> /// <returns>a packet received</returns> /// <exception cref="SSHException">unprocessed incoming packet exists</exception> public DataFragment SendAndWaitResponse(DataFragment data) { lock (_sync) { if (data.Length > 0) { // queue must have no items if (_queue.Count > 0) { Exception err = _queue.Peek() as Exception; if (err != null) { ClearQueue(); throw err; } throw new SSHException("Unexpected incoming packet"); } _socket.Write(data); } return WaitResponse(); } }
public SSHDataReader(DataFragment data) { Init(data); }
/// <summary> /// Enqueue a copy of the specified <see cref="DataFragment"/> /// </summary> /// <param name="data"></param> private void EnqueueDataFragment(DataFragment data) { lock (_sync) { _queue.Enqueue(data.Isolate()); Monitor.PulseAll(_sync); } }