/** @throws IOException */ protected void startBinaryPacketProtocol() throws IOException { // Send our Kex Init sendKeyExchangeInit(); SshMessage msg; // Perform a transport protocol message loop while (state.getValue() != TransportProtocolState.DISCONNECTED) { // Process incoming messages returning any transport protocol // messages to be handled here msg = processMessages(); if (log.isDebugEnabled()) { log.debug("Received " + msg.getMessageName()); } switch (msg.getMessageId()) { case SshMsgKexInit.SSH_MSG_KEX_INIT: { onMsgKexInit((SshMsgKexInit) msg); break; } case SshMsgDisconnect.SSH_MSG_DISCONNECT: { onMsgDisconnect((SshMsgDisconnect) msg); break; } case SshMsgIgnore.SSH_MSG_IGNORE: { onMsgIgnore((SshMsgIgnore) msg); break; } case SshMsgUnimplemented.SSH_MSG_UNIMPLEMENTED: { onMsgUnimplemented((SshMsgUnimplemented) msg); break; } case SshMsgDebug.SSH_MSG_DEBUG: { onMsgDebug((SshMsgDebug) msg); break; } default: onMessageReceived(msg); } } }
/** * @param msg * @param sender * @throws IOException * @throws TransportProtocolException */ public synchronized void sendMessage(SshMessage msg, Object sender) throws IOException { // Send a message, if were in key exchange then add it to // the list unless of course it is a transport protocol or key // exchange message if (log.isDebugEnabled()) { log.info("Sending " + msg.getMessageName()); } int currentState = state.getValue(); if (sender instanceof SshKeyExchange || sender instanceof TransportProtocolCommon || (currentState == TransportProtocolState.CONNECTED)) { sshOut.sendMessage(msg); if (currentState == TransportProtocolState.CONNECTED) { if (sendIgnore) { byte[] count = new byte[1]; ConfigurationLoader.getRND().nextBytes(count); byte[] rand = new byte[(count[0] & 0xFF) + 1]; ConfigurationLoader.getRND().nextBytes(rand); SshMsgIgnore ignore = new SshMsgIgnore(new String(rand)); if (log.isDebugEnabled()) { log.debug("Sending " + ignore.getMessageName()); } sshOut.sendMessage(ignore); } } } else if (currentState == TransportProtocolState.PERFORMING_KEYEXCHANGE) { log.debug("Adding to message queue whilst in key exchange"); synchronized (messageStack) { // Add this message to the end of the list messageStack.add(msg); } } else { throw new TransportProtocolException("The transport protocol is disconnected"); } }
/** * @return * @throws IOException */ protected SshMessage processMessages() throws IOException { byte[] msgdata = null; SshMessage msg; SshMessageStore ms; while (state.getValue() != TransportProtocolState.DISCONNECTED) { long currentTime = System.currentTimeMillis(); transferredKB = sshIn.getNumBytesTransfered() / 1024 + sshOut.getNumBytesTransfered() / 1024; long kbLimit = transferredKB - lastTriggeredKB; if (((currentTime - startTime) > kexTimeout) || (kbLimit > kexTransferLimitKB)) { // ((sshIn.getNumBytesTransfered() + // sshOut.getNumBytesTransfered()) > kexTransferLimit)) { startTime = currentTime; lastTriggeredKB = transferredKB; if (log.isDebugEnabled()) { log.info("rekey"); } sendKeyExchangeInit(); } boolean hasmsg = false; while (!hasmsg) { try { msgdata = sshIn.readMessage(); hasmsg = true; } catch (InterruptedIOException ex /*SocketTimeoutException ex*/) { log.info("Possible timeout on transport inputstream"); Iterator it = eventHandlers.iterator(); TransportProtocolEventHandler eventHandler; while (it.hasNext()) { eventHandler = (TransportProtocolEventHandler) it.next(); eventHandler.onSocketTimeout(this /*, provider.isConnected()*/); } } } Integer messageId = SshMessage.getMessageId(msgdata); if (!messageStore.isRegisteredMessage(messageId)) { try { ms = getMessageStore(messageId); msg = ms.createMessage(msgdata); if (log.isDebugEnabled()) { log.info("Received " + msg.getMessageName()); } ms.addMessage(msg); } catch (MessageNotRegisteredException mnre) { log.info("Unimplemented message received " + String.valueOf(messageId.intValue())); msg = new SshMsgUnimplemented(sshIn.getSequenceNo()); sendMessage(msg, this); } } else { return messageStore.createMessage(msgdata); } } throw new IOException("The transport protocol has disconnected"); }
/** * @param filter * @return * @throws IOException */ public SshMessage readMessage(int[] filter) throws IOException { byte[] msgdata = null; SshMessage msg; while (state.getValue() != TransportProtocolState.DISCONNECTED) { boolean hasmsg = false; while (!hasmsg) { msgdata = sshIn.readMessage(); hasmsg = true; } Integer messageId = SshMessage.getMessageId(msgdata); // First check the filter for (int i = 0; i < filter.length; i++) { if (filter[i] == messageId.intValue()) { if (messageStore.isRegisteredMessage(messageId)) { return messageStore.createMessage(msgdata); } else { SshMessageStore ms = getMessageStore(messageId); msg = ms.createMessage(msgdata); if (log.isDebugEnabled()) { log.debug("Processing " + msg.getMessageName()); } return msg; } } } if (messageStore.isRegisteredMessage(messageId)) { msg = messageStore.createMessage(msgdata); switch (messageId.intValue()) { case SshMsgDisconnect.SSH_MSG_DISCONNECT: { onMsgDisconnect((SshMsgDisconnect) msg); break; } case SshMsgIgnore.SSH_MSG_IGNORE: { onMsgIgnore((SshMsgIgnore) msg); break; } case SshMsgUnimplemented.SSH_MSG_UNIMPLEMENTED: { onMsgUnimplemented((SshMsgUnimplemented) msg); break; } case SshMsgDebug.SSH_MSG_DEBUG: { onMsgDebug((SshMsgDebug) msg); break; } default: // Exception not allowed throw new IOException("Unexpected transport protocol message"); } } else { throw new IOException("Unexpected message received"); } } throw new IOException("The transport protocol disconnected"); }