📄 channelmanager.java
字号:
int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);
int windowChange = ((msg[5] & 0xff) << 24) | ((msg[6] & 0xff) << 16) | ((msg[7] & 0xff) << 8) | (msg[8] & 0xff);
Channel c = getChannel(id);
if (c == null)
throw new IOException("Unexpected SSH_MSG_CHANNEL_WINDOW_ADJUST message for non-existent channel " + id);
synchronized (c)
{
final long huge = 0xFFFFffffL; /* 2^32 - 1 */
c.remoteWindow += (windowChange & huge); /* avoid sign extension */
if ((c.remoteWindow > huge))
c.remoteWindow = huge;
c.notifyAll();
}
if (log.isEnabled())
log.log(80, "Got SSH_MSG_CHANNEL_WINDOW_ADJUST (channel " + id + ", " + windowChange + ")");
}
public void msgChannelOpen(byte[] msg, int msglen) throws IOException
{
TypesReader tr = new TypesReader(msg, 0, msglen);
tr.readByte(); // skip packet type
String channelType = tr.readString();
int remoteID = tr.readUINT32(); /* sender channel */
int remoteWindow = tr.readUINT32(); /* initial window size */
int remoteMaxPacketSize = tr.readUINT32(); /* maximum packet size */
if ("x11".equals(channelType))
{
synchronized (x11_magic_cookies)
{
/* If we did not request X11 forwarding, then simply ignore this bogus request. */
if (x11_magic_cookies.size() == 0)
{
PacketChannelOpenFailure pcof = new PacketChannelOpenFailure(remoteID,
Packets.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED, "X11 forwarding not activated", "");
tm.sendAsynchronousMessage(pcof.getPayload());
if (log.isEnabled())
log.log(20, "Unexpected X11 request, denying it!");
return;
}
}
String remoteOriginatorAddress = tr.readString();
int remoteOriginatorPort = tr.readUINT32();
Channel c = new Channel(this);
synchronized (c)
{
c.remoteID = remoteID;
c.remoteWindow = remoteWindow & 0xFFFFffffL; /* properly convert UINT32 to long */
c.remoteMaxPacketSize = remoteMaxPacketSize;
c.localID = addChannel(c);
}
/*
* The open confirmation message will be sent from another thread
*/
RemoteX11AcceptThread rxat = new RemoteX11AcceptThread(c, remoteOriginatorAddress, remoteOriginatorPort);
rxat.setDaemon(true);
rxat.start();
return;
}
if ("forwarded-tcpip".equals(channelType))
{
String remoteConnectedAddress = tr.readString(); /* address that was connected */
int remoteConnectedPort = tr.readUINT32(); /* port that was connected */
String remoteOriginatorAddress = tr.readString(); /* originator IP address */
int remoteOriginatorPort = tr.readUINT32(); /* originator port */
RemoteForwardingData rfd = null;
synchronized (remoteForwardings)
{
rfd = (RemoteForwardingData) remoteForwardings.get(new Integer(remoteConnectedPort));
}
if (rfd == null)
{
PacketChannelOpenFailure pcof = new PacketChannelOpenFailure(remoteID,
Packets.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED,
"No thanks, unknown port in forwarded-tcpip request", "");
/* Always try to be polite. */
tm.sendAsynchronousMessage(pcof.getPayload());
if (log.isEnabled())
log.log(20, "Unexpected forwarded-tcpip request, denying it!");
return;
}
Channel c = new Channel(this);
synchronized (c)
{
c.remoteID = remoteID;
c.remoteWindow = remoteWindow & 0xFFFFffffL; /* convert UINT32 to long */
c.remoteMaxPacketSize = remoteMaxPacketSize;
c.localID = addChannel(c);
}
/*
* The open confirmation message will be sent from another thread.
*/
RemoteAcceptThread rat = new RemoteAcceptThread(c, remoteConnectedAddress, remoteConnectedPort,
remoteOriginatorAddress, remoteOriginatorPort, rfd.targetAddress, rfd.targetPort);
rat.setDaemon(true);
rat.start();
return;
}
/* Tell the server that we have no idea what it is talkin about */
PacketChannelOpenFailure pcof = new PacketChannelOpenFailure(remoteID, Packets.SSH_OPEN_UNKNOWN_CHANNEL_TYPE,
"Unknown channel type", "");
tm.sendAsynchronousMessage(pcof.getPayload());
if (log.isEnabled())
log.log(20, "The peer tried to open an unsupported channel type (" + channelType + ")");
}
public void msgChannelRequest(byte[] msg, int msglen) throws IOException
{
TypesReader tr = new TypesReader(msg, 0, msglen);
tr.readByte(); // skip packet type
int id = tr.readUINT32();
Channel c = getChannel(id);
if (c == null)
throw new IOException("Unexpected SSH_MSG_CHANNEL_REQUEST message for non-existent channel " + id);
String type = tr.readString("US-ASCII");
boolean wantReply = tr.readBoolean();
if (log.isEnabled())
log.log(80, "Got SSH_MSG_CHANNEL_REQUEST (channel " + id + ", '" + type + "')");
if (type.equals("exit-status"))
{
if (wantReply != false)
throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message, 'want reply' is true");
int exit_status = tr.readUINT32();
if (tr.remain() != 0)
throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message");
synchronized (c)
{
c.exit_status = new Integer(exit_status);
c.notifyAll();
}
if (log.isEnabled())
log.log(50, "Got EXIT STATUS (channel " + id + ", status " + exit_status + ")");
return;
}
if (type.equals("exit-signal"))
{
if (wantReply != false)
throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message, 'want reply' is true");
String signame = tr.readString("US-ASCII");
tr.readBoolean();
tr.readString();
tr.readString();
if (tr.remain() != 0)
throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message");
synchronized (c)
{
c.exit_signal = signame;
c.notifyAll();
}
if (log.isEnabled())
log.log(50, "Got EXIT SIGNAL (channel " + id + ", signal " + signame + ")");
return;
}
/* We simply ignore unknown channel requests, however, if the server wants a reply,
* then we signal that we have no idea what it is about.
*/
if (wantReply)
{
byte[] reply = new byte[5];
reply[0] = Packets.SSH_MSG_CHANNEL_FAILURE;
reply[1] = (byte) (c.remoteID >> 24);
reply[2] = (byte) (c.remoteID >> 16);
reply[3] = (byte) (c.remoteID >> 8);
reply[4] = (byte) (c.remoteID);
tm.sendAsynchronousMessage(reply);
}
if (log.isEnabled())
log.log(50, "Channel request '" + type + "' is not known, ignoring it");
}
public void msgChannelEOF(byte[] msg, int msglen) throws IOException
{
if (msglen != 5)
throw new IOException("SSH_MSG_CHANNEL_EOF message has wrong size (" + msglen + ")");
int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);
Channel c = getChannel(id);
if (c == null)
throw new IOException("Unexpected SSH_MSG_CHANNEL_EOF message for non-existent channel " + id);
synchronized (c)
{
c.EOF = true;
c.notifyAll();
}
if (log.isEnabled())
log.log(50, "Got SSH_MSG_CHANNEL_EOF (channel " + id + ")");
}
public void msgChannelClose(byte[] msg, int msglen) throws IOException
{
if (msglen != 5)
throw new IOException("SSH_MSG_CHANNEL_CLOSE message has wrong size (" + msglen + ")");
int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);
Channel c = getChannel(id);
if (c == null)
throw new IOException("Unexpected SSH_MSG_CHANNEL_CLOSE message for non-existent channel " + id);
synchronized (c)
{
c.EOF = true;
c.state = Channel.STATE_CLOSED;
c.setReasonClosed("Close requested by remote");
c.closeMessageRecv = true;
removeChannel(c.localID);
c.notifyAll();
}
if (log.isEnabled())
log.log(50, "Got SSH_MSG_CHANNEL_CLOSE (channel " + id + ")");
}
public void msgChannelSuccess(byte[] msg, int msglen) throws IOException
{
if (msglen != 5)
throw new IOException("SSH_MSG_CHANNEL_SUCCESS message has wrong size (" + msglen + ")");
int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);
Channel c = getChannel(id);
if (c == null)
throw new IOException("Unexpected SSH_MSG_CHANNEL_SUCCESS message for non-existent channel " + id);
synchronized (c)
{
c.successCounter++;
c.notifyAll();
}
if (log.isEnabled())
log.log(80, "Got SSH_MSG_CHANNEL_SUCCESS (channel " + id + ")");
}
public void msgChannelFailure(byte[] msg, int msglen) throws IOException
{
if (msglen != 5)
throw new IOException("SSH_MSG_CHANNEL_FAILURE message has wrong size (" + msglen + ")");
int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);
Channel c = getChannel(id);
if (c == null)
throw new IOException("Unexpected SSH_MSG_CHANNEL_FAILURE message for non-existent channel " + id);
synchronized (c)
{
c.failedCounter++;
c.notifyAll();
}
if (log.isEnabled())
log.log(50, "Got SSH_MSG_CHANNEL_FAILURE (channel " + id + ")");
}
public void msgChannelOpenConfirmation(byte[] msg, int msglen) throws IOException
{
PacketChannelOpenConfirmation sm = new PacketChannelOpenConfirmation(msg, 0, msglen);
Channel c = getChannel(sm.recipientChannelID);
if (c == null)
throw new IOException("Unexpected SSH_MSG_CHANNEL_OPEN_CONFIRMATION message for non-existent channel "
+ sm.recipientChannelID);
synchronized (c)
{
if (c.state != Channel.STATE_OPENING)
throw new IOException("Unexpected SSH_MSG_CHANNEL_OPEN_CONFIRMATION message for channel "
+ sm.recipientChannelID);
c.remoteID = sm.senderChannelID;
c.remoteWindow = sm.initialWindowSize & 0xFFFFffffL; /* convert UINT32 to long */
c.remoteMaxPacketSize = sm.maxPacketSize;
c.state = Channel.STATE_OPEN;
c.notifyAll();
}
if (log.isEnabled())
log.log(50, "Got SSH_MSG_CHANNEL_OPEN_CONFIRMATION (channel " + sm.recipientChannelID + " / remote: "
+ sm.senderChannelID + ")");
}
public void msgChannelOpenFailure(byte[] msg, int msglen) throws IOException
{
if (msglen < 5)
throw new IOException("SSH_MSG_CHANNEL_OPEN_FAILURE message has wrong size (" + msglen + ")");
int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);
Channel c = getChannel(id);
if (c == null)
throw new IOException("Unexpected SSH_MSG_CHANNEL_OPEN_FAILURE message for non-existent channel " + id);
synchronized (c)
{
c.EOF = true;
c.state = Channel.STATE_CLOSED;
c.notifyAll();
}
if (log.isEnabled())
log.log(50, "Got SSH_MSG_CHANNEL_OPEN_FAILURE (channel " + id + ")");
}
public void msgGlobalRequest(byte[] msg, int msglen) throws IOException
{
/* Currently we do not support any kind of global request */
TypesReader tr = new TypesReader(msg, 0, msglen);
tr.readByte(); // skip packet type
String requestName = tr.readString();
boolean wantReply = tr.readBoolean();
if (wantReply)
{
byte[] reply_failure = new byte[1];
reply_failure[0] = Packets.SSH_MSG_REQUEST_FAILURE;
tm.sendAsynchronousMessage(reply_failure);
}
/* We do not clean up the requestName String - that is OK for debug */
if (log.isEnabled())
log.log(80, "Got SSH_MSG_GLOBAL_REQUEST (" + requestName + ")");
}
public void msgGlobalSuccess() throws IOException
{
synchronized (channels)
{
globalSuccessCounter++;
channels.notifyAll();
}
if (log.isEnabled())
log.log(80, "Got SSH_MSG_REQUEST_SUCCESS");
}
public void msgGlobalFailure() throws IOException
{
synchronized (channels)
{
globalFailedCounter++;
channels.notifyAll();
}
if (log.isEnabled())
log.log(80, "Got SSH_MSG_REQUEST_FAILURE");
}
public void handleMessage(byte[] msg, int msglen) throws IOException
{
if (msg == null)
{
if (log.isEnabled())
log.log(50, "HandleMessage: got shutdown");
synchronized (listenerThreads)
{
for (int i = 0; i < listenerThreads.size(); i++)
{
IChannelWorkerThread lat = (IChannelWorkerThread) listenerThreads.elementAt(i);
lat.stopWorking();
}
listenerThreadsAllowed = false;
}
synchronized (channels)
{
shutdown = true;
for (int i = 0; i < channels.size(); i++)
{
Channel c = (Channel) channels.elementAt(i);
synchronized (c)
{
c.EOF = true;
c.state = Channel.STATE_CLOSED;
c.setReasonClosed("The connection is being shutdown");
c.closeMessageRecv = true; /*
* You never know, perhaps
* we are waiting for a
* pending close message
* from the server...
*/
c.notifyAll();
}
}
/* Works with J2ME */
channels.setSize(0);
channels.trimToSize();
channels.notifyAll(); /* Notify global response waiters */
return;
}
}
switch (msg[0])
{
case Packets.SSH_MSG_CHANNEL_OPEN_CONFIRMATION:
msgChannelOpenConfirmation(msg, msglen);
break;
case Packets.SSH_MSG_CHANNEL_WINDOW_ADJUST:
msgChannelWindowAdjust(msg, msglen);
break;
case Packets.SSH_MSG_CHANNEL_DATA:
msgChannelData(msg, msglen);
break;
case Packets.SSH_MSG_CHANNEL_EXTENDED_DATA:
msgChannelExtendedData(msg, msglen);
break;
case Packets.SSH_MSG_CHANNEL_REQUEST:
msgChannelRequest(msg, msglen);
break;
case Packets.SSH_MSG_CHANNEL_EOF:
msgChannelEOF(msg, msglen);
break;
case Packets.SSH_MSG_CHANNEL_OPEN:
msgChannelOpen(msg, msglen);
break;
case Packets.SSH_MSG_CHANNEL_CLOSE:
msgChannelClose(msg, msglen);
break;
case Packets.SSH_MSG_CHANNEL_SUCCESS:
msgChannelSuccess(msg, msglen);
break;
case Packets.SSH_MSG_CHANNEL_FAILURE:
msgChannelFailure(msg, msglen);
break;
case Packets.SSH_MSG_CHANNEL_OPEN_FAILURE:
msgChannelOpenFailure(msg, msglen);
break;
case Packets.SSH_MSG_GLOBAL_REQUEST:
msgGlobalRequest(msg, msglen);
break;
case Packets.SSH_MSG_REQUEST_SUCCESS:
msgGlobalSuccess();
break;
case Packets.SSH_MSG_REQUEST_FAILURE:
msgGlobalFailure();
break;
default:
throw new IOException("Cannot handle unknown channel message " + (msg[0] & 0xff));
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -