/// <summary> /// Process a global message. /// </summary> /// <param name="packet"></param> /// <returns></returns> protected internal override bool ProcessGlobalMessage(SSHPacket packet) { // We need to filter for any messages that require a response from the // connection protocol such as channel open or global requests. These // are not handled anywhere else within this implementation because // doing so would require a thread to wait. try { switch (packet.MessageID) { case SSH_MSG_CHANNEL_OPEN: { #if DEBUG System.Diagnostics.Trace.WriteLine("Received SSH_MSG_CHANNEL_OPEN"); #endif // Attempt to open the channel System.String type = packet.ReadString(); int remoteid = (int)packet.ReadUINT32(); int remotewindow = (int)packet.ReadUINT32(); int remotepacket = (int)packet.ReadUINT32(); byte[] requestdata = packet.Available > 0 ? new byte[packet.Available] : null; if (requestdata != null) { packet.ReadBytes(requestdata); } ProcessChannelOpenRequest(type, remoteid, remotewindow, remotepacket, requestdata); return(true); } case SSH_MSG_GLOBAL_REQUEST: { #if DEBUG System.Diagnostics.Trace.WriteLine("Received SSH_MSG_GLOBAL_REQUEST"); #endif // Attempt to process the global request System.String requestname = packet.ReadString(); bool wantreply = packet.ReadBool(); byte[] requestdata = new byte[packet.Available]; packet.ReadBytes(requestdata); // Process the request ProcessGlobalRequest(requestname, wantreply, requestdata); return(true); } default: return(false); } } catch (System.IO.IOException ex) { throw new SSHException(ex.Message, SSHException.INTERNAL_ERROR); } }
/// <summary> /// Sends a global request. /// </summary> /// <param name="request"></param> /// <param name="wantreply"></param> /// <returns></returns> public bool SendGlobalRequest(GlobalRequest request, bool wantreply) { try { SSHPacket packet = GetPacket(); packet.WriteByte(SSH_MSG_GLOBAL_REQUEST); packet.WriteString(request.Name); packet.WriteBool(wantreply); if (request.Data != null) { packet.WriteBytes(request.Data); } #if DEBUG System.Diagnostics.Trace.WriteLine("Sending SSH_MSG_GLOBAL_REQUEST"); System.Diagnostics.Trace.WriteLine(request.Name); #endif SendMessage(packet); if (wantreply) { packet = GlobalMessages.NextMessage(GLOBAL_REQUEST_MESSAGES); if (packet.MessageID == SSH_MSG_REQUEST_SUCCESS) { if (packet.Available > 1) { byte[] tmp = new byte[packet.Available]; packet.ReadBytes(tmp); request.Data = tmp; } else { request.Data = null; } return(true); } else { return(false); } } else { return(true); } } catch (System.IO.IOException ex) { throw new SSHException(ex.Message, SSHException.INTERNAL_ERROR); } }
/// <summary> /// Opens a channel /// </summary> /// <param name="channel"></param> /// <param name="requestdata"></param> public void OpenChannel(SSH2Channel channel, byte[] requestdata) { lock (this) { try { int channelid = AllocateChannel(channel); if (channelid == -1) { throw new ChannelOpenException("Maximum number of channels exceeded", ChannelOpenException.RESOURCE_SHORTAGE); } channel.Init(this, channelid); SSHPacket packet = GetPacket(); packet.WriteByte(SSH_MSG_CHANNEL_OPEN); packet.WriteString(channel.Name); packet.WriteUINT32(channel.ChannelID); packet.WriteUINT32(channel.WindowSize); packet.WriteUINT32(channel.PacketSize); if (requestdata != null) { packet.WriteBytes(requestdata); } #if DEBUG System.Diagnostics.Trace.WriteLine("Sending SSH_MSG_CHANNEL_OPEN"); System.Diagnostics.Trace.WriteLine("Channelid=" + channel.ChannelID); System.Diagnostics.Trace.WriteLine("Name=" + channel.Name); #endif transport.SendMessage(packet); packet = channel.MessageStore.NextMessage(CHANNEL_OPEN_RESPONSE_MESSAGES); #if DEBUG System.Diagnostics.Trace.WriteLine("Received reply to SSH_MSG_CHANNEL_OPEN"); channel.LogMessage(packet); #endif if (packet.MessageID == SSH_MSG_CHANNEL_OPEN_FAILURE) { FreeChannel(channel); int reason = (int)packet.ReadUINT32(); throw new ChannelOpenException(packet.ReadString(), reason); } else { int remoteid = (int)packet.ReadUINT32(); int remotewindow = (int)packet.ReadUINT32(); int remotepacket = (int)packet.ReadUINT32(); byte[] responsedata = new byte[packet.Available]; packet.ReadBytes(responsedata); channel.Open(remoteid, remotewindow, remotepacket, responsedata); return; } } catch (System.IO.IOException ex) { throw new SSHException(ex.Message, SSHException.INTERNAL_ERROR); } } }