⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssh2transport.java

📁 一个非常好的ssh客户端实现
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
	    }	    if (!equals) {		disconnectInternal(SSH2.DISCONNECT_CONNECTION_LOST,				   "Server host key changed", "", false);	    }	}    }    private void transportTransmitLoop() {	isTxUp = true;	tpLog.debug("SSH2Transport", "transportTransmitLoop",		    "starting");	try {	    SSH2TransportPDU pdu;	    while((pdu = (SSH2TransportPDU)txQueue.getFirst()) != null) {		if(DEBUG_ALL_TX) tpLog.debug2("SSH2Transport",					      "transportTransmitLoop",					      "sending message of type: " +					      SSH2.msgTypeString(pdu.pktType),					      pdu.getData(),					      pdu.getPayloadOffset(),					      pdu.getPayloadLength());		txNumPacketsSinceKEX++;		txNumBytesSinceKEX += pdu.getPayloadLength();		// Note, we don't use transmitInternal since we don't want to		// loop over the exception handler here		//		pdu.writeTo(tpOut, txSeqNum++, txContext, tpRand);		activity = true;		// Initiate rekey if needed		if (txNumPacketsSinceKEX >= PACKETS_BEFORE_REKEY		    || txNumBytesSinceKEX >= BYTES_BEFORE_REKEY) {		    startKeyExchange();		}	    }	} catch (ShortBufferException e) {	    String msg = "Internal error/bug: " + e.getMessage();	    tpLog.error("SSH2Transport", "transportTransmitLoop", msg);	    disconnectInternal(SSH2.DISCONNECT_CONNECTION_LOST, msg,			       /* !!! TODO: languageTag, from ourPrefs? */ "",			       false);	} catch (IOException e) {	    String msg = "I/O error: " + e.getMessage();	    if(isTxUp) {		tpLog.error("SSH2Transport", "transportTransmitLoop", msg);	    }	    disconnectInternal(SSH2.DISCONNECT_CONNECTION_LOST, msg,			       /* !!! TODO: languageTag, from ourPrefs? */ "",			       false);	} catch (SSH2CompressionException e) {	    String msg = "Internal error/bug: " + e.getMessage();	    tpLog.error("SSH2Transport", "transportTransmitLoop", msg);	    disconnectInternal(SSH2.DISCONNECT_COMPRESSION_ERROR, msg,			       /* !!! TODO: languageTag, from ourPrefs? */ "",			       false);	} catch (SSH2Exception e) {	    String msg = "Key reexchange failed: " + e.getMessage();	    tpLog.error("SSH2Transport", "transportTransmitLoop", msg);	    disconnectInternal(SSH2.DISCONNECT_COMPRESSION_ERROR, msg,			       /* !!! TODO: languageTag, from ourPrefs? */ "",			       false);	} finally {	    shutdownTx();	    kexComplete(false);	    authTerminate();	}	tpLog.debug("SSH2Transport", "transportTransmitLoop",		    "stopping");    }    private void transportReceiveLoop() {	isRxUp = true;	tpLog.debug("SSH2Transport", "transportReceiveLoop", "starting");	try {	    while(isRxUp) {		processRxPacket(receiveInternal());	    }	} catch (ShortBufferException e) {	    String msg = "Internal error/bug: " + e.getMessage();	    disconnectInternal(SSH2.DISCONNECT_CONNECTION_LOST, msg,			       /* !!! TODO: languageTag, from ourPrefs? */ "",			       false);	} catch (SSH2MacCheckException e) {	    String msg = e.getMessage();	    disconnectInternal(SSH2.DISCONNECT_MAC_ERROR, msg,			       /* !!! TODO: languageTag, from ourPrefs? */ "",			       false);	} catch (SSH2CompressionException e) {	    String msg = e.getMessage();	    disconnectInternal(SSH2.DISCONNECT_COMPRESSION_ERROR, msg,			       /* !!! TODO: languageTag, from ourPrefs? */ "",			       false);	} catch (SSH2SignatureException e) {	    String msg = e.getMessage();	    disconnectInternal(SSH2.DISCONNECT_KEY_EXCHANGE_FAILED, msg,			       /* !!! TODO: languageTag, from ourPrefs? */ "",			       false);	} catch (SSH2Exception e) {	    if(isRxUp) {		String msg = e.getMessage();		if(e.getRootCause() != null) {		    msg += " (rootcause: " + e.getRootCause() + ")";		}		disconnectInternal(SSH2.DISCONNECT_PROTOCOL_ERROR, msg,				   /* !!! TODO: languageTag, from ourPrefs? */ "",				   false);	    }	} catch (IOException e) {	    if(isRxUp) {		String msg = "I/O error: " + e.getMessage();		disconnectInternal(SSH2.DISCONNECT_CONNECTION_LOST, msg,				   /* !!! TODO: languageTag, from ourPrefs? */ "",				   false);	    }	} finally {	    shutdownRx();	    kexComplete(false);	    authTerminate();	}	tpLog.debug("SSH2Transport", "transportReceiveLoop",		    "stopping");    }    private void processRxPacket(SSH2TransportPDU pdu)	throws ShortBufferException, IOException, SSH2Exception    {	rxNumPacketsSinceKEX++;	rxNumBytesSinceKEX += pdu.getPayloadLength();	switch(pdu.pktType) {	case SSH2.MSG_DISCONNECT: {	    int    reason      = pdu.readInt();	    String description = pdu.readJavaString();	    String languageTag = pdu.readJavaString();	    disconnectInternal(reason, description, languageTag, true);	    break;	}	case SSH2.MSG_IGNORE:	    byte[] data = pdu.readString();	    eventHandler.msgIgnore(this, data);	    break;	case SSH2.MSG_UNIMPLEMENTED:	    int rejectedSeqNum = pdu.readInt();	    eventHandler.msgUnimplemented(this, rejectedSeqNum);	    break;	case SSH2.MSG_DEBUG: {	    boolean alwaysDisplay = pdu.readBoolean();	    String  message       = pdu.readJavaString();	    String  languageTag   = pdu.readJavaString();	    eventHandler.msgDebug(this, alwaysDisplay, message,				  languageTag);	    break;	}	case SSH2.MSG_SERVICE_REQUEST:	    break;	case SSH2.MSG_SERVICE_ACCEPT:	    userAuth.processMessage(pdu);	    pdu = null;	    break;	case SSH2.MSG_KEXINIT:	    processKEXINIT(pdu);	    pdu = null;	    break;	case SSH2.MSG_NEWKEYS:	    if(!keyExchangeInProgress)		throw new SSH2CorruptPacketException(		     "Received MSG_NEWKEYS while not doing key exchange");	    changeKeys(false);	    kexComplete(true);	    break;	case SSH2.FIRST_KEX_PACKET:	case 31:	case 32:	case 33:	case 34:	case 35:	case 36:	case 37:	case 38:	case 39:	case 40:	case 41:	case 42:	case 43:	case 44:	case 45:	case 46:	case 47:	case 48:	case SSH2.LAST_KEX_PACKET:	    if(!keyExchangeInProgress)		throw new SSH2CorruptPacketException(		     "Received KEX packet while not doing key exchange");	    keyExchanger.processKEXMethodPDU(pdu);	    break;	case SSH2.MSG_USERAUTH_REQUEST:	case SSH2.MSG_USERAUTH_FAILURE:	case SSH2.MSG_USERAUTH_SUCCESS:	case SSH2.MSG_USERAUTH_BANNER:	case SSH2.FIRST_USERAUTH_METHOD_PACKET:	case 61:	case 62:	case 63:	case 64:	case 65:	case 66:	case 67:	case 68:	case 69:	case 70:	case 71:	case 72:	case 73:	case 74:	case 75:	case 76:	case 77:	case 78:	case SSH2.LAST_USERAUTH_METHOD_PACKET:	    userAuth.processMessage(pdu);	    pdu = null;	    break;	case SSH2.MSG_GLOBAL_REQUEST:	case SSH2.MSG_REQUEST_SUCCESS:	case SSH2.MSG_REQUEST_FAILURE:	case SSH2.MSG_CHANNEL_OPEN:	    connection.processGlobalMessage(pdu);	    pdu = null;	    break;	case SSH2.MSG_CHANNEL_DATA:	case SSH2.MSG_CHANNEL_EXTENDED_DATA:	case SSH2.MSG_CHANNEL_OPEN_CONFIRMATION:	case SSH2.MSG_CHANNEL_OPEN_FAILURE:	case SSH2.MSG_CHANNEL_WINDOW_ADJUST:	case SSH2.MSG_CHANNEL_EOF:	case SSH2.MSG_CHANNEL_CLOSE:	case SSH2.MSG_CHANNEL_REQUEST:	case SSH2.MSG_CHANNEL_SUCCESS:	case SSH2.MSG_CHANNEL_FAILURE:	    connection.processChannelMessage(pdu);	    pdu = null;	    break;	default:	    tpLog.warning("SSH2Transport",			  "received packet of unknown type: " + pdu.pktType);	    SSH2TransportPDU pduUnimp =		SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_UNIMPLEMENTED);	    pduUnimp.writeInt(rxSeqNum);	    if(keyExchangeInProgress) {		transmitInternal(pduUnimp);	    } else {		transmit(pduUnimp);	    }	    eventHandler.peerSentUnknownMessage(this, pdu.pktType);	    break;	}	if(pdu != null) {	    pdu.release();	}	// Initiate rekey if needed	if (rxNumPacketsSinceKEX >= PACKETS_BEFORE_REKEY	    || rxNumBytesSinceKEX >= BYTES_BEFORE_REKEY) {	    startKeyExchange();	}    }    /**     * Receives a PDU directly from the <code>InputStream</code> from the peer     * without checking if we are connected. This method can only be used when     * the receiver is not running.     *     * @return the PDU which was read     *     * @exception SSH2Exception     * @exception ShortBufferException     * @exception IOException     */    public SSH2TransportPDU receiveInternal()	throws SSH2Exception, ShortBufferException, IOException    {	SSH2TransportPDU pdu = SSH2TransportPDU.createIncomingPacket();	pdu.readFrom(tpIn, rxSeqNum++, rxContext);	activity = true;	if(DEBUG_ALL_RX) tpLog.debug2("SSH2Transport",				      "receiveInternal",				      "received message of type: " +				      SSH2.msgTypeString(pdu.pktType),				      pdu.getData(),				      pdu.getPayloadOffset(),				      pdu.getPayloadLength());	return pdu;    }    private void shutdownTx() {	if(isTxUp) {	    isTxUp = false;	    try { tpOut.close(); } catch (IOException e) { /* don't care */ }	    txQueue.disable();	    txQueue.setBlocking(false);	}    }    private void shutdownRx() {	if(isRxUp) {	    isRxUp = false;	    try { tpIn.close(); } catch (IOException e) { /* don't care */ }	}    }    private synchronized void changeKeys(boolean transmitter)	throws SSH2Exception    {	try {	    String cipherName = ourPrefs.getAgreedCipher(transmitter,							 weAreAServer);	    String macName    = ourPrefs.getAgreedMac(transmitter,						      weAreAServer);	    String compName   = ourPrefs.getAgreedCompression(transmitter,							      weAreAServer);	    int    cKeyLen    = ourPrefs.getCipherKeyLen(cipherName);	    int    mKeyLen    = ourPrefs.getMacKeyLen(macName);	    tpLog.info("SSH2Transport", "new " +		       (transmitter ? "transmitter" : "receiver") +		       " context (" + cipherName + "," + macName + "," +		       compName + ")");	    cipherName = ourPrefs.ssh2ToJCECipher(cipherName);	    macName    = ourPrefs.ssh2ToJCEMac(macName);	    TranceiverContext ctx =		SSH2TransportPDU.createTranceiverContext(cipherName,							 macName,							 compName);	    initTranceiverContext(ctx, cKeyLen,				  (incompatibleHMACKeyLength ? 16 : mKeyLen),				  transmitter);	    if(transmitter) {		txContext = ctx;	    } else {		rxContext = ctx;	    }	} catch (Exception e) {	    throw new SSH2FatalException("Error in changeKeys", e);	}    }    private void initTranceiverContext(TranceiverContext context, int ckLen,				       int mkLen, boolean transmitter)	throws SSH2Exception    {	byte[] iv, cKey, mKey;	char[] ids;	if(weAreAServer ^ transmitter) {	    ids = new char[] { 'A', 'C', 'E' };	} else {	    ids = new char[] { 'B', 'D', 'F' };	}	iv   = deriveKey(ids[0], context.getCipherBlockSize());	cKey = deriveKey(ids[1], ckLen);	mKey = deriveKey(ids[2], mkLen);	int compressionLevel = 6;	try {	    compressionLevel =		Integer.parseInt(ourPrefs.getPreference(SSH2Preferences.							COMP_LEVEL));	} catch (Exception e) {	    compressionLevel = 6;	}	context.init(cKey, iv, mKey, compressionLevel, transmitter);    }    byte[] deriveKey(char id, int len) {	byte[] key = new byte[len];	byte[] sharedSecret_K = keyExchanger.getSharedSecret_K();	byte[] exchangeHash_H = keyExchanger.getExchangeHash_H();	if(sessionId == null) {	    sessionId = new byte[exchangeHash_H.length];	    System.arraycopy(exchangeHash_H, 0, sessionId, 0,			     sessionId.length);	}	MessageDigest sha1 = keyExchanger.getExchangeHashAlgorithm();	sha1.update(sharedSecret_K);	sha1.update(exchangeHash_H);	sha1.update(new byte[] { (byte)id });	sha1.update(sessionId);	byte[] material = sha1.digest();	int curLen = material.length;	System.arraycopy(material, 0, key, 0, (curLen < len ? curLen : len));	while(curLen < len) {	    sha1.reset();	    sha1.update(sharedSecret_K);	    sha1.update(exchangeHash_H);	    sha1.update(key, 0, curLen);	    material = sha1.digest();	    if(len - curLen > material.length)		System.arraycopy(material, 0, key, curLen, material.length);	    else		System.arraycopy(material, 0, key, curLen, len - curLen);	    curLen += material.length;	}	tpLog.debug2("SSH2Transport", "deriveKey", "key id " + id, key);	return key;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -