public PacketUserauthFailure(byte payload[]) throws IOException { this.payload = payload; TypesReader tr = new TypesReader(payload); int packet_type = tr.readByte(); if (packet_type != Packets.SSH_MSG_USERAUTH_FAILURE) { throw new PacketTypeException(packet_type); } authThatCanContinue = new HashSet<String>(Arrays.asList(tr.readNameList())); partialSuccess = tr.readBoolean(); if (tr.remain() != 0) { throw new PacketFormatException( String.format("Padding in %s", Packets.getMessageName(packet_type))); } }
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 */ log.debug("Got SSH_MSG_GLOBAL_REQUEST (" + requestName + ")"); }
public void receiveLoop() throws IOException { byte[] msg = new byte[35000]; while (true) { int msglen; try { msglen = tc.receiveMessage(msg, 0, msg.length); } catch (SocketTimeoutException e) { // Timeout in read if (idle) { log.debug("Ignoring socket timeout"); continue; } throw e; } idle = true; int type = msg[0] & 0xff; if (type == Packets.SSH_MSG_IGNORE) { continue; } if (type == Packets.SSH_MSG_DEBUG) { if (log.isDebugEnabled()) { TypesReader tr = new TypesReader(msg, 0, msglen); tr.readByte(); tr.readBoolean(); StringBuilder debugMessageBuffer = new StringBuilder(); debugMessageBuffer.append(tr.readString("UTF-8")); for (int i = 0; i < debugMessageBuffer.length(); i++) { char c = debugMessageBuffer.charAt(i); if ((c >= 32) && (c <= 126)) { continue; } debugMessageBuffer.setCharAt(i, '\uFFFD'); } log.debug("DEBUG Message from remote: '" + debugMessageBuffer.toString() + "'"); } continue; } if (type == Packets.SSH_MSG_UNIMPLEMENTED) { throw new IOException("Peer sent UNIMPLEMENTED message, that should not happen."); } if (type == Packets.SSH_MSG_DISCONNECT) { TypesReader tr = new TypesReader(msg, 0, msglen); tr.readByte(); int reason_code = tr.readUINT32(); StringBuilder reasonBuffer = new StringBuilder(); reasonBuffer.append(tr.readString("UTF-8")); /* * Do not get fooled by servers that send abnormal long error * messages */ if (reasonBuffer.length() > 255) { reasonBuffer.setLength(255); reasonBuffer.setCharAt(254, '.'); reasonBuffer.setCharAt(253, '.'); reasonBuffer.setCharAt(252, '.'); } /* * Also, check that the server did not send characters that may * screw up the receiver -> restrict to reasonable US-ASCII * subset -> "printable characters" (ASCII 32 - 126). Replace * all others with 0xFFFD (UNICODE replacement character). */ for (int i = 0; i < reasonBuffer.length(); i++) { char c = reasonBuffer.charAt(i); if ((c >= 32) && (c <= 126)) { continue; } reasonBuffer.setCharAt(i, '\uFFFD'); } throw new IOException( "Peer sent DISCONNECT message (reason code " + reason_code + "): " + reasonBuffer.toString()); } /* * Is it a KEX Packet? */ if ((type == Packets.SSH_MSG_KEXINIT) || (type == Packets.SSH_MSG_NEWKEYS) || ((type >= 30) && (type <= 49))) { km.handleMessage(msg, msglen); continue; } MessageHandler mh = null; for (int i = 0; i < messageHandlers.size(); i++) { HandlerEntry he = messageHandlers.get(i); if ((he.low <= type) && (type <= he.high)) { mh = he.mh; break; } } if (mh == null) { throw new IOException("Unexpected SSH message (type " + type + ")"); } mh.handleMessage(msg, msglen); } }
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); ServerSessionImpl server_session = null; if (server_state != null) { synchronized (c) { server_session = c.ss; } } String type = tr.readString("US-ASCII"); boolean wantReply = tr.readBoolean(); log.debug("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 exit-status 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(); } log.debug("Got EXIT STATUS (channel " + id + ", status " + exit_status + ")"); return; } if ((server_state == null) && (type.equals("exit-signal"))) { if (wantReply != false) throw new IOException( "Badly formatted SSH_MSG_CHANNEL_REQUEST exit-signal 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(); } log.debug("Got EXIT SIGNAL (channel " + id + ", signal " + signame + ")"); return; } if ((server_session != null) && (type.equals("pty-req"))) { PtySettings pty = new PtySettings(); pty.term = tr.readString(); pty.term_width_characters = tr.readUINT32(); pty.term_height_characters = tr.readUINT32(); pty.term_width_pixels = tr.readUINT32(); pty.term_height_pixels = tr.readUINT32(); pty.terminal_modes = tr.readByteString(); if (tr.remain() != 0) throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message"); Runnable run_after_sending_success = null; ServerSessionCallback sscb = server_session.getServerSessionCallback(); if (sscb != null) run_after_sending_success = sscb.requestPtyReq(server_session, pty); if (wantReply) { if (run_after_sending_success != null) { tm.sendAsynchronousMessage(new PacketChannelSuccess(c.remoteID).getPayload()); } else { tm.sendAsynchronousMessage(new PacketChannelFailure(c.remoteID).getPayload()); } } if (run_after_sending_success != null) { runAsync(run_after_sending_success); } return; } if ((server_session != null) && (type.equals("shell"))) { if (tr.remain() != 0) throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message"); Runnable run_after_sending_success = null; ServerSessionCallback sscb = server_session.getServerSessionCallback(); if (sscb != null) run_after_sending_success = sscb.requestShell(server_session); if (wantReply) { if (run_after_sending_success != null) { tm.sendAsynchronousMessage(new PacketChannelSuccess(c.remoteID).getPayload()); } else { tm.sendAsynchronousMessage(new PacketChannelFailure(c.remoteID).getPayload()); } } if (run_after_sending_success != null) { runAsync(run_after_sending_success); } return; } if ((server_session != null) && (type.equals("exec"))) { String command = tr.readString(); if (tr.remain() != 0) throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message"); Runnable run_after_sending_success = null; ServerSessionCallback sscb = server_session.getServerSessionCallback(); if (sscb != null) run_after_sending_success = sscb.requestExec(server_session, command); if (wantReply) { if (run_after_sending_success != null) { tm.sendAsynchronousMessage(new PacketChannelSuccess(c.remoteID).getPayload()); } else { tm.sendAsynchronousMessage(new PacketChannelFailure(c.remoteID).getPayload()); } } if (run_after_sending_success != null) { runAsync(run_after_sending_success); } 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) { tm.sendAsynchronousMessage(new PacketChannelFailure(c.remoteID).getPayload()); } log.debug("Channel request '" + type + "' is not known, ignoring it"); }
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(); log.debug("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(); } log.debug("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(); } log.debug("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); } log.debug("Channel request '" + type + "' is not known, ignoring it"); }