From dd5f3966e37c54a9f2720ec30ea4f56aad74b872 Mon Sep 17 00:00:00 2001 From: Tim Endres Date: Mon, 29 Jul 2019 15:42:40 +0300 Subject: [PATCH] Commit version 5.4.2 sources --- build.xml | 174 +- pom.xml | 22 +- site/relnotes/Release 5.3.3 Notes.txt | 149 + site/relnotes/Release 5.3.4 Notes.txt | 151 + site/relnotes/Release 5.4.1 Notes.txt | 163 + site/relnotes/Release 5.4.2 Notes.txt | 152 + .../java/com/ice/cvsc/CVSArgumentVector.java | 6 +- src/main/java/com/ice/cvsc/CVSBufferedUI.java | 61 + src/main/java/com/ice/cvsc/CVSCUtilities.java | 6 +- src/main/java/com/ice/cvsc/CVSClient.java | 420 +- src/main/java/com/ice/cvsc/CVSEntry.java | 71 +- .../java/com/ice/cvsc/CVSEntryVector.java | 6 +- .../java/com/ice/cvsc/CVSFileException.java | 6 +- src/main/java/com/ice/cvsc/CVSIgnore.java | 6 +- src/main/java/com/ice/cvsc/CVSLog.java | 4 +- src/main/java/com/ice/cvsc/CVSMode.java | 6 +- src/main/java/com/ice/cvsc/CVSNotifyItem.java | 6 +- src/main/java/com/ice/cvsc/CVSNullUI.java | 43 + src/main/java/com/ice/cvsc/CVSProject.java | 17 +- src/main/java/com/ice/cvsc/CVSProjectDef.java | 23 +- src/main/java/com/ice/cvsc/CVSRequest.java | 21 +- .../java/com/ice/cvsc/CVSRespItemVector.java | 6 +- src/main/java/com/ice/cvsc/CVSResponse.java | 11 +- .../java/com/ice/cvsc/CVSResponseHandler.java | 6 +- .../java/com/ice/cvsc/CVSResponseItem.java | 9 +- src/main/java/com/ice/cvsc/CVSScramble.java | 6 +- src/main/java/com/ice/cvsc/CVSTimestamp.java | 6 +- .../java/com/ice/cvsc/CVSTimestampFormat.java | 6 +- src/main/java/com/ice/cvsc/CVSTracer.java | 6 +- .../java/com/ice/cvsc/CVSUserInterface.java | 6 +- src/main/java/com/ice/cvsc/package.html | 2 +- src/main/java/com/ice/jcvsii/Config.java | 6 +- .../java/com/ice/jcvsii/ConfigConstants.java | 2 +- src/main/java/com/ice/jcvsii/JCVS.java | 28 +- .../java/com/ice/jcvsii/ProjectFrame.java | 6 +- src/main/java/com/ice/viewer/HexViewer.java | 24 +- .../isnetworks/ssh/AbstractFileBrowser.java | 72 - .../java/com/isnetworks/ssh/FileBrowser.java | 89 - .../java/com/isnetworks/ssh/FileDisplay.java | 316 - .../java/com/isnetworks/ssh/FileList.java | 142 - .../java/com/isnetworks/ssh/FileListItem.java | 148 - .../com/isnetworks/ssh/LocalFileBrowser.java | 181 - .../java/com/isnetworks/ssh/SSHException.java | 59 - .../com/mindbright/application/MindTerm.java | 820 --- .../mindbright/application/MindTermLite.java | 534 -- .../com/mindbright/application/MindVNC.java | 15 - .../application/ModuleActiveSync.java | 111 - .../mindbright/application/ModulePortFwd.java | 220 - .../application/ModuleTerminal.java | 102 - .../com/mindbright/application/SSH2Test.java | 299 - .../mindbright/application/SSH2Tunneling.java | 578 -- src/main/java/com/mindbright/asn1/ASN1.java | 61 - .../com/mindbright/asn1/ASN1BitString.java | 75 - .../java/com/mindbright/asn1/ASN1Boolean.java | 50 - .../java/com/mindbright/asn1/ASN1DER.java | 308 - .../java/com/mindbright/asn1/ASN1Decoder.java | 32 - .../java/com/mindbright/asn1/ASN1Encoder.java | 31 - .../com/mindbright/asn1/ASN1Explicit.java | 25 - .../com/mindbright/asn1/ASN1IA5String.java | 24 - .../com/mindbright/asn1/ASN1Implicit.java | 43 - .../java/com/mindbright/asn1/ASN1Integer.java | 55 - .../java/com/mindbright/asn1/ASN1Null.java | 40 - .../java/com/mindbright/asn1/ASN1OID.java | 77 - .../java/com/mindbright/asn1/ASN1Object.java | 41 - .../com/mindbright/asn1/ASN1OctetString.java | 24 - .../com/mindbright/asn1/ASN1Sequence.java | 24 - .../com/mindbright/asn1/ASN1SequenceOf.java | 25 - .../java/com/mindbright/asn1/ASN1Set.java | 24 - .../java/com/mindbright/asn1/ASN1SetOf.java | 25 - .../java/com/mindbright/asn1/ASN1String.java | 50 - .../com/mindbright/asn1/ASN1Structure.java | 89 - .../com/mindbright/gui/AWTConvenience.java | 135 - .../mindbright/gui/AWTGridBagContainer.java | 50 - src/main/java/com/mindbright/gui/Logo.java | 60 - .../java/com/mindbright/gui/ProgressBar.java | 105 - .../jca/security/AlgorithmParameters.java | 69 - .../jca/security/AlgorithmParametersSpi.java | 49 - .../jca/security/DigestException.java | 26 - .../security/GeneralSecurityException.java | 26 - .../InvalidAlgorithmParameterException.java | 24 - .../jca/security/InvalidKeyException.java | 26 - .../security/InvalidParameterException.java | 28 - .../java/com/mindbright/jca/security/Key.java | 22 - .../mindbright/jca/security/KeyException.java | 26 - .../mindbright/jca/security/KeyFactory.java | 86 - .../jca/security/KeyFactorySpi.java | 38 - .../com/mindbright/jca/security/KeyPair.java | 36 - .../jca/security/KeyPairGenerator.java | 103 - .../jca/security/KeyPairGeneratorSpi.java | 39 - .../jca/security/MessageDigest.java | 119 - .../jca/security/MessageDigestSpi.java | 54 - .../security/NoSuchAlgorithmException.java | 26 - .../jca/security/NoSuchProviderException.java | 26 - .../mindbright/jca/security/PrivateKey.java | 19 - .../com/mindbright/jca/security/Provider.java | 84 - .../jca/security/ProviderLookup.java | 96 - .../mindbright/jca/security/PublicKey.java | 19 - .../mindbright/jca/security/SecureRandom.java | 109 - .../jca/security/SecureRandomSpi.java | 31 - .../com/mindbright/jca/security/Security.java | 86 - .../mindbright/jca/security/Signature.java | 236 - .../jca/security/SignatureException.java | 26 - .../mindbright/jca/security/SignatureSpi.java | 81 - .../UnsupportedOperationException.java | 26 - .../jca/security/interfaces/DSAKey.java | 20 - .../interfaces/DSAKeyPairGenerator.java | 26 - .../jca/security/interfaces/DSAParams.java | 24 - .../security/interfaces/DSAPrivateKey.java | 24 - .../jca/security/interfaces/DSAPublicKey.java | 24 - .../jca/security/interfaces/RSAKey.java | 22 - .../security/interfaces/RSAPrivateCrtKey.java | 29 - .../security/interfaces/RSAPrivateKey.java | 24 - .../jca/security/interfaces/RSAPublicKey.java | 24 - .../security/spec/AlgorithmParameterSpec.java | 19 - .../jca/security/spec/DSAParameterSpec.java | 29 - .../jca/security/spec/DSAParamsImpl.java | 46 - .../jca/security/spec/DSAPrivateKeySpec.java | 35 - .../jca/security/spec/DSAPublicKeySpec.java | 35 - .../spec/InvalidKeySpecException.java | 30 - .../spec/InvalidParameterSpecException.java | 30 - .../mindbright/jca/security/spec/KeySpec.java | 19 - .../jca/security/spec/RSAKeyImpl.java | 32 - .../security/spec/RSAPrivateCrtKeySpec.java | 70 - .../jca/security/spec/RSAPrivateKeySpec.java | 33 - .../jca/security/spec/RSAPublicKeySpec.java | 33 - .../java/com/mindbright/net/HttpHeader.java | 209 - .../mindbright/net/ProxyAuthenticator.java | 23 - .../java/com/mindbright/net/RFC822Head.java | 133 - .../com/mindbright/net/SocksProxySocket.java | 281 - .../com/mindbright/net/WebProxyException.java | 28 - .../mindbright/net/WebProxyTunnelSocket.java | 144 - .../com/mindbright/net/ftp/FTPException.java | 31 - .../com/mindbright/net/ftp/FTPServer.java | 558 -- .../net/ftp/FTPServerEventHandler.java | 48 - .../com/mindbright/security/Mindbright.java | 119 - .../mindbright/security/cipher/ArcFour.java | 106 - .../security/cipher/BlockCipher.java | 294 - .../mindbright/security/cipher/Blowfish.java | 462 -- .../mindbright/security/cipher/CAST128.java | 653 -- .../com/mindbright/security/cipher/DES.java | 533 -- .../com/mindbright/security/cipher/DES3.java | 149 - .../com/mindbright/security/cipher/IDEA.java | 189 - .../com/mindbright/security/cipher/RC2.java | 236 - .../mindbright/security/cipher/Rijndael.java | 473 -- .../mindbright/security/cipher/Twofish.java | 583 -- .../com/mindbright/security/digest/MD2.java | 204 - .../com/mindbright/security/digest/MD5.java | 205 - .../security/digest/MD512BitBlock.java | 99 - .../mindbright/security/digest/RIPEMD160.java | 259 - .../com/mindbright/security/digest/SHA1.java | 177 - .../com/mindbright/security/mac/HMAC.java | 164 - .../com/mindbright/security/mac/HMACMD5.java | 22 - .../mindbright/security/mac/HMACMD5_96.java | 23 - .../security/mac/HMACRIPEMD160.java | 22 - .../security/mac/HMACRIPEMD160_96.java | 23 - .../com/mindbright/security/mac/HMACSHA1.java | 22 - .../mindbright/security/mac/HMACSHA1_96.java | 23 - .../security/prng/BlumBlumShub.java | 195 - .../security/publickey/BaseSignature.java | 131 - .../mindbright/security/publickey/DHKey.java | 48 - .../security/publickey/DHKeyAgreement.java | 102 - .../security/publickey/DHKeyFactory.java | 67 - .../publickey/DHKeyPairGenerator.java | 72 - .../security/publickey/DHPrivateKey.java | 33 - .../security/publickey/DHPublicKey.java | 33 - .../security/publickey/DSAAlgorithm.java | 118 - .../mindbright/security/publickey/DSAKey.java | 47 - .../security/publickey/DSAKeyFactory.java | 67 - .../publickey/DSAKeyPairGenerator.java | 103 - .../security/publickey/DSAPrivateKey.java | 35 - .../security/publickey/DSAPublicKey.java | 35 - .../security/publickey/DSAWithSHA1.java | 67 - .../security/publickey/DiffieHellman.java | 97 - .../security/publickey/ModPGroups.java | 56 - .../security/publickey/RSAAlgorithm.java | 208 - .../mindbright/security/publickey/RSAKey.java | 47 - .../security/publickey/RSAKeyFactory.java | 82 - .../publickey/RSAKeyPairGenerator.java | 54 - .../security/publickey/RSAPrivateCrtKey.java | 85 - .../security/publickey/RSAPrivateKey.java | 36 - .../security/publickey/RSAPublicKey.java | 34 - .../security/publickey/RSAWithAny.java | 180 - .../security/publickey/RSAWithMD2.java | 24 - .../security/publickey/RSAWithMD5.java | 24 - .../security/publickey/RSAWithRIPEMD160.java | 24 - .../security/publickey/RSAWithSHA1.java | 24 - src/main/java/com/mindbright/ssh/SSH.java | 510 -- .../ssh/SSHAccessDeniedException.java | 26 - .../com/mindbright/ssh/SSHAuthenticator.java | 32 - .../java/com/mindbright/ssh/SSHBlowfish.java | 92 - .../java/com/mindbright/ssh/SSHChannel.java | 70 - .../mindbright/ssh/SSHChannelController.java | 431 -- .../mindbright/ssh/SSHChannelListener.java | 25 - .../mindbright/ssh/SSHChannelMulticaster.java | 28 - .../java/com/mindbright/ssh/SSHCipher.java | 67 - .../java/com/mindbright/ssh/SSHClient.java | 1236 ---- .../com/mindbright/ssh/SSHClientUser.java | 35 - .../mindbright/ssh/SSHClientUserAdaptor.java | 82 - .../ssh/SSHCompressionException.java | 28 - .../com/mindbright/ssh/SSHCompressor.java | 50 - .../com/mindbright/ssh/SSHCompressorZLib.java | 122 - .../com/mindbright/ssh/SSHConnectChannel.java | 171 - .../java/com/mindbright/ssh/SSHConsole.java | 32 - .../com/mindbright/ssh/SSHConsoleClient.java | 179 - src/main/java/com/mindbright/ssh/SSHDES.java | 75 - src/main/java/com/mindbright/ssh/SSHDES3.java | 46 - .../mindbright/ssh/SSHDataInputStream.java | 51 - .../mindbright/ssh/SSHDataOutputStream.java | 42 - .../mindbright/ssh/SSHFtpListenChannel.java | 34 - .../java/com/mindbright/ssh/SSHFtpPlugin.java | 45 - .../java/com/mindbright/ssh/SSHFtpTunnel.java | 194 - src/main/java/com/mindbright/ssh/SSHIDEA.java | 63 - .../mindbright/ssh/SSHInteractiveClient.java | 1009 --- .../com/mindbright/ssh/SSHInteractor.java | 41 - .../mindbright/ssh/SSHInteractorAdapter.java | 62 - .../ssh/SSHKeyGenerationDialog.java | 617 -- .../com/mindbright/ssh/SSHListenChannel.java | 141 - .../com/mindbright/ssh/SSHMenuHandler.java | 52 - .../mindbright/ssh/SSHMenuHandlerFull.java | 1808 ------ .../com/mindbright/ssh/SSHMiscDialogs.java | 333 - .../java/com/mindbright/ssh/SSHNoEncrypt.java | 31 - .../ssh/SSHPasswordAuthenticator.java | 75 - src/main/java/com/mindbright/ssh/SSHPdu.java | 33 - .../com/mindbright/ssh/SSHPduInputStream.java | 195 - .../mindbright/ssh/SSHPduOutputStream.java | 191 - .../mindbright/ssh/SSHPropertyHandler.java | 1664 ----- .../com/mindbright/ssh/SSHProtocolPlugin.java | 66 - .../com/mindbright/ssh/SSHProxyDialog.java | 217 - .../mindbright/ssh/SSHRSAAuthenticator.java | 78 - .../com/mindbright/ssh/SSHRSAKeyFile.java | 173 - .../mindbright/ssh/SSHRSAPublicKeyFile.java | 166 - .../mindbright/ssh/SSHRSAPublicKeyString.java | 74 - .../ssh/SSHRemoteFileBrowsingConsole.java | 264 - .../java/com/mindbright/ssh/SSHRxChannel.java | 55 - .../java/com/mindbright/ssh/SSHSCPClient.java | 42 - .../java/com/mindbright/ssh/SSHSCPDialog.java | 372 -- .../com/mindbright/ssh/SSHSCPGUIThread.java | 386 -- .../java/com/mindbright/ssh/SSHServer.java | 487 -- .../com/mindbright/ssh/SSHServerSocket.java | 92 - .../java/com/mindbright/ssh/SSHSocket.java | 34 - .../com/mindbright/ssh/SSHSocketFactory.java | 195 - .../com/mindbright/ssh/SSHSocketImpl.java | 163 - .../com/mindbright/ssh/SSHSocketTunnel.java | 262 - .../java/com/mindbright/ssh/SSHStdIO.java | 280 - .../java/com/mindbright/ssh/SSHTunnel.java | 215 - .../com/mindbright/ssh/SSHTunnelDialog.java | 251 - .../java/com/mindbright/ssh/SSHTxChannel.java | 65 - .../mindbright/ssh/SSHVersionSpySocket.java | 139 - src/main/java/com/mindbright/ssh/Version.java | 24 - src/main/java/com/mindbright/ssh2/SSH2.java | 295 - .../ssh2/SSH2AccessDeniedException.java | 22 - .../mindbright/ssh2/SSH2AuthKbdInteract.java | 99 - .../com/mindbright/ssh2/SSH2AuthModule.java | 84 - .../com/mindbright/ssh2/SSH2AuthPassword.java | 118 - .../mindbright/ssh2/SSH2AuthPublicKey.java | 123 - .../mindbright/ssh2/SSH2Authenticator.java | 219 - .../java/com/mindbright/ssh2/SSH2Channel.java | 297 - .../ssh2/SSH2CompressionException.java | 24 - .../com/mindbright/ssh2/SSH2Compressor.java | 56 - .../mindbright/ssh2/SSH2CompressorZLib.java | 116 - .../mindbright/ssh2/SSH2ConnectException.java | 25 - .../com/mindbright/ssh2/SSH2Connection.java | 852 --- .../ssh2/SSH2ConnectionEventAdapter.java | 83 - .../ssh2/SSH2ConnectionEventHandler.java | 204 - .../ssh2/SSH2ConnectionPreferences.java | 186 - .../com/mindbright/ssh2/SSH2Connector.java | 277 - .../mindbright/ssh2/SSH2ConsoleRemote.java | 127 - .../ssh2/SSH2CorruptPacketException.java | 24 - .../java/com/mindbright/ssh2/SSH2DSS.java | 83 - .../com/mindbright/ssh2/SSH2DataBuffer.java | 214 - .../com/mindbright/ssh2/SSH2EOFException.java | 24 - .../com/mindbright/ssh2/SSH2Exception.java | 36 - .../com/mindbright/ssh2/SSH2FTPOverSFTP.java | 315 - .../mindbright/ssh2/SSH2FTPProxyFilter.java | 254 - .../mindbright/ssh2/SSH2FatalException.java | 28 - .../com/mindbright/ssh2/SSH2Interactor.java | 33 - .../mindbright/ssh2/SSH2KEXDHGroup1SHA1.java | 205 - .../mindbright/ssh2/SSH2KEXDHGroupXSHA1.java | 161 - .../ssh2/SSH2KEXFailedException.java | 25 - .../com/mindbright/ssh2/SSH2KeyExchanger.java | 70 - .../com/mindbright/ssh2/SSH2KeyPairFile.java | 820 --- .../com/mindbright/ssh2/SSH2ListUtil.java | 150 - .../com/mindbright/ssh2/SSH2Listener.java | 289 - .../ssh2/SSH2MacCheckException.java | 24 - .../com/mindbright/ssh2/SSH2PKISigner.java | 31 - .../mindbright/ssh2/SSH2PublicKeyFile.java | 231 - .../java/com/mindbright/ssh2/SSH2RSA.java | 77 - .../ssh2/SSH2RetryingTCPChannel.java | 79 - .../com/mindbright/ssh2/SSH2SCP1Client.java | 37 - .../java/com/mindbright/ssh2/SSH2SFTP.java | 476 -- .../com/mindbright/ssh2/SSH2SFTPClient.java | 822 --- .../mindbright/ssh2/SSH2SFTPFileBrowser.java | 154 - .../com/mindbright/ssh2/SSH2SFTPTransfer.java | 222 - .../mindbright/ssh2/SSH2SessionChannel.java | 416 -- .../com/mindbright/ssh2/SSH2Signature.java | 177 - .../ssh2/SSH2SignatureException.java | 25 - .../com/mindbright/ssh2/SSH2SimpleClient.java | 122 - .../mindbright/ssh2/SSH2SimpleSFTPShell.java | 564 -- .../mindbright/ssh2/SSH2SimpleSignature.java | 98 - .../mindbright/ssh2/SSH2StreamChannel.java | 259 - .../com/mindbright/ssh2/SSH2StreamFilter.java | 24 - .../ssh2/SSH2StreamFilterAdapter.java | 29 - .../ssh2/SSH2StreamFilterFactory.java | 22 - .../mindbright/ssh2/SSH2StreamSniffer.java | 89 - .../com/mindbright/ssh2/SSH2TCPChannel.java | 106 - .../mindbright/ssh2/SSH2TerminalAdapter.java | 21 - .../ssh2/SSH2TerminalAdapterImpl.java | 85 - .../com/mindbright/ssh2/SSH2Transport.java | 1601 ----- .../ssh2/SSH2TransportEventAdapter.java | 68 - .../ssh2/SSH2TransportEventHandler.java | 173 - .../com/mindbright/ssh2/SSH2TransportPDU.java | 267 - .../mindbright/ssh2/SSH2TransportPDUPool.java | 107 - .../ssh2/SSH2TransportPreferences.java | 450 -- .../com/mindbright/ssh2/SSH2UserAuth.java | 319 - .../ssh2/SSH2UserCancelException.java | 24 - .../com/mindbright/ssh2/SSH2X11Filter.java | 187 - .../java/com/mindbright/ssh2/package.html | 18 - .../sshcommon/SSHConsoleRemote.java | 28 - .../mindbright/sshcommon/SSHFileTransfer.java | 29 - .../sshcommon/SSHFileTransferProgress.java | 25 - .../com/mindbright/sshcommon/SSHSCP1.java | 377 -- .../sshcommon/SSHSCPStdoutProgress.java | 32 - .../mindbright/terminal/GlobalClipboard.java | 149 - .../terminal/LineReaderTerminal.java | 191 - .../com/mindbright/terminal/Terminal.java | 137 - .../mindbright/terminal/TerminalCapture.java | 61 - .../terminal/TerminalClipboardHandler.java | 22 - .../mindbright/terminal/TerminalDefProps.java | 180 - .../com/mindbright/terminal/TerminalDumb.java | 47 - .../terminal/TerminalInputAdapter.java | 30 - .../terminal/TerminalInputListener.java | 23 - .../terminal/TerminalInterpreter.java | 40 - .../terminal/TerminalMenuHandler.java | 31 - .../terminal/TerminalMenuHandlerFull.java | 1042 ---- .../terminal/TerminalMenuListener.java | 21 - .../terminal/TerminalOutputListener.java | 22 - .../com/mindbright/terminal/TerminalWin.java | 3108 ---------- .../mindbright/terminal/TerminalXTerm.java | 5431 ----------------- .../java/com/mindbright/util/ASCIIArmour.java | 350 -- src/main/java/com/mindbright/util/Base64.java | 129 - src/main/java/com/mindbright/util/CRC32.java | 87 - .../mindbright/util/EncryptedProperties.java | 188 - .../java/com/mindbright/util/HexDump.java | 130 - .../com/mindbright/util/InputStreamPipe.java | 286 - src/main/java/com/mindbright/util/Log.java | 94 - src/main/java/com/mindbright/util/Math.java | 137 - .../com/mindbright/util/OutputStreamPipe.java | 60 - .../java/com/mindbright/util/PrimeSieve.java | 102 - .../java/com/mindbright/util/Progress.java | 20 - src/main/java/com/mindbright/util/Queue.java | 167 - .../java/com/mindbright/util/RandomSeed.java | 423 -- .../com/mindbright/util/SKEYDictionary.java | 389 -- .../mindbright/util/SecureRandomAndPad.java | 87 - .../java/com/mindbright/util/StringUtil.java | 36 - src/main/java/javax/crypto/Cipher.java | 187 - src/main/java/javax/crypto/CipherSpi.java | 76 - src/main/java/javax/crypto/KeyAgreement.java | 122 - .../java/javax/crypto/KeyAgreementSpi.java | 53 - src/main/java/javax/crypto/Mac.java | 161 - src/main/java/javax/crypto/MacSpi.java | 49 - src/main/java/javax/crypto/SecretKey.java | 21 - .../javax/crypto/ShortBufferException.java | 24 - .../java/javax/crypto/interfaces/DHKey.java | 22 - .../javax/crypto/interfaces/DHPrivateKey.java | 24 - .../javax/crypto/interfaces/DHPublicKey.java | 24 - .../javax/crypto/spec/DHGenParameterSpec.java | 38 - .../javax/crypto/spec/DHParameterSpec.java | 40 - .../java/javax/crypto/spec/DHParamsImpl.java | 39 - .../javax/crypto/spec/DHPrivateKeySpec.java | 35 - .../javax/crypto/spec/DHPublicKeySpec.java | 35 - .../javax/crypto/spec/IvParameterSpec.java | 37 - .../java/javax/crypto/spec/SecretKeySpec.java | 56 - .../security/ForbiddenTargetException.java | 7 - .../netscape/security/PrivilegeManager.java | 9 - src/main/resources/META-INF/MANIFEST.MF | 11 +- .../com/ice/jcvsii/defaults.properties | 6 +- 376 files changed, 1138 insertions(+), 58798 deletions(-) create mode 100644 site/relnotes/Release 5.3.3 Notes.txt create mode 100644 site/relnotes/Release 5.3.4 Notes.txt create mode 100644 site/relnotes/Release 5.4.1 Notes.txt create mode 100644 site/relnotes/Release 5.4.2 Notes.txt create mode 100644 src/main/java/com/ice/cvsc/CVSBufferedUI.java create mode 100644 src/main/java/com/ice/cvsc/CVSNullUI.java delete mode 100644 src/main/java/com/isnetworks/ssh/AbstractFileBrowser.java delete mode 100644 src/main/java/com/isnetworks/ssh/FileBrowser.java delete mode 100644 src/main/java/com/isnetworks/ssh/FileDisplay.java delete mode 100644 src/main/java/com/isnetworks/ssh/FileList.java delete mode 100644 src/main/java/com/isnetworks/ssh/FileListItem.java delete mode 100644 src/main/java/com/isnetworks/ssh/LocalFileBrowser.java delete mode 100644 src/main/java/com/isnetworks/ssh/SSHException.java delete mode 100644 src/main/java/com/mindbright/application/MindTerm.java delete mode 100644 src/main/java/com/mindbright/application/MindTermLite.java delete mode 100644 src/main/java/com/mindbright/application/MindVNC.java delete mode 100644 src/main/java/com/mindbright/application/ModuleActiveSync.java delete mode 100644 src/main/java/com/mindbright/application/ModulePortFwd.java delete mode 100644 src/main/java/com/mindbright/application/ModuleTerminal.java delete mode 100644 src/main/java/com/mindbright/application/SSH2Test.java delete mode 100644 src/main/java/com/mindbright/application/SSH2Tunneling.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1BitString.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1Boolean.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1DER.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1Decoder.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1Encoder.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1Explicit.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1IA5String.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1Implicit.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1Integer.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1Null.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1OID.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1Object.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1OctetString.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1Sequence.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1SequenceOf.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1Set.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1SetOf.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1String.java delete mode 100644 src/main/java/com/mindbright/asn1/ASN1Structure.java delete mode 100644 src/main/java/com/mindbright/gui/AWTConvenience.java delete mode 100644 src/main/java/com/mindbright/gui/AWTGridBagContainer.java delete mode 100644 src/main/java/com/mindbright/gui/Logo.java delete mode 100644 src/main/java/com/mindbright/gui/ProgressBar.java delete mode 100644 src/main/java/com/mindbright/jca/security/AlgorithmParameters.java delete mode 100644 src/main/java/com/mindbright/jca/security/AlgorithmParametersSpi.java delete mode 100644 src/main/java/com/mindbright/jca/security/DigestException.java delete mode 100644 src/main/java/com/mindbright/jca/security/GeneralSecurityException.java delete mode 100644 src/main/java/com/mindbright/jca/security/InvalidAlgorithmParameterException.java delete mode 100644 src/main/java/com/mindbright/jca/security/InvalidKeyException.java delete mode 100644 src/main/java/com/mindbright/jca/security/InvalidParameterException.java delete mode 100644 src/main/java/com/mindbright/jca/security/Key.java delete mode 100644 src/main/java/com/mindbright/jca/security/KeyException.java delete mode 100644 src/main/java/com/mindbright/jca/security/KeyFactory.java delete mode 100644 src/main/java/com/mindbright/jca/security/KeyFactorySpi.java delete mode 100644 src/main/java/com/mindbright/jca/security/KeyPair.java delete mode 100644 src/main/java/com/mindbright/jca/security/KeyPairGenerator.java delete mode 100644 src/main/java/com/mindbright/jca/security/KeyPairGeneratorSpi.java delete mode 100644 src/main/java/com/mindbright/jca/security/MessageDigest.java delete mode 100644 src/main/java/com/mindbright/jca/security/MessageDigestSpi.java delete mode 100644 src/main/java/com/mindbright/jca/security/NoSuchAlgorithmException.java delete mode 100644 src/main/java/com/mindbright/jca/security/NoSuchProviderException.java delete mode 100644 src/main/java/com/mindbright/jca/security/PrivateKey.java delete mode 100644 src/main/java/com/mindbright/jca/security/Provider.java delete mode 100644 src/main/java/com/mindbright/jca/security/ProviderLookup.java delete mode 100644 src/main/java/com/mindbright/jca/security/PublicKey.java delete mode 100644 src/main/java/com/mindbright/jca/security/SecureRandom.java delete mode 100644 src/main/java/com/mindbright/jca/security/SecureRandomSpi.java delete mode 100644 src/main/java/com/mindbright/jca/security/Security.java delete mode 100644 src/main/java/com/mindbright/jca/security/Signature.java delete mode 100644 src/main/java/com/mindbright/jca/security/SignatureException.java delete mode 100644 src/main/java/com/mindbright/jca/security/SignatureSpi.java delete mode 100644 src/main/java/com/mindbright/jca/security/UnsupportedOperationException.java delete mode 100644 src/main/java/com/mindbright/jca/security/interfaces/DSAKey.java delete mode 100644 src/main/java/com/mindbright/jca/security/interfaces/DSAKeyPairGenerator.java delete mode 100644 src/main/java/com/mindbright/jca/security/interfaces/DSAParams.java delete mode 100644 src/main/java/com/mindbright/jca/security/interfaces/DSAPrivateKey.java delete mode 100644 src/main/java/com/mindbright/jca/security/interfaces/DSAPublicKey.java delete mode 100644 src/main/java/com/mindbright/jca/security/interfaces/RSAKey.java delete mode 100644 src/main/java/com/mindbright/jca/security/interfaces/RSAPrivateCrtKey.java delete mode 100644 src/main/java/com/mindbright/jca/security/interfaces/RSAPrivateKey.java delete mode 100644 src/main/java/com/mindbright/jca/security/interfaces/RSAPublicKey.java delete mode 100644 src/main/java/com/mindbright/jca/security/spec/AlgorithmParameterSpec.java delete mode 100644 src/main/java/com/mindbright/jca/security/spec/DSAParameterSpec.java delete mode 100644 src/main/java/com/mindbright/jca/security/spec/DSAParamsImpl.java delete mode 100644 src/main/java/com/mindbright/jca/security/spec/DSAPrivateKeySpec.java delete mode 100644 src/main/java/com/mindbright/jca/security/spec/DSAPublicKeySpec.java delete mode 100644 src/main/java/com/mindbright/jca/security/spec/InvalidKeySpecException.java delete mode 100644 src/main/java/com/mindbright/jca/security/spec/InvalidParameterSpecException.java delete mode 100644 src/main/java/com/mindbright/jca/security/spec/KeySpec.java delete mode 100644 src/main/java/com/mindbright/jca/security/spec/RSAKeyImpl.java delete mode 100644 src/main/java/com/mindbright/jca/security/spec/RSAPrivateCrtKeySpec.java delete mode 100644 src/main/java/com/mindbright/jca/security/spec/RSAPrivateKeySpec.java delete mode 100644 src/main/java/com/mindbright/jca/security/spec/RSAPublicKeySpec.java delete mode 100644 src/main/java/com/mindbright/net/HttpHeader.java delete mode 100644 src/main/java/com/mindbright/net/ProxyAuthenticator.java delete mode 100644 src/main/java/com/mindbright/net/RFC822Head.java delete mode 100644 src/main/java/com/mindbright/net/SocksProxySocket.java delete mode 100644 src/main/java/com/mindbright/net/WebProxyException.java delete mode 100644 src/main/java/com/mindbright/net/WebProxyTunnelSocket.java delete mode 100644 src/main/java/com/mindbright/net/ftp/FTPException.java delete mode 100644 src/main/java/com/mindbright/net/ftp/FTPServer.java delete mode 100644 src/main/java/com/mindbright/net/ftp/FTPServerEventHandler.java delete mode 100644 src/main/java/com/mindbright/security/Mindbright.java delete mode 100644 src/main/java/com/mindbright/security/cipher/ArcFour.java delete mode 100644 src/main/java/com/mindbright/security/cipher/BlockCipher.java delete mode 100644 src/main/java/com/mindbright/security/cipher/Blowfish.java delete mode 100644 src/main/java/com/mindbright/security/cipher/CAST128.java delete mode 100644 src/main/java/com/mindbright/security/cipher/DES.java delete mode 100644 src/main/java/com/mindbright/security/cipher/DES3.java delete mode 100644 src/main/java/com/mindbright/security/cipher/IDEA.java delete mode 100644 src/main/java/com/mindbright/security/cipher/RC2.java delete mode 100644 src/main/java/com/mindbright/security/cipher/Rijndael.java delete mode 100644 src/main/java/com/mindbright/security/cipher/Twofish.java delete mode 100644 src/main/java/com/mindbright/security/digest/MD2.java delete mode 100644 src/main/java/com/mindbright/security/digest/MD5.java delete mode 100644 src/main/java/com/mindbright/security/digest/MD512BitBlock.java delete mode 100644 src/main/java/com/mindbright/security/digest/RIPEMD160.java delete mode 100644 src/main/java/com/mindbright/security/digest/SHA1.java delete mode 100644 src/main/java/com/mindbright/security/mac/HMAC.java delete mode 100644 src/main/java/com/mindbright/security/mac/HMACMD5.java delete mode 100644 src/main/java/com/mindbright/security/mac/HMACMD5_96.java delete mode 100644 src/main/java/com/mindbright/security/mac/HMACRIPEMD160.java delete mode 100644 src/main/java/com/mindbright/security/mac/HMACRIPEMD160_96.java delete mode 100644 src/main/java/com/mindbright/security/mac/HMACSHA1.java delete mode 100644 src/main/java/com/mindbright/security/mac/HMACSHA1_96.java delete mode 100644 src/main/java/com/mindbright/security/prng/BlumBlumShub.java delete mode 100644 src/main/java/com/mindbright/security/publickey/BaseSignature.java delete mode 100644 src/main/java/com/mindbright/security/publickey/DHKey.java delete mode 100644 src/main/java/com/mindbright/security/publickey/DHKeyAgreement.java delete mode 100644 src/main/java/com/mindbright/security/publickey/DHKeyFactory.java delete mode 100644 src/main/java/com/mindbright/security/publickey/DHKeyPairGenerator.java delete mode 100644 src/main/java/com/mindbright/security/publickey/DHPrivateKey.java delete mode 100644 src/main/java/com/mindbright/security/publickey/DHPublicKey.java delete mode 100644 src/main/java/com/mindbright/security/publickey/DSAAlgorithm.java delete mode 100644 src/main/java/com/mindbright/security/publickey/DSAKey.java delete mode 100644 src/main/java/com/mindbright/security/publickey/DSAKeyFactory.java delete mode 100644 src/main/java/com/mindbright/security/publickey/DSAKeyPairGenerator.java delete mode 100644 src/main/java/com/mindbright/security/publickey/DSAPrivateKey.java delete mode 100644 src/main/java/com/mindbright/security/publickey/DSAPublicKey.java delete mode 100644 src/main/java/com/mindbright/security/publickey/DSAWithSHA1.java delete mode 100644 src/main/java/com/mindbright/security/publickey/DiffieHellman.java delete mode 100644 src/main/java/com/mindbright/security/publickey/ModPGroups.java delete mode 100644 src/main/java/com/mindbright/security/publickey/RSAAlgorithm.java delete mode 100644 src/main/java/com/mindbright/security/publickey/RSAKey.java delete mode 100644 src/main/java/com/mindbright/security/publickey/RSAKeyFactory.java delete mode 100644 src/main/java/com/mindbright/security/publickey/RSAKeyPairGenerator.java delete mode 100644 src/main/java/com/mindbright/security/publickey/RSAPrivateCrtKey.java delete mode 100644 src/main/java/com/mindbright/security/publickey/RSAPrivateKey.java delete mode 100644 src/main/java/com/mindbright/security/publickey/RSAPublicKey.java delete mode 100644 src/main/java/com/mindbright/security/publickey/RSAWithAny.java delete mode 100644 src/main/java/com/mindbright/security/publickey/RSAWithMD2.java delete mode 100644 src/main/java/com/mindbright/security/publickey/RSAWithMD5.java delete mode 100644 src/main/java/com/mindbright/security/publickey/RSAWithRIPEMD160.java delete mode 100644 src/main/java/com/mindbright/security/publickey/RSAWithSHA1.java delete mode 100644 src/main/java/com/mindbright/ssh/SSH.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHAccessDeniedException.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHAuthenticator.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHBlowfish.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHChannel.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHChannelController.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHChannelListener.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHChannelMulticaster.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHCipher.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHClient.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHClientUser.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHClientUserAdaptor.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHCompressionException.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHCompressor.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHCompressorZLib.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHConnectChannel.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHConsole.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHConsoleClient.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHDES.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHDES3.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHDataInputStream.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHDataOutputStream.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHFtpListenChannel.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHFtpPlugin.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHFtpTunnel.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHIDEA.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHInteractiveClient.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHInteractor.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHInteractorAdapter.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHKeyGenerationDialog.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHListenChannel.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHMenuHandler.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHMenuHandlerFull.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHMiscDialogs.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHNoEncrypt.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHPasswordAuthenticator.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHPdu.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHPduInputStream.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHPduOutputStream.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHPropertyHandler.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHProtocolPlugin.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHProxyDialog.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHRSAAuthenticator.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHRSAKeyFile.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHRSAPublicKeyFile.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHRSAPublicKeyString.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHRemoteFileBrowsingConsole.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHRxChannel.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHSCPClient.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHSCPDialog.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHSCPGUIThread.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHServer.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHServerSocket.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHSocket.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHSocketFactory.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHSocketImpl.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHSocketTunnel.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHStdIO.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHTunnel.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHTunnelDialog.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHTxChannel.java delete mode 100644 src/main/java/com/mindbright/ssh/SSHVersionSpySocket.java delete mode 100644 src/main/java/com/mindbright/ssh/Version.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2AccessDeniedException.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2AuthKbdInteract.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2AuthModule.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2AuthPassword.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2AuthPublicKey.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2Authenticator.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2Channel.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2CompressionException.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2Compressor.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2CompressorZLib.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2ConnectException.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2Connection.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2ConnectionEventAdapter.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2ConnectionEventHandler.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2ConnectionPreferences.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2Connector.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2ConsoleRemote.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2CorruptPacketException.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2DSS.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2DataBuffer.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2EOFException.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2Exception.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2FTPOverSFTP.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2FTPProxyFilter.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2FatalException.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2Interactor.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2KEXDHGroup1SHA1.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2KEXDHGroupXSHA1.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2KEXFailedException.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2KeyExchanger.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2KeyPairFile.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2ListUtil.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2Listener.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2MacCheckException.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2PKISigner.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2PublicKeyFile.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2RSA.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2RetryingTCPChannel.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2SCP1Client.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2SFTP.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2SFTPClient.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2SFTPFileBrowser.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2SFTPTransfer.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2SessionChannel.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2Signature.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2SignatureException.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2SimpleClient.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2SimpleSFTPShell.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2SimpleSignature.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2StreamChannel.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2StreamFilter.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2StreamFilterAdapter.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2StreamFilterFactory.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2StreamSniffer.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2TCPChannel.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2TerminalAdapter.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2TerminalAdapterImpl.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2Transport.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2TransportEventAdapter.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2TransportEventHandler.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2TransportPDU.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2TransportPDUPool.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2TransportPreferences.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2UserAuth.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2UserCancelException.java delete mode 100644 src/main/java/com/mindbright/ssh2/SSH2X11Filter.java delete mode 100644 src/main/java/com/mindbright/ssh2/package.html delete mode 100644 src/main/java/com/mindbright/sshcommon/SSHConsoleRemote.java delete mode 100644 src/main/java/com/mindbright/sshcommon/SSHFileTransfer.java delete mode 100644 src/main/java/com/mindbright/sshcommon/SSHFileTransferProgress.java delete mode 100644 src/main/java/com/mindbright/sshcommon/SSHSCP1.java delete mode 100644 src/main/java/com/mindbright/sshcommon/SSHSCPStdoutProgress.java delete mode 100644 src/main/java/com/mindbright/terminal/GlobalClipboard.java delete mode 100644 src/main/java/com/mindbright/terminal/LineReaderTerminal.java delete mode 100644 src/main/java/com/mindbright/terminal/Terminal.java delete mode 100644 src/main/java/com/mindbright/terminal/TerminalCapture.java delete mode 100644 src/main/java/com/mindbright/terminal/TerminalClipboardHandler.java delete mode 100644 src/main/java/com/mindbright/terminal/TerminalDefProps.java delete mode 100644 src/main/java/com/mindbright/terminal/TerminalDumb.java delete mode 100644 src/main/java/com/mindbright/terminal/TerminalInputAdapter.java delete mode 100644 src/main/java/com/mindbright/terminal/TerminalInputListener.java delete mode 100644 src/main/java/com/mindbright/terminal/TerminalInterpreter.java delete mode 100644 src/main/java/com/mindbright/terminal/TerminalMenuHandler.java delete mode 100644 src/main/java/com/mindbright/terminal/TerminalMenuHandlerFull.java delete mode 100644 src/main/java/com/mindbright/terminal/TerminalMenuListener.java delete mode 100644 src/main/java/com/mindbright/terminal/TerminalOutputListener.java delete mode 100644 src/main/java/com/mindbright/terminal/TerminalWin.java delete mode 100644 src/main/java/com/mindbright/terminal/TerminalXTerm.java delete mode 100644 src/main/java/com/mindbright/util/ASCIIArmour.java delete mode 100644 src/main/java/com/mindbright/util/Base64.java delete mode 100644 src/main/java/com/mindbright/util/CRC32.java delete mode 100644 src/main/java/com/mindbright/util/EncryptedProperties.java delete mode 100644 src/main/java/com/mindbright/util/HexDump.java delete mode 100644 src/main/java/com/mindbright/util/InputStreamPipe.java delete mode 100644 src/main/java/com/mindbright/util/Log.java delete mode 100644 src/main/java/com/mindbright/util/Math.java delete mode 100644 src/main/java/com/mindbright/util/OutputStreamPipe.java delete mode 100644 src/main/java/com/mindbright/util/PrimeSieve.java delete mode 100644 src/main/java/com/mindbright/util/Progress.java delete mode 100644 src/main/java/com/mindbright/util/Queue.java delete mode 100644 src/main/java/com/mindbright/util/RandomSeed.java delete mode 100644 src/main/java/com/mindbright/util/SKEYDictionary.java delete mode 100644 src/main/java/com/mindbright/util/SecureRandomAndPad.java delete mode 100644 src/main/java/com/mindbright/util/StringUtil.java delete mode 100644 src/main/java/javax/crypto/Cipher.java delete mode 100644 src/main/java/javax/crypto/CipherSpi.java delete mode 100644 src/main/java/javax/crypto/KeyAgreement.java delete mode 100644 src/main/java/javax/crypto/KeyAgreementSpi.java delete mode 100644 src/main/java/javax/crypto/Mac.java delete mode 100644 src/main/java/javax/crypto/MacSpi.java delete mode 100644 src/main/java/javax/crypto/SecretKey.java delete mode 100644 src/main/java/javax/crypto/ShortBufferException.java delete mode 100644 src/main/java/javax/crypto/interfaces/DHKey.java delete mode 100644 src/main/java/javax/crypto/interfaces/DHPrivateKey.java delete mode 100644 src/main/java/javax/crypto/interfaces/DHPublicKey.java delete mode 100644 src/main/java/javax/crypto/spec/DHGenParameterSpec.java delete mode 100644 src/main/java/javax/crypto/spec/DHParameterSpec.java delete mode 100644 src/main/java/javax/crypto/spec/DHParamsImpl.java delete mode 100644 src/main/java/javax/crypto/spec/DHPrivateKeySpec.java delete mode 100644 src/main/java/javax/crypto/spec/DHPublicKeySpec.java delete mode 100644 src/main/java/javax/crypto/spec/IvParameterSpec.java delete mode 100644 src/main/java/javax/crypto/spec/SecretKeySpec.java delete mode 100644 src/main/java/netscape/security/ForbiddenTargetException.java delete mode 100644 src/main/java/netscape/security/PrivilegeManager.java diff --git a/build.xml b/build.xml index 9c60992..ee30fb7 100644 --- a/build.xml +++ b/build.xml @@ -1,12 +1,15 @@ + + + @@ -50,7 +53,8 @@ ** --> - + + - + + + - - - - - - - - - - - - - - - - - - - - + + @@ -134,7 +124,9 @@ - + + + @@ -162,12 +154,13 @@ version="true" use="true" windowtitle="jCVS II" - bottom="<i>Copyright © 1997-2002, Timothy G. Endres, All Rights Reserved.</i>" + bottom="<i>Copyright © 1997-2003, Timothy G. Endres, All Rights Reserved.</i>" > + @@ -178,11 +171,12 @@ - + + @@ -190,84 +184,32 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - + - - - - - - - - - - - + + + + "); - mUploadButton.addActionListener(new Actions(true)); - } - return mUploadButton; - } - - public void refresh() { - try { - netscape.security.PrivilegeManager.enablePrivilege("UniversalFileAccess"); - } catch (netscape.security.ForbiddenTargetException e) { - // !!! - } - try { - mRemoteFileBrowser.refresh(); - mLocalFileBrowser.refresh(); - } catch( SSHException e ) { - logError(e); - } - } - - /** - * Initialize the connection to the remote system and - * start in the SSH home directory on the local system - */ - public void show() { - try { - netscape.security.PrivilegeManager.enablePrivilege("UniversalFileAccess"); - netscape.security.PrivilegeManager.enablePrivilege("TerminalEmulator"); - } catch (netscape.security.ForbiddenTargetException e) { - // !!! - } - setSize(600, 500); - try { - mRemoteFileBrowser.initialize(); - mLocalFileBrowser.initialize(); - } catch(SSHException e) { - logError(e); - } - super.show(); - } - - /** - * An exception happened, so show the user the message in the text area - */ - public void logError( Exception e ) { - mMessageTextArea.append( e.getMessage() + "\n" ); - } - - public static void showSCP(String title, Frame p, - SSHInteractiveClient client) - { - SSHSCPDialog dialog = new SSHSCPDialog(title, p, client); - - SSHConsoleRemote remote = null; - - if(client.isSSH2) { - remote = new SSH2ConsoleRemote(client.connection, null); - } else { - try { - remote = - new SSHConsoleClient(client.propsHandler.getSrvHost(), - client.propsHandler.getSrvPort(), - client.propsHandler, null); - ((SSHConsoleClient)remote).setClientUser(client.propsHandler); - } catch (IOException e) { - client.alert("Error creating scp dialog: " + e.getMessage()); - } - } - - dialog.setLocalFileBrowser(new - LocalFileBrowser(dialog.getLocalFileDisplay(), - client.getPropertyHandler())); - - dialog.setRemoteFileBrowser(new - SSHRemoteFileBrowsingConsole(dialog.getRemoteFileDisplay(), - client.getPropertyHandler(), - dialog, - remote)); - - dialog.show(); - } - - public static void showSFTP(String title, Frame p, - SSHInteractiveClient client) - { - if(!client.isSSH2) { - client.alert("SFTP can only be used with ssh2 currently"); - return; - } - - SSHSCPDialog dialog = new SSHSCPDialog(title, p, client); - - dialog.isSFTP = true; - - dialog.setLocalFileBrowser(new - LocalFileBrowser(dialog.getLocalFileDisplay(), - client.getPropertyHandler())); - - dialog.setRemoteFileBrowser(new - SSH2SFTPFileBrowser(client.connection, - dialog.getRemoteFileDisplay())); - - dialog.show(); - } - -} diff --git a/src/main/java/com/mindbright/ssh/SSHSCPGUIThread.java b/src/main/java/com/mindbright/ssh/SSHSCPGUIThread.java deleted file mode 100644 index 49c70be..0000000 --- a/src/main/java/com/mindbright/ssh/SSHSCPGUIThread.java +++ /dev/null @@ -1,386 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh; - -import java.awt.*; -import java.awt.event.*; -import java.io.File; -import java.io.OutputStream; -import java.io.IOException; - -import com.mindbright.gui.ProgressBar; -import com.mindbright.gui.AWTConvenience; -import com.mindbright.gui.AWTGridBagContainer; - -import com.mindbright.sshcommon.SSHFileTransfer; -import com.mindbright.sshcommon.SSHFileTransferProgress; - -import com.mindbright.ssh2.SSH2SCP1Client; -import com.mindbright.ssh2.SSH2SFTPTransfer; - -public final class SSHSCPGUIThread extends Thread - implements SSHFileTransferProgress -{ - String curDir, localFile, remoteFile; - String remoteHost; - int remotePort; - boolean recursive, background, toRemote; - Frame parent; - SSHSCPDialog browseDialog; - - SSHInteractiveClient client; - - String[] localFileList; - String[] remoteFileList; - - Dialog copyIndicator; - ProgressBar progress; - SSHFileTransfer fileXfer; - Thread copyThread; - Label srcLbl, dstLbl, sizeLbl, nameLbl, speedLbl; - Button cancB; - long startTime; - long lastTime; - long totTransSize; - long fileTransSize; - long curFileSize; - long lastSize; - int fileCnt; - boolean doneCopying; - - public SSHSCPGUIThread(SSHInteractiveClient client, - Frame parent, - String curDir, - String[] localFileList, String[] remoteFileList, - boolean recursive, boolean background, - boolean toRemote, SSHSCPDialog browseDialog) - throws Exception - { - try { - netscape.security.PrivilegeManager.enablePrivilege("UniversalFileAccess"); - } catch (netscape.security.ForbiddenTargetException e) { - // !!! - } - - this.localFileList = localFileList; - this.remoteFileList = remoteFileList; - - if(!toRemote) { - if(localFileList.length > 1) { - throw new Exception("Ambiguos local target"); - } - } else { - if(remoteFileList.length > 1) { - throw new Exception("Ambiguos remote target"); - } - } - localFile = localFileList[0]; - remoteFile = remoteFileList[0]; - - this.client = client; - this.remoteHost = client.propsHandler.getSrvHost(); - this.remotePort = client.propsHandler.getSrvPort(); - this.curDir = curDir; - this.parent = parent; - this.localFile = localFile; - this.remoteFile = remoteFile; - this.recursive = recursive; - this.background = background; - this.toRemote = toRemote; - this.fileCnt = 0; - this.doneCopying = false; - this.startTime = 0; - this.lastTime = 0; - this.totTransSize = 0; - this.fileTransSize = 0; - this.lastSize = 0; - this.browseDialog = browseDialog; - this.start(); - } - - public void run() { - String sourceFile = "localhost:" + unQuote(localFile); - String destFile = remoteHost + ":" + unQuote(remoteFile); - - if(!toRemote) { - String tmp; - tmp = sourceFile; - sourceFile = destFile; - destFile = tmp; - } - - copyIndicator = new Dialog(parent, "MindTerm - File Transfer", false); - - Label lbl; - Button b; - AWTGridBagContainer grid = new AWTGridBagContainer(copyIndicator); - - lbl = new Label("Source:"); - grid.add(lbl, 0, 1); - - srcLbl = new Label(cutName(sourceFile, 32)); - grid.add(srcLbl, 0, 4); - - lbl = new Label("Destination:"); - grid.add(lbl, 1, 1); - - dstLbl = new Label(cutName(destFile, 32)); - grid.add(dstLbl, 1, 4); - - lbl= new Label("Current:"); - grid.add(lbl, 2, 1); - - nameLbl= new Label("connecting..."); - grid.add(nameLbl, 2, 3); - - sizeLbl= new Label(""); - grid.add(sizeLbl, 2, 1); - - grid.getConstraints().fill = GridBagConstraints.NONE; - grid.getConstraints().anchor = GridBagConstraints.CENTER; - grid.getConstraints().insets = new Insets(4, 12, 4, 4); - - progress = new ProgressBar(512, 160, 20); - grid.add(progress, 3, 3); - - grid.getConstraints().fill = GridBagConstraints.HORIZONTAL; - grid.getConstraints().insets = new Insets(4, 4, 4, 4); - - speedLbl = new Label("0.0 kB/sec", Label.CENTER); - grid.add(speedLbl, 3, GridBagConstraints.REMAINDER); - - cancB = new Button("Cancel"); - cancB.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - if(!doneCopying) { - if(copyThread != null) - copyThread.stop(); - if(fileXfer != null) - fileXfer.abort(); - } - copyIndicator.setVisible(false); - } - }); - - grid.getConstraints().fill = GridBagConstraints.NONE; - grid.getConstraints().ipadx = 2; - grid.getConstraints().ipady = 2; - - grid.add(cancB, 4, GridBagConstraints.REMAINDER); - - AWTConvenience.setBackgroundOfChildren(copyIndicator); - - Dimension d = speedLbl.getSize(); - d.width += d.width * 2; - speedLbl.setSize(d); - sizeLbl.setSize(d); - - copyIndicator.setResizable(true); - copyIndicator.pack(); - AWTConvenience.placeDialog(copyIndicator); - - copyThread = new Thread(new Runnable() { - public void run() { - try { - netscape.security.PrivilegeManager.enablePrivilege("UniversalFileAccess"); - netscape.security.PrivilegeManager.enablePrivilege("TerminalEmulator"); - } catch (netscape.security.ForbiddenTargetException e) { - // !!! - } - - try { - SSHInteractor interactAdapter = new SSHInteractorAdapter() { - public void open(SSHClient client) { - nameLbl.setText("...connected"); - } - public void disconnected(SSHClient client, - boolean graceful) { - fileXfer.abort(); - } - public void alert(String msg) { - client.alert(msg); - } - }; - - if(browseDialog.isSFTP) { - fileXfer = new SSH2SFTPTransfer(new File(curDir), - client.connection); - } else { - if(client.isSSH2) { - OutputStream alertOutput = new OutputStream() { - public void write(int bb) throws IOException { - byte[] buf = new byte[] { (byte)bb }; - write(buf); - } - public void write(byte bb[], int off, int len) - throws IOException { - client.alert("Remote warning/error: " + - new String(bb, off, len)); - } - }; - SSH2SCP1Client scpClient2 = - new SSH2SCP1Client(new File(curDir), - client.connection, - alertOutput, - SSH.DEBUG); - fileXfer = scpClient2.scp1(); - } else { - SSHSCPClient scpClient = - new SSHSCPClient(remoteHost, remotePort, - client.propsHandler, - interactAdapter, - new File(curDir), - SSH.DEBUG); - scpClient.setClientUser(client.propsHandler); - fileXfer = scpClient.scp1(); - } - } - - fileXfer.setProgress(SSHSCPGUIThread.this); - if(toRemote) { - fileXfer.copyToRemote(localFileList, remoteFileList[0], - recursive); - } else { - fileXfer.copyToLocal(localFileList[0], remoteFileList, - recursive); - } - - copyThread.setPriority(Thread.NORM_PRIORITY); - Toolkit.getDefaultToolkit().beep(); - } catch (Exception e) { - client.alert("SCP Error: " + e.getMessage()); - if(SSH.DEBUGMORE) { - System.out.println("SCP Error:"); - e.printStackTrace(); - } - } - nameLbl.setText("Copied " + fileCnt + " file" + (fileCnt != 1 ? "s" : "") + "."); - double kSize = (double)totTransSize / 1024; - sizeLbl.setText(round(kSize) + " kB"); - doneCopying = true; - cancB.setLabel("Done"); - - browseDialog.refresh(); - - AWTConvenience.setKeyListenerOfChildren(copyIndicator, - new AWTConvenience.OKCancelAdapter(cancB, cancB), - null); - - } - }); - - if(background) { - copyThread.setPriority(Thread.MIN_PRIORITY); - } - - copyThread.start(); - - copyIndicator.setVisible(true); - } - - static int addUnique(String[] list, String str, int last) { - int i; - for(i = 0; i < last; i++) - if(list[i].equals(str)) - break; - if(i == last) - list[last++] = str; - return last; - } - - public void startFile(String file, long size) { - double kSize = (double)size / 1024; - sizeLbl.setText(round(kSize) + " kB"); - nameLbl.setText(unQuote(file)); - progress.setMax(size, true); - lastTime = System.currentTimeMillis(); - if(startTime == 0) - startTime = lastTime; - curFileSize = size; - fileTransSize = 0; - fileCnt++; - } - public void startDir(String file) { - if(startTime == 0) - startTime = System.currentTimeMillis(); - if(file.length() > curDir.length()) - file = file.substring(curDir.length()); - if(toRemote) { - srcLbl.setText(cutName("localhost:" + unQuote(file), 32)); - } else { - dstLbl.setText(cutName("localhost:" + unQuote(file), 32)); - } - } - - public void endFile() { - progress.setValue(curFileSize, true); - } - - public void endDir() { - } - - public void progress(int size) { - totTransSize += (long)size; - fileTransSize += (long)size; - if((curFileSize > 0) && - ((((totTransSize - lastSize) * 100) / curFileSize) >= 1)) { - progress.setValue(fileTransSize, !background); - long now = System.currentTimeMillis(); - long elapsed = (now - startTime); - if(elapsed == 0) { - elapsed = 1; - } - int curSpeed = (int)((double)totTransSize / - ((double)elapsed / 1000)); - elapsed = (now - lastTime); - if(elapsed == 0) { - elapsed = 1; - } - curSpeed += (int)((double)(totTransSize - lastSize) / - ((double)elapsed / 1000)); - curSpeed >>>= 1; - curSpeed >>>= 10; - speedLbl.setText(curSpeed + " kB/sec"); - lastSize = totTransSize; - lastTime = now; - } - } - - double round(double val) { - val = val * 10.0; - val = Math.floor(val); - val = val / 10.0; - return val; - } - - String cutName(String name, int len) { - if(name.length() > len) { - len -= 3; - String pre = name.substring(0, len / 2); - String suf = name.substring(name.length() - (len / 2)); - name = pre + "..." + suf; - } - return name; - } - - String unQuote(String str) { - if(str.charAt(0) == '"') { - str = str.substring(1, str.length() - 1); - } - return str; - } - -} diff --git a/src/main/java/com/mindbright/ssh/SSHServer.java b/src/main/java/com/mindbright/ssh/SSHServer.java deleted file mode 100644 index 4c04c8f..0000000 --- a/src/main/java/com/mindbright/ssh/SSHServer.java +++ /dev/null @@ -1,487 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh; - -import java.net.*; -import java.io.*; -import java.math.BigInteger; - -import com.mindbright.jca.security.*; -import com.mindbright.jca.security.interfaces.*; -import com.mindbright.terminal.*; -import com.mindbright.util.SecureRandomAndPad; - -import com.mindbright.security.publickey.RSAAlgorithm; - -/** - * @author Mats Andersson - * @version 0.96, 12/04/98 - * @see SSHClient - */ -public class SSHServer extends SSH implements Runnable { - - static KeyPair serverKey; - static KeyPair hostKey; - - protected InetAddress localAddr; - - static String authKeysDir = ""; - static String hostKeyFile = "identity"; - static int serverKeyBits = SSH.SERVER_KEY_LENGTH; - - protected String cliVersionStr; - protected int cliVersionMajor; - protected int cliVersionMinor; - - protected Thread myThread; - protected SecureRandomAndPad rand; - - protected Socket sshSocket; - protected BufferedInputStream sshIn; - protected BufferedOutputStream sshOut; - - protected SSHChannelController controller; - - static public void setHostKeyFile(String fileName) { - hostKeyFile = fileName; - } - - static public void setAuthKeysDir(String dirName) { - authKeysDir = dirName; - } - - static public void setServerKeyBits(int bits) { - serverKeyBits = bits; - } - - public InetAddress getLocalAddr() { - return localAddr; - } - - public void setLocalAddr(String addr) throws UnknownHostException { - localAddr = InetAddress.getByName(addr); - } - - public SSHServer(Socket sshSocket, - int protocolFlags, int supportedCiphers, int supportedAuthTypes, - KeyPair srvServerKey, KeyPair srvHostKey) throws IOException { - this.isAnSSHClient = false; - this.sshSocket = sshSocket; - this.sshIn = new BufferedInputStream(sshSocket.getInputStream(), 8192); - this.sshOut = new BufferedOutputStream(sshSocket.getOutputStream()); - - this.protocolFlags = protocolFlags; - this.supportedCiphers = supportedCiphers; - this.supportedAuthTypes = supportedAuthTypes; - this.serverKey = srvServerKey; - this.hostKey = srvHostKey; - this.rand = secureRandom(); - } - - protected void start() { - myThread = new Thread(this); - myThread.start(); - } - - public void run() { - try { - System.out.println("connection from " + sshSocket.getInetAddress().getHostAddress() + " port " + - sshSocket.getPort()); - - negotiateVersion(); - sendServerData(); - receiveSessionKey(); - - // !!! - // At this stage the communication is encrypted - // !!! - - authenticateUser(); - controller = new SSHChannelController(this, sshIn, sshOut, - sndCipher, sndComp, - rcvCipher, rcvComp, - null, true); - receiveOptions(); - - controller.start(); - - try { - controller.waitForExit(); - } catch(InterruptedException e) { - // !!! - log("Error when shutting down SSHClient: " + e.getMessage()); - controller.killAll(); - } - - } catch (IOException e) { - // !!! - log("error in MindTunnel: " + e); - } - } - - static RSAPrivateCrtKey getPrivate(SSHRSAKeyFile keyFile) { - RSAPrivateCrtKey privKey = keyFile.getPrivate(""); - while(privKey == null) { - BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); - System.out.println(""); - System.out.print("key-file '" + keyFile.getComment() + "' password: "); - String passwd; - try { - passwd = br.readLine(); - } catch(IOException e) { - passwd = ""; - } - privKey = keyFile.getPrivate(passwd); - } - return privKey; - } - - public static void sshd(int port) throws IOException { - boolean keepRunning = true; - ServerSocket listenSock = null; - - SSHRSAKeyFile keyFile; - keyFile = new SSHRSAKeyFile(hostKeyFile); - hostKey = new KeyPair(keyFile.getPublic(), getPrivate(keyFile)); - listenSock = new ServerSocket(port); - - int hostKeyBits = ((RSAPublicKey)hostKey.getPublic()).getModulus().bitLength(); - int keyLenDiff = Math.abs(serverKeyBits - hostKeyBits); - if(keyLenDiff < 24) { - throw new IOException("Invalid server keys, difference in sizes must be at least 24 bits"); - } - - System.out.print("generating server-key of length " + serverKeyBits + "..."); - try { - serverKey = generateKeyPair("RSA", serverKeyBits); - } catch (NoSuchAlgorithmException e) { - throw new IOException("Can't generate RSA key: " + e.getMessage()); - } - System.out.println("done"); - - System.out.println("starting new MindTunnel on port " + port + "..."); - - while(keepRunning) { - Socket sshSocket = listenSock.accept(); - SSHServer srv = new SSHServer(sshSocket, PROTOFLAG_HOST_IN_FWD_OPEN, 0xff, 0x0f, - serverKey, hostKey); - - // !!! Change later, must take arguments for localHost - // - srv.localAddr = InetAddress.getLocalHost(); - srv.start(); - } - - } - - void negotiateVersion() throws IOException { - byte[] buf; - int len; - String verStr; - - verStr = getVersionId(false); - verStr += "\n"; - buf = verStr.getBytes(); - - sshOut.write(buf); - sshOut.flush(); - - buf = new byte[256]; - len = sshIn.read(buf); - - cliVersionStr = new String(buf, 0, len); - - try { - int l = cliVersionStr.indexOf('-'); - int r = cliVersionStr.indexOf('.'); - cliVersionMajor = Integer.parseInt(cliVersionStr.substring(l + 1, r)); - l = r; - r = cliVersionStr.indexOf('-', l); - if(r == -1) { - cliVersionMinor = Integer.parseInt(cliVersionStr.substring(l + 1)); - } else { - cliVersionMinor = Integer.parseInt(cliVersionStr.substring(l + 1, r)); - } - } catch (Throwable t) { - throw new IOException("Client version string invalid: " + cliVersionStr); - } - - if(cliVersionMajor > 1) { - throw new IOException("MindTunnel do not support SSHv2 yet, can only serve SSHv1 client"); - } else if(cliVersionMajor < 1 || cliVersionMinor < 5) { - throw new IOException("Client's protocol version (" + cliVersionMajor + "-" + - cliVersionMinor + ") is too old, please upgrade"); - } - - // Strip white-space - cliVersionStr = cliVersionStr.trim(); - } - - void sendServerData() throws IOException { - SSHPduOutputStream pdu = - new SSHPduOutputStream(SMSG_PUBLIC_KEY, null, null, rand); - - srvCookie = new byte[8]; - rand.nextBytes(srvCookie); - generateSessionId(); - - pdu.write(srvCookie); - - RSAPublicKey publ = (RSAPublicKey)serverKey.getPublic(); - int n = publ.getModulus().bitLength(); - pdu.writeInt(n); - pdu.writeBigInteger(publ.getPublicExponent()); - pdu.writeBigInteger(publ.getModulus()); - - publ = (RSAPublicKey)hostKey.getPublic(); - n = publ.getModulus().bitLength(); - pdu.writeInt(n); - pdu.writeBigInteger(publ.getPublicExponent()); - pdu.writeBigInteger(publ.getModulus()); - - pdu.writeInt(protocolFlags); - pdu.writeInt(supportedCiphers); - pdu.writeInt(supportedAuthTypes); - - pdu.writeTo(sshOut); - } - - public static KeyPair generateKeyPair(String alg, int bits) - throws NoSuchAlgorithmException - { - KeyPairGenerator kpg = KeyPairGenerator.getInstance(alg); - kpg.initialize(bits, secureRandom()); - return kpg.generateKeyPair(); - } - - void receiveSessionKey() throws IOException { - SSHPduInputStream inpdu = - new SSHPduInputStream(CMSG_SESSION_KEY, null, null); - inpdu.readFrom(sshIn); - - cipherType = (int)inpdu.readByte(); - if(!isCipherSupported(cipherType)) - //sendDisconnect(); - ; - log("cipher: " + getCipherName(cipherType)); - - byte[] srvCookieCopy = new byte[srvCookie.length]; - inpdu.read(srvCookieCopy); - - BigInteger encKey = inpdu.readBigInteger(); - int cliProtoFlags = inpdu.readInt(); - - RSAPrivateCrtKey key1 = (RSAPrivateCrtKey)serverKey.getPrivate(); - RSAPrivateCrtKey key2 = (RSAPrivateCrtKey)hostKey.getPrivate(); - - if(key2.getModulus().bitLength() > key1.getModulus().bitLength()) { - RSAPrivateCrtKey tmp = key1; - key1 = key2; - key2 = tmp; - } - - try { - encKey = RSAAlgorithm.doPrivateCrt(encKey, - key1.getPrimeP(), - key1.getPrimeQ(), - key1.getPrimeExponentP(), - key1.getPrimeExponentQ(), - key1.getCrtCoefficient()); - encKey = RSAAlgorithm.stripPKCS1Pad(encKey, 2); - encKey = RSAAlgorithm.doPrivateCrt(encKey, - key2.getPrimeP(), - key2.getPrimeQ(), - key2.getPrimeExponentP(), - key2.getPrimeExponentQ(), - key2.getCrtCoefficient()); - encKey = RSAAlgorithm.stripPKCS1Pad(encKey, 2); - sessionKey = encKey.toByteArray(); - } catch (Exception e) { - throw new IOException("Error doing RSA: " + e.getMessage()); - } - - // Must strip if too long, i.e. m.s.b. is 0 because of how BigInteger's toByteArray work... - // - if(sessionKey.length > (SESSION_KEY_LENGTH / 8)) { - byte[] keyCopy = new byte[SESSION_KEY_LENGTH / 8]; - System.arraycopy(sessionKey, 1, keyCopy, 0, SESSION_KEY_LENGTH / 8); - sessionKey = keyCopy; - } - - for(int i = 0; i < sessionId.length; i++) - sessionKey[i] ^= sessionId[i]; - - initServerCipher(); - - // !!! Check that all is ok... - - sendResult(SMSG_SUCCESS); - } - - void authenticateUser() throws IOException { - boolean finished = false; - SSHPduInputStream inpdu = new SSHPduInputStream(CMSG_USER, - rcvCipher, rcvComp); - String user; - - inpdu.readFrom(sshIn); - user = inpdu.readString(); - - log("authenticating: " + user); - sendResult(SMSG_FAILURE); - - while(!finished) { - inpdu = new SSHPduInputStream(MSG_ANY, rcvCipher, rcvComp); - inpdu.readFrom(sshIn); - - switch(inpdu.type) { - case CMSG_AUTH_RSA: - if(doRSAAuth(user, inpdu.readBigInteger())) { - log("rsa-authentication for " + user + " succeeded"); - sendResult(SMSG_SUCCESS); - finished = true; - } else { - log("rsa-authentication for " + user + " failed"); - sendResult(SMSG_FAILURE); - } - break; - case CMSG_AUTH_PASSWORD: - log("trying passwd-auth for: " + user); - sendResult(SMSG_FAILURE); - break; - default: - sendResult(SMSG_FAILURE); - } - } - - } - - boolean doRSAAuth(String userName, BigInteger pubKeyN) throws IOException { - SSHRSAPublicKeyFile keyFile; - SSHPduOutputStream outpdu; - SSHPduInputStream inpdu; - boolean authenticated = false; - - keyFile = SSHRSAPublicKeyFile.loadFromFile(authKeysDir + userName, false); - - RSAPublicKey pubKey = keyFile.getPublic(pubKeyN, userName); - if(pubKey == null) - return false; - - byte[] challenge = new byte[32]; - byte[] tmp; - BigInteger enc; - int keyByteLen = (pubKey.getModulus().bitLength() + 7) / 8; - - rand.nextBytes(challenge); - tmp = new byte[challenge.length + 1]; - System.arraycopy(challenge, 0, tmp, 1, challenge.length); - enc = new BigInteger(tmp); - - try { - enc = RSAAlgorithm.addPKCS1Pad(enc, 2, keyByteLen, rand); - } catch (Exception e) { - throw new IOException("Error when stripping PKCS#1 pad: " + - e.getMessage()); - } - - enc = RSAAlgorithm.doPublic(enc, pubKey.getModulus(), - pubKey.getPublicExponent()); - - outpdu = new SSHPduOutputStream(SMSG_AUTH_RSA_CHALLENGE, - sndCipher, sndComp, rand); - outpdu.writeBigInteger(enc); - outpdu.writeTo(sshOut); - - inpdu = new SSHPduInputStream(CMSG_AUTH_RSA_RESPONSE, rcvCipher, rcvComp); - inpdu.readFrom(sshIn); - tmp = new byte[16]; - inpdu.read(tmp, 0, 16); - - try { - MessageDigest md5 = MessageDigest.getInstance("MD5"); - md5.update(challenge, 0, 32); - md5.update(sessionId); - challenge = md5.digest(); - } catch (Exception e) { - // !!! - System.out.println("!!! MD5 Not supported..."); - throw new IOException(e.getMessage()); - } - - int i; - for(i = 0; i < challenge.length; i++) - if(tmp[i] != challenge[i]) - break; - if(i == challenge.length) - authenticated = true; - - return authenticated; - } - - void receiveOptions() throws IOException { - SSHPduInputStream pdu; - boolean finished = false; - - while(!finished) { - pdu = new SSHPduInputStream(MSG_ANY, rcvCipher, rcvComp); - pdu.readFrom(sshIn); - switch(pdu.type) { - case CMSG_REQUEST_COMPRESSION: - log("compression requested"); - break; - case CMSG_MAX_PACKET_SIZE: - log("mtu requested"); - break; - case CMSG_X11_REQUEST_FORWARDING: - log("x11-tunnel requested"); - sendResult(SMSG_FAILURE); - break; - case CMSG_REQUEST_PTY: - log("pty requested"); - sendResult(SMSG_FAILURE); - break; - case CMSG_PORT_FORWARD_REQUEST: - int localPort = pdu.readInt(); - String remoteHost = pdu.readString(); - int remotePort = pdu.readInt(); - log("port-fwd requested: " + localPort + ":" + remoteHost + ":" + remotePort); - controller.newListenChannel(localAddr.getHostAddress(), localPort, remoteHost, remotePort, "general"); - sendResult(SMSG_SUCCESS); - break; - case CMSG_EXEC_CMD: - String command = pdu.readString(); - log("cmd: " + command); - finished = true; - break; - case CMSG_EXEC_SHELL: - log("exec-shell"); - finished = true; - break; - default: - log("receiveOptions got unknown msg"); - break; - } - } - } - - void sendResult(int type) throws IOException { - SSHPduOutputStream pdu; - pdu = new SSHPduOutputStream(type, sndCipher, sndComp, rand); - pdu.writeTo(sshOut); - } - -} diff --git a/src/main/java/com/mindbright/ssh/SSHServerSocket.java b/src/main/java/com/mindbright/ssh/SSHServerSocket.java deleted file mode 100644 index 8835a23..0000000 --- a/src/main/java/com/mindbright/ssh/SSHServerSocket.java +++ /dev/null @@ -1,92 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh; - -import java.net.*; -import java.io.*; - -public class SSHServerSocket { - // - // !!! Can't extend ServerSocket since it's not intended to be used - // in this way... (i.e. it's only for a "vm-global" switch of - // socket-implementation) - // - // If we extend ServerSocket we waste a local port for each remote - // port we listen to, this is perhaps not too bad, BUT since applets - // can't listen to local sockets we are doomed if we want to use it - // in one... There is not much gain in extension here, I can't think - // of a real case where it would really matter. - // - public static final int DEFAULT_BACKLOG = 25; - - protected SSHSocketFactory factory; - protected SSHSocketImpl impl; - - protected SSHServerSocket(SSHSocketImpl impl) { - this.impl = impl; - } - - protected void finalize() throws IOException { - impl.close(); - } - - protected void setSocketFactory(SSHSocketFactory factory) { - this.factory = factory; - } - - public InetAddress getInetAddress() { - return impl.getInetAddress(); - } - - protected int getLocalPort() { - return impl.getLocalPort(); - } - - public SSHSocket accept() throws IOException { - SSHSocketImpl aImpl = factory.createSocketImpl(impl.client, false); - SSHSocket aSock; - - impl.accept(aImpl); - aSock = new SSHSocket(aImpl); - - return aSock; - } - - public void close() throws IOException { - impl.close(); - } - - public synchronized void setSoTimeout(int timeout) throws SocketException { - impl.setOption(SSHSocketImpl.SO_TIMEOUT, new Integer(timeout)); - } - - public synchronized int getSoTimeout() throws IOException { - Object o = impl.getOption(SSHSocketImpl.SO_TIMEOUT); - /* extra type safety */ - if (o instanceof Integer) { - return ((Integer) o).intValue(); - } else { - return 0; - } - } - - public String toString() { - return "ServerSocket[addr=" + impl.getInetAddress() + - ",port=" + impl.getPort() + - ",localport=" + impl.getLocalPort() + "]"; - } - -} diff --git a/src/main/java/com/mindbright/ssh/SSHSocket.java b/src/main/java/com/mindbright/ssh/SSHSocket.java deleted file mode 100644 index bb98a29..0000000 --- a/src/main/java/com/mindbright/ssh/SSHSocket.java +++ /dev/null @@ -1,34 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh; - -import java.net.*; -import java.io.*; - -public class SSHSocket extends Socket { - - SSHSocketImpl myImpl; - - protected SSHSocket(SocketImpl impl) throws IOException { - super(impl); - myImpl = (SSHSocketImpl)impl; - } - - protected void finalize() throws IOException { - myImpl.close(); - } - -} diff --git a/src/main/java/com/mindbright/ssh/SSHSocketFactory.java b/src/main/java/com/mindbright/ssh/SSHSocketFactory.java deleted file mode 100644 index 94c3036..0000000 --- a/src/main/java/com/mindbright/ssh/SSHSocketFactory.java +++ /dev/null @@ -1,195 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh; - -import java.net.*; -import java.io.*; -import java.util.Hashtable; -import java.util.Enumeration; -import java.util.Vector; - -public class SSHSocketFactory extends SSHClientUserAdaptor { - - public final static int NOLISTENPORT = -1; - - protected SSHAuthenticator authenticator; - protected Hashtable clientCache; - - public SSHSocketFactory(String host, int port, SSHAuthenticator authenticator) { - super(host, port); - this.authenticator = authenticator; - this.clientCache = new Hashtable(); - } - - public SSHSocketFactory(String host, SSHAuthenticator authenticator) { - this(host, SSH.DEFAULTPORT, authenticator); - } - - protected synchronized SSHClient getClient() { - Enumeration e = clientCache.keys(); - if(!e.hasMoreElements()) - return null; - return (SSHClient)e.nextElement(); - } - - protected void finalize() throws IOException { - Enumeration e = clientCache.keys(); - while(e.hasMoreElements()) { - SSHClient client = (SSHClient)e.nextElement(); - client.waitForExit(1000); - } - } - - protected synchronized void addClient(SSHClient client) { - clientCache.put(client, new Vector()); - } - - protected synchronized void registerPseudoUser(SSHClient client, SSHSocketImpl impl) { - Vector users = (Vector)clientCache.get(client); - users.addElement(impl); - } - - protected synchronized void closePseudoAll(SSHClient client) { - Vector users = (Vector)clientCache.get(client); - if(users == null) - return; - SSHSocketImpl u; - while(users.size() > 0) { - u = (SSHSocketImpl)users.elementAt(0); - try { - u.close(); - } catch (IOException e) { - // !!! - } - users.removeElementAt(0); - } - clientCache.remove(client); - } - - protected synchronized void closePseudoUser(SSHClient client, SSHSocketImpl u) { - Vector users = (Vector)clientCache.get(client); - for(int i = 0; i < users.size(); i++) { - if(users.elementAt(i) == u) { - users.removeElementAt(i); - client.delRef(); - break; - } - } - if(users.size() == 0) - clientCache.remove(client); - } - - protected SSHClient createSSHClient(int listenPort) throws IOException { - SSHClient client; - if(listenPort != NOLISTENPORT || ((client = getClient()) == null)) { - client = new SSHClient(authenticator, this); - // !!! This indicates that we are going to use this client to implement a SSHServerSocket - // - if(listenPort != NOLISTENPORT) - client.addRemotePortForward(listenPort, InetAddress.getLocalHost().getHostAddress(), - listenPort, "general"); - client.bootSSH(false); - client.startExitMonitor(); - addClient(client); - } - return client; - } - - protected SSHSocketImpl createSocketImpl(SSHClient client, boolean acceptor) throws IOException { - SSHSocketImpl impl = new SSHSocketImpl(); - - impl.setFactory(this); - try { - impl.create(client, acceptor); - } catch (IOException e) { - impl.close(); - throw e; - } - - registerPseudoUser(client, impl); - return impl; - } - - public SSHSocket createSocket(String address, int port) throws IOException { - SSHSocketImpl impl = createSocketImpl(createSSHClient(NOLISTENPORT), false); - SSHSocket sock = new SSHSocket(impl); - try { - impl.connect(address, port); - } catch (IOException e) { - impl.close(); - throw e; - } - return sock; - } - - public SSHServerSocket createServerSocket(int port, int backlog) throws IOException { - SSHSocketImpl impl = createSocketImpl(createSSHClient(port), true); - SSHServerSocket sock = new SSHServerSocket(impl); - if (port < 0 || port > 0xFFFF) - throw new IllegalArgumentException("Port value out of range: " + port); - - impl.setFactory(this); - try { - impl.bind(InetAddress.getLocalHost(), port); - impl.listen(backlog); - } catch (IOException e) { - impl.close(); - throw e; - } - sock.setSocketFactory(this); - return sock; - } - - public SSHServerSocket createServerSocket(int port) throws IOException { - return createServerSocket(port, SSHServerSocket.DEFAULT_BACKLOG); - } - - public void setServer(String host, int port) { - sshHost = host; - sshPort = port; - } - - public void setServer(String host) { - setServer(host, SSH.DEFAULTPORT); - } - - public void setAuthenticator(SSHAuthenticator authenticator) { - this.authenticator = authenticator; - } - - // SSHClientUser interface "extensions" - // - public void open(SSHClient client) { - // !!! Might want to handle something here, I'm too tired to think of it now (also :-)... - } - - public void connected(SSHClient client) { - // !!! Might want to handle something here, I'm too tired to think of it now... - } - - public void disconnected(SSHClient client, boolean graceful) { - closePseudoAll(client); - } - - public void report(String msg) { - SSH.log("Embedded SSHClient report: " + msg); - } - - public void alert(String msg) { - SSH.log("Embedded SSHClient alert: " + msg); - } - -} diff --git a/src/main/java/com/mindbright/ssh/SSHSocketImpl.java b/src/main/java/com/mindbright/ssh/SSHSocketImpl.java deleted file mode 100644 index 9fa6b17..0000000 --- a/src/main/java/com/mindbright/ssh/SSHSocketImpl.java +++ /dev/null @@ -1,163 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh; - -import java.net.*; -import java.io.*; - -import com.mindbright.util.Queue; - -public class SSHSocketImpl extends SocketImpl { - - public final static int SO_TIMEOUT = 0x1006; // !!! - - protected SSHSocketFactory factory; - - SSHClient client; - SSHSocketTunnel tunnel; - Queue cnQueue; - - boolean isClosed; - - protected SSHSocketImpl() { - // !!! Used to indicate to create if we have done bind() or not... - // (i.e. if we are an implementation of a SSHServerSocket or a SSHSocket) - localport = SSHSocketFactory.NOLISTENPORT; - } - - protected void setFactory(SSHSocketFactory factory) { - this.factory = factory; - } - - protected void create(boolean stream) { - // !!! Not used, but abstract in SocketImpl - } - - protected void create(SSHClient client, boolean acceptor) throws IOException { - InetAddress localHost = InetAddress.getLocalHost(); - - this.client = client; - client.addRef(); - - if(acceptor) { - cnQueue = client.controller.getCnQueue(); - } else { - tunnel = new SSHSocketTunnel(client.controller, this); - tunnel.setLocalAddress(localHost); - } - } - - protected void connect(String host, int port) throws IOException { - try { - address = InetAddress.getByName(host); - } catch (Exception e) { - address = InetAddress.getLocalHost(); - } - - tunnel.connect(host, port); - } - - protected void connect(InetAddress address, int port) throws IOException { - connect(address.getHostAddress(), port); - } - - protected void bind(InetAddress host, int port) throws IOException { - localport = port; - // !!! This is done elsewhere (also, the local address is not important...) - // !!! tunnel.setLocalAddress(host); - } - - protected void listen(int backlog) throws IOException { - cnQueue.setMaxDepth(backlog); - } - - protected void accept(SocketImpl s) throws IOException { - SSHPduOutputStream respPdu; - SSHPduInputStream inPdu; - SSHSocketImpl aImpl = (SSHSocketImpl)s; - int remoteChannel; - inPdu = (SSHPduInputStream) cnQueue.getFirst(); - if(inPdu == null) - throw new IOException("Socket closed"); - remoteChannel = inPdu.readInt(); - aImpl.tunnel.setRemoteChannelId(remoteChannel); - respPdu = new SSHPduOutputStream(SSH.MSG_CHANNEL_OPEN_CONFIRMATION, - client.controller.sndCipher, - client.controller.sndComp, - client.rand); - respPdu.writeInt(remoteChannel); - respPdu.writeInt(aImpl.tunnel.channelId); - client.controller.transmit(respPdu); - client.controller.addTunnel(aImpl.tunnel); - - /* !!! - } catch (Exception e) { - respPdu = new SSHPduOutputStream(SSH.MSG_CHANNEL_OPEN_FAILURE, - client.controller.sndCipher, client.rand); - respPdu.writeInt(remoteChannel); - client.controller.transmit(respPdu); - throw new IOException(e.getMessage()); - } - */ - } - - protected InputStream getInputStream() throws IOException { - return tunnel.in; - } - - protected OutputStream getOutputStream() throws IOException { - return tunnel.out; - } - - protected int available() throws IOException { - return tunnel.available(); - } - - protected void close() throws IOException { - if(localport == SSHSocketFactory.NOLISTENPORT) { - if(tunnel != null && !tunnel.terminated()) - tunnel.close(); - } else { - factory.closePseudoUser(client, this); - } - } - - protected void finalize() throws IOException { - if(!isClosed) - close(); - } - - public void setOption(int optID, Object value) throws SocketException { - throw new SocketException("Not implemented"); - } - - public Object getOption(int optID) throws SocketException { - throw new SocketException("Not implemented"); - } - - protected InetAddress getInetAddress() { - return address; - } - - protected int getPort() { - return port; - } - - protected int getLocalPort() { - return localport; - } - -} diff --git a/src/main/java/com/mindbright/ssh/SSHSocketTunnel.java b/src/main/java/com/mindbright/ssh/SSHSocketTunnel.java deleted file mode 100644 index db16ca7..0000000 --- a/src/main/java/com/mindbright/ssh/SSHSocketTunnel.java +++ /dev/null @@ -1,262 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh; - -import java.net.*; -import java.io.*; - -import com.mindbright.util.Queue; - -public final class SSHSocketTunnel extends SSHTunnel { - - public final static class SSHSocketIS extends InputStream { - protected SSHSocketTunnel tunnel; - protected SSHSocketIS(SSHSocketTunnel tunnel) { - this.tunnel = tunnel; - } - public int read() throws IOException { - byte[] b = new byte[1]; - if(read(b, 0, 1) == -1) - return -1; - return (int) b[0]; - } - public int read(byte b[], int off, int len) throws IOException { - return tunnel.read(b, off, len); - } - public void close() throws IOException { - tunnel.closein(true); - } - } - - public final static class SSHSocketOS extends OutputStream { - protected SSHSocketTunnel tunnel; - protected SSHSocketOS(SSHSocketTunnel tunnel) { - this.tunnel = tunnel; - } - public void write(int b) throws IOException { - byte[] ba = new byte[1]; - ba[0] = (byte) b; - tunnel.write(ba, 0, 1); - } - public void write(byte b[], int off, int len) throws IOException { - tunnel.write(b, off, len); - } - public void close() throws IOException { - tunnel.closeout(); - } - } - - Object lock; - boolean inputClosePending; - boolean inputExplicitClosed; - boolean outputClosed; - boolean terminated; - boolean openFail; - - protected SSHPdu rest; - protected SSHSocketIS in; - protected SSHSocketOS out; - protected InetAddress localAddress; - - protected SSHSocketImpl impl; - - public SSHSocketTunnel(SSHChannelController controller, SSHSocketImpl impl) throws IOException { - super(null, controller.newChannelId(), SSH.UNKNOWN_CHAN_NUM, controller); - - this.lock = new Object(); - - this.inputClosePending = false; - this.inputExplicitClosed = false; - this.outputClosed = false; - this.terminated = false; - this.openFail = false; - - this.txQueue = new Queue(); - this.in = new SSHSocketIS(this); - this.out = new SSHSocketOS(this); - this.impl = impl; - } - - public void start() { - synchronized(lock) { - lock.notify(); - } - } - - public void openFailure() { - openFail = true; - start(); - } - - public int read(byte b[], int off, int len) throws IOException { - SSHPdu pdu = null; - int actLen; - - synchronized(this) { - if(inputExplicitClosed) - throw new SocketException("Socket closed"); - } - - // We reuse the connect-lock since it is only used before we - // start, after that it becomes the read-synchronization lock - // - synchronized(lock) { - if(rest != null) { - pdu = rest; - rest = null; - } else if(inputClosePending && txQueue.isEmpty()) { - pdu = null; - } else { - pdu = (SSHPdu)txQueue.getFirst(); - } - - if(pdu == null) - return -1; - - int rawLen = pdu.rawSize(); - if(len < rawLen) { - rest = pdu; - actLen = len; - } else { - actLen = rawLen; - } - - System.arraycopy(pdu.rawData(), pdu.rawOffset(), b, off, actLen); - - if(rest != null) { - rest.rawAdjustSize(rawLen - len); - } - } - - return actLen; - } - - public void write(byte b[], int off, int len) throws IOException { - SSHPduOutputStream pdu; - - synchronized(this) { - if(outputClosed) - throw new IOException("Resource temporarily unavailable"); - } - - pdu = new SSHPduOutputStream(SSH.MSG_CHANNEL_DATA, - controller.sndCipher, controller.sndComp, - SSH.secureRandom()); - pdu = (SSHPduOutputStream)prepare(pdu); - pdu.writeInt(len); - pdu.write(b, off, len); - controller.transmit(pdu); - } - - public void connect(String host, int port) throws IOException { - SSHPduOutputStream respPdu; - - setRemoteDesc(host + ":" + port); - - respPdu = new SSHPduOutputStream(SSH.MSG_PORT_OPEN, - controller.sndCipher, controller.sndComp, - SSH.secureRandom()); - controller.addTunnel(this); - respPdu.writeInt(channelId); - respPdu.writeString(host); - respPdu.writeInt(port); - respPdu.writeString(localAddress.getHostAddress()); - controller.transmit(respPdu); - - // Wait for start() to be called (i.e. the channel to be confirmed open) - // - synchronized(lock) { - try { - lock.wait(); - } catch(InterruptedException e) { - // !!! - } - } - - if(openFail) - throw new ConnectException("Connection Refused"); - } - -// TGE begin support for JDK1.4 - - // UNDONE I simply do not know how to handle the timeout request. It is - // simple enough to place it into the lock.wait() call, but then if it - // timesout, how do we know the state of the connection?! Further, how - // do we terminate it? I think MindBright needs to deal with this one... - - public void connect(String host, int port, int timeoutMillis) throws IOException { - this.connect( host, port ); - } - -// TGE end - - public void close() throws IOException { - closein(true); - closeout(); - } - - public synchronized void closeout() { - outputClosed = true; - sendInputEOF(); - } - - public void closein(boolean explicit) { - txQueue.release(); - synchronized(this) { - inputClosePending = true; - inputExplicitClosed = explicit; - sendOutputClosed(); - } - } - - public int available() throws IOException { - if(rest != null) - return rest.rawSize(); - else - return 0; - } - - protected void setLocalAddress(InetAddress localAddress) { - this.localAddress = localAddress; - } - - public synchronized void checkTermination() { - if(sentInputEOF && sentOutputClosed && - receivedInputEOF && receivedOutputClosed) { - terminated = true; - controller.delTunnel(channelId); - impl.factory.closePseudoUser(controller.sshAsClient(), impl); - } - } - - public synchronized boolean terminated() { - return terminated; - } - - public void receiveOutputClosed() { - super.receiveOutputClosed(); - closeout(); - } - - public void receiveInputEOF() { - // !!! NOTE: we do not call super's method... - receivedInputEOF = true; - closein(false); - closeout(); - checkTermination(); - } - -} diff --git a/src/main/java/com/mindbright/ssh/SSHStdIO.java b/src/main/java/com/mindbright/ssh/SSHStdIO.java deleted file mode 100644 index c4f735c..0000000 --- a/src/main/java/com/mindbright/ssh/SSHStdIO.java +++ /dev/null @@ -1,280 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh; - -import java.io.*; -import java.awt.*; -import java.awt.datatransfer.*; - -import com.mindbright.terminal.*; - -public final class SSHStdIO implements TerminalInputListener, SSHConsole { - - static public class SSHExternalMessage extends IOException { - public boolean ctrlC; - public boolean isError; - public SSHExternalMessage(String msg) { - super(msg); - ctrlC = false; - } - } - - Container ownerContainer; - SSHChannelController controller; - SSHInteractiveClient client; - // - // !!! Changed this to TerminalWin instead of Terminal, we were - // almost asuming it anyway (theoretical performance gain too! :-) - // - TerminalWin term; - - SSHCipher sndCipher; - String ownerName; - - Boolean readLineLock; - boolean isReadingLine; - boolean echoStar; - String readLineStr; - - protected boolean isConnected; - - public SSHStdIO() { - this.readLineLock = new Boolean(false); - this.controller = null; - this.sndCipher = null; - this.isConnected = false; - } - - public boolean isConnected() { - return isConnected; - } - - public void setTerminal(TerminalWin term) { - this.term = term; - if(term != null) { - term.addInputListener(this); - } - } - - public void setClient(SSHInteractiveClient client) { - this.client = client; - } - - public void setOwnerContainer(Container ownerContainer) { - this.ownerContainer = ownerContainer; - } - - public void setOwnerName(String ownerName) { - this.ownerName = ownerName; - } - - SSHExternalMessage extMsg = null; - public void breakPromptLine() { - breakPromptLine(""); - } - public void breakPromptLine(String msg) { - if(isReadingLine) { - synchronized(readLineLock) { - extMsg = new SSHExternalMessage(msg); - readLineLock.notify(); - } - } - } - - public String readLine(String defaultVal) { - synchronized(readLineLock) { - if(defaultVal != null) { - readLineStr = defaultVal; - term.write(defaultVal); - } else { - readLineStr = ""; - } - isReadingLine = true; - try { - readLineLock.wait(); - } catch (InterruptedException e) { - // !!! - } - isReadingLine = false; - } - return readLineStr; - } - - public String promptLine(String prompt, String defaultVal, boolean echoStar) throws IOException { - String line = null; - if(term != null) { - term.setAttribute(Terminal.ATTR_BOLD, true); - term.write(prompt); - term.setAttribute(Terminal.ATTR_BOLD, false); - this.echoStar = echoStar; - line = readLine(defaultVal); - this.echoStar = false; - } else { - BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); - System.out.print(prompt); - line = br.readLine(); - } - if(extMsg != null) { - SSHExternalMessage msg = extMsg; - extMsg = null; - throw msg; - } - - return line; - } - - public void updateTitle() { - int rows = 0; - int cols = 0; - - if(term == null || ownerContainer == null) - return; - - String title = null; - title = term.getTitle(); - - if(title == null) { - if(client.isOpened()) { - title = client.propsHandler.getProperty("usrname"); - title += "@" + client.propsHandler.getProperty("server"); - title += " <" + client.getServerVersion() + ">"; - } else { - title = ownerName; - } - - if(!client.activateTunnels) { - title += " (CLONE)"; - } - } - - rows = term.rows(); - cols = term.cols(); - title += " [" + cols + "x" + rows + "]"; - - if(ownerContainer instanceof Frame) - ((Frame)ownerContainer).setTitle(title); - } - - // SSHConsole interface - // - public Terminal getTerminal() { - return term; - } - public void stdoutWriteString(byte[] str) { - if(isConnected) - print(new String(str)); - } - public void stderrWriteString(byte[] str) { - if(isConnected) - print(new String(str)); - } - public void print(String str) { - if(term != null) { - term.write(str); - } else { - System.out.print(str); - } - } - public void println(String str) { - if(term != null) { - term.write(str + "\n\r"); - } else { - System.out.println(str); - } - } - public void serverConnect(SSHChannelController controller, - SSHCipher sndCipher) { - this.controller = controller; - this.sndCipher = sndCipher; - isConnected = true; - } - public void serverDisconnect(String reason) { - this.controller = null; - this.sndCipher = null; - isConnected = false; - println(reason); - } - - // TerminalInputListener interface - // - public void typedChar(char c) { - try { - if(isConnected) { - client.stdinWriteChar(c); - } else { - synchronized(readLineLock) { - if(isReadingLine) { - if((c == (char)0x03) || (c == (char)0x04)) { - extMsg = new SSHExternalMessage(""); - extMsg.ctrlC = (c == (char)0x03); - readLineLock.notify(); - } else if(c == (char)127 || c == (char)0x08) { - if(readLineStr.length() > 0) { - boolean ctrlChar = false; - if(readLineStr.charAt(readLineStr.length() - 1) < ' ') { - ctrlChar = true; - } - readLineStr = readLineStr.substring(0, readLineStr.length() - 1); - term.write((char)8); - if(ctrlChar) term.write((char)8); - term.write(' '); - if(ctrlChar) term.write(' '); - term.write((char)8); - if(ctrlChar) term.write((char)8); - } else - term.doBell(); - } else if(c == '\r') { - // readLineStr = readLineStr + "\r"; - readLineLock.notify(); - term.write("\n\r"); - } else { - readLineStr = readLineStr + c; - if(echoStar) - term.write('*'); - else - term.write(c); - } - } - } - } - } catch (IOException e) { - // !!! - System.out.println("**** Error in SSHStdIO.typedChar: " + e); - } - } - public void sendBytes(byte[] b) { - try { - if(isConnected) { - client.stdinWriteString(b); - } else { - for(int i = 0; i < b.length; i++) - typedChar((char)b[i]); - } - } catch (IOException e) { - // !!! - System.out.println("**** Error in SSHStdIO.sendBytes: " + e); - } - } - public void signalWindowChanged(int rows, int cols, int vpixels, int hpixels) { - if(isConnected) { - client.signalWindowChanged(rows, cols, vpixels, hpixels); - } else { - // !!! - } - updateTitle(); - } - -} diff --git a/src/main/java/com/mindbright/ssh/SSHTunnel.java b/src/main/java/com/mindbright/ssh/SSHTunnel.java deleted file mode 100644 index 982a54e..0000000 --- a/src/main/java/com/mindbright/ssh/SSHTunnel.java +++ /dev/null @@ -1,215 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh; - -import java.net.*; -import java.io.*; - -import com.mindbright.util.Queue; - -public class SSHTunnel implements SSHChannelListener { - - int channelId; - int remoteChannelId; - - boolean sentInputEOF; - boolean sentOutputClosed; - boolean receivedInputEOF; - boolean receivedOutputClosed; - - protected SSHChannelController controller; - - protected Socket ioSocket; - protected SSHTxChannel txChan; - protected SSHRxChannel rxChan; - - protected Queue txQueue; - - protected String remoteDesc; - - public SSHTunnel(Socket ioSocket, int channelId, int remoteChannelId, - SSHChannelController controller) - throws IOException { - - this.ioSocket = ioSocket; - this.channelId = channelId; - this.remoteChannelId = remoteChannelId; - this.controller = controller; - this.sentInputEOF = false; - this.sentOutputClosed = false; - this.receivedInputEOF = false; - this.receivedOutputClosed = false; - - if(ioSocket != null) { - try { - rxChan = new SSHRxChannel(new BufferedInputStream(ioSocket.getInputStream(), 8192), channelId); - txChan = new SSHTxChannel(new BufferedOutputStream(ioSocket.getOutputStream()), channelId); - } catch (Exception e) { - throw new IOException("Could not create tunnel: " + e.toString()); - } - txQueue = txChan.getQueue(); - - rxChan.setSSHPduFactory(new SSHPduOutputStream(SSH.MSG_CHANNEL_DATA, - controller.sndCipher, - controller.sndComp, - SSH.secureRandom())); - txChan.setSSHChannelListener(this); - rxChan.setSSHChannelListener(this); - } - } - - public int getLocalPort() { - if(ioSocket != null) - return ioSocket.getLocalPort(); - return 0; - } - - public String getLocalHost() { - if(ioSocket != null) - return ioSocket.getLocalAddress().getHostAddress(); - return "N/A"; - } - - public boolean isOpen() { - if(this.remoteChannelId == SSH.UNKNOWN_CHAN_NUM) - return false; - return true; - } - - public boolean setRemoteChannelId(int remoteChannelId) { - if(isOpen()) - return false; - this.remoteChannelId = remoteChannelId; - return true; - } - - public void start() { - txChan.start(); - rxChan.start(); - } - - public void openFailure() { - if(ioSocket != null) { - try { - ioSocket.close(); - } catch (IOException e) { - // !!! - } - } - } - - public SSHPdu prepare(SSHPdu pdu) throws IOException { - ((SSHPduOutputStream)pdu).writeInt(remoteChannelId); - return pdu; - } - - public void receive(SSHPdu pdu) { - controller.transmit(pdu); - } - - public void transmit(SSHPdu pdu) { - txQueue.putLast(pdu); - } - - public void close(SSHChannel chan) { - if(chan == null || chan instanceof SSHTxChannel) { - sendOutputClosed(); - try { - ioSocket.close(); - } catch (IOException e) { - controller.alert("Error closing socket for: " + channelId + " : " + e.toString()); - } - } else { - sendInputEOF(); - } - checkTermination(); - } - - public synchronized void terminateNow() { - close(null); - } - - public synchronized void checkTermination() { - if(sentInputEOF && sentOutputClosed && - receivedInputEOF && receivedOutputClosed) { - controller.delTunnel(channelId); - if(txChan != null && txChan.isAlive()) - txChan.stop(); - if(rxChan != null && rxChan.isAlive()) - rxChan.stop(); - } - } - - public void sendOutputClosed() { - if(sentOutputClosed) - return; - try { - SSHPduOutputStream pdu = - new SSHPduOutputStream(SSH.MSG_CHANNEL_OUTPUT_CLOSED, - controller.sndCipher, controller.sndComp, - SSH.secureRandom()); - pdu.writeInt(remoteChannelId); - controller.transmit(pdu); - sentOutputClosed = true; - } catch (Exception e) { - controller.alert("Error sending output-closed: " + e.toString()); - } - } - - public void sendInputEOF() { - if(sentInputEOF) - return; - try { - SSHPduOutputStream pdu = new SSHPduOutputStream(SSH.MSG_CHANNEL_INPUT_EOF, - controller.sndCipher, - controller.sndComp, - SSH.secureRandom()); - pdu.writeInt(remoteChannelId); - controller.transmit(pdu); - sentInputEOF = true; - } catch (Exception e) { - controller.alert("Error sending input-EOF: " + e.toString()); - } - } - - public void receiveOutputClosed() { - if(rxChan != null) - rxChan.stop(); - receivedOutputClosed = true; - sendInputEOF(); - checkTermination(); - } - - public void receiveInputEOF() { - if(txChan != null) - txChan.setClosePending(); - receivedInputEOF = true; - checkTermination(); - } - - public void setRemoteDesc(String desc) { - remoteDesc = desc; - } - - public String getDescription() { - if(ioSocket != null) - return ioSocket.getInetAddress().getHostAddress() + ":" + ioSocket.getPort() + " <--> " + - getLocalHost() + ":" + ioSocket.getLocalPort() + " <-ssh-> " + remoteDesc; - else - return "< N/A >"; - } - -} diff --git a/src/main/java/com/mindbright/ssh/SSHTunnelDialog.java b/src/main/java/com/mindbright/ssh/SSHTunnelDialog.java deleted file mode 100644 index 0c5b6b7..0000000 --- a/src/main/java/com/mindbright/ssh/SSHTunnelDialog.java +++ /dev/null @@ -1,251 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh; - -import java.awt.*; -import java.awt.event.*; - -import com.mindbright.gui.AWTConvenience; -import com.mindbright.gui.AWTGridBagContainer; - -public final class SSHTunnelDialog { - - protected final static int ACT_LIST_CLICK = 0; - protected final static int ACT_ADD = 1; - protected final static int ACT_DEL = 2; - - private static class Actions implements ActionListener, ItemListener { - private int action; - - public Actions(int action) { - this.action = action; - } - - public void actionPerformed(ActionEvent e) { - switch(action) { - case ACT_LIST_CLICK: { - int i = tunnelList.getSelectedIndex(); - if(i != -1) { - SSHClient.LocalForward fwd = (SSHClient.LocalForward) client.localForwards.elementAt(i); - localPort.setText(String.valueOf(fwd.localPort)); - remotePort.setText(String.valueOf(fwd.remotePort)); - remoteHost.setText(fwd.remoteHost); - for(i = 1; i < servs.length; i++) { - if(fwd.remotePort == servs[i]) { - protoChoice.select(protos[i]); - break; - } - } - if(i == servs.length) - protoChoice.select("general"); - } - break; - } - case ACT_ADD: { - String rh = remoteHost.getText(); - String plug = "general"; - int lp = -1, rp = -1; - try { - lp = Integer.valueOf(localPort.getText()).intValue(); - rp = Integer.valueOf(remotePort.getText()).intValue(); - if(lp < 1 || lp > 65535) { - lp = -1; - throw new NumberFormatException(); - } - if(rp < 1 || rp > 65535) { - rp = -1; - throw new NumberFormatException(); - } - } catch (NumberFormatException ee) { - if(lp == -1) { - localPort.setText(""); - localPort.requestFocus(); - } else { - remotePort.setText(""); - remotePort.requestFocus(); - } - return; - } - if(protoChoice.getSelectedItem().equals("ftp")) - plug = "ftp"; - try { - propsHandler.setProperty("local" + client.localForwards.size(), - "/" + plug + "/" + lp + ":" + rh + ":" + rp); - if(client.isOpened()) - SSHMiscDialogs.alert("Tunnel Notice", - "Tunnel is now open and operational", - parent); - } catch (Throwable ee) { - SSHMiscDialogs.alert("Tunnel Notice", - "Could not open tunnel: " + - ee.getMessage(), parent); - } - updateTunnelList(); - break; - } - case ACT_DEL: { - int i = tunnelList.getSelectedIndex(); - if(i != -1) { - propsHandler.removeLocalTunnelAt(i, true); - } - updateTunnelList(); - break; - } - } - } - - public void itemStateChanged(ItemEvent e) { - String it = (String)e.getItem(); - int i; - for(i = 0; i < protos.length; i++) - if(it.equals(protos[i])) - break; - if(i > 0) { - remotePort.setText(String.valueOf(servs[i])); - } - } - - } - - private static Dialog basicTunnelsDialog = null; - private static List tunnelList; - private static TextField remoteHost, remotePort, localPort; - private static Choice protoChoice; - private final static String[] protos = { "general", "ftp", "telnet", "smtp", "http", "pop2", "pop3", "nntp", "imap" }; - final static int[] servs = { 0, 21, 23, 25, 80, 109, 110, 119, 143 }; - - private static SSHPropertyHandler propsHandler; - private static Frame parent; - private static SSHClient client; - - public static void show(String title, SSHClient cli, - SSHPropertyHandler props, Frame p) { - propsHandler = props; - parent = p; - client = cli; - if(basicTunnelsDialog == null) { - basicTunnelsDialog = new Dialog(parent, title, true); - - Label lbl; - Button b; - ActionListener al; - AWTGridBagContainer grid = - new AWTGridBagContainer(basicTunnelsDialog); - - grid.getConstraints().fill = GridBagConstraints.NONE; - - lbl = new Label("Current local tunnels:"); - grid.add(lbl, 0, 2); - - grid.getConstraints().fill = GridBagConstraints.BOTH; - grid.getConstraints().insets = new Insets(4, 4, 4, 4); - grid.getConstraints().weightx = 1.0; - grid.getConstraints().weighty = 1.0; - - tunnelList = new List(8); - grid.add(tunnelList, 1, 4); - - tunnelList.addActionListener(new Actions(ACT_LIST_CLICK)); - - grid.getConstraints().fill = GridBagConstraints.NONE; - grid.getConstraints().weighty = 0; - - lbl = new Label("Local port:"); - grid.add(lbl, 2, 1); - - grid.getConstraints().fill = GridBagConstraints.HORIZONTAL; - localPort = new TextField("", 5); - grid.add(localPort, 2, 1); - - grid.getConstraints().fill = GridBagConstraints.NONE; - - lbl = new Label("Protocol:"); - grid.add(lbl, 2, 1); - - protoChoice = AWTConvenience.newChoice(protos); - protoChoice.select("general"); - grid.add(protoChoice, 2, 1); - - protoChoice.addItemListener(new Actions(-1)); - - lbl = new Label("Remote host:"); - grid.add(lbl, 3, 1); - - grid.getConstraints().fill = GridBagConstraints.HORIZONTAL; - - remoteHost = new TextField("", 16); - grid.add(remoteHost, 3, 3); - - grid.getConstraints().fill = GridBagConstraints.NONE; - - lbl = new Label("Remote port:"); - grid.add(lbl, 4, 1); - - grid.getConstraints().fill = GridBagConstraints.HORIZONTAL; - grid.getConstraints().weightx = 0.9; - - remotePort = new TextField("", 5); - grid.add(remotePort, 4, 1); - - b = new Button("Add"); - b.addActionListener(new Actions(ACT_ADD)); - - grid.getConstraints().weightx = 0.1; - - grid.add(b, 4, 1); - - b = new Button("Delete"); - b.addActionListener(new Actions(ACT_DEL)); - - grid.add(b, 4, 1); - - b = new Button("Close Dialog"); - b.addActionListener(new AWTConvenience.CloseAction(basicTunnelsDialog)); - - grid.getConstraints().fill = GridBagConstraints.NONE; - grid.getConstraints().anchor = GridBagConstraints.CENTER; - grid.getConstraints().ipady = 2; - grid.getConstraints().ipadx = 2; - - grid.add(b, 5, GridBagConstraints.REMAINDER); - - basicTunnelsDialog.addWindowListener(new AWTConvenience.CloseAdapter(b)); - - AWTConvenience.setBackgroundOfChildren(basicTunnelsDialog); - - basicTunnelsDialog.setResizable(true); - basicTunnelsDialog.pack(); - } - updateTunnelList(); - - basicTunnelsDialog.setTitle(title); - - AWTConvenience.placeDialog(basicTunnelsDialog); - localPort.requestFocus(); - basicTunnelsDialog.setVisible(true); - } - - private static void updateTunnelList() { - tunnelList.removeAll(); - for(int i = 0; i < client.localForwards.size(); i++) { - SSHClient.LocalForward fwd = (SSHClient.LocalForward) client.localForwards.elementAt(i); - String plugStr = (fwd.plugin.equals("general") ? "" : " (plugin: " + fwd.plugin + ")"); - tunnelList.add("local: " + fwd.localPort + " -> remote: " + fwd.remoteHost + "/" + - fwd.remotePort + plugStr); - } - } - -} diff --git a/src/main/java/com/mindbright/ssh/SSHTxChannel.java b/src/main/java/com/mindbright/ssh/SSHTxChannel.java deleted file mode 100644 index 2e52c5c..0000000 --- a/src/main/java/com/mindbright/ssh/SSHTxChannel.java +++ /dev/null @@ -1,65 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh; - -import java.io.*; - -import com.mindbright.util.Queue; - -public class SSHTxChannel extends SSHChannel { - - protected OutputStream out; - protected Queue queue; - - boolean closePending; - - public SSHTxChannel(OutputStream out, int channelId) { - super(channelId); - this.out = out; - this.closePending = false; - queue = new Queue(); - } - - public Queue getQueue() { - return queue; - } - - public void setClosePending() { - closePending = true; - queue.setBlocking(false); - } - - public synchronized boolean isClosePending() { - return closePending; - } - - public void serviceLoop() throws Exception { - SSH.logExtra("Starting tx-chan: " + channelId); - for(;;) { - SSHPdu pdu; - // !!! the thread is (hopefully) suspended when we set closePending - // so we don't have to access a lock each loop - if(closePending && queue.isEmpty()) { - throw new Exception("CLOSE"); - } - pdu = (SSHPdu)queue.getFirst(); - // pdu = pdu.preProcess(); - pdu.writeTo(out); - // pdu = pdu.postProcess(); - } - } - -} diff --git a/src/main/java/com/mindbright/ssh/SSHVersionSpySocket.java b/src/main/java/com/mindbright/ssh/SSHVersionSpySocket.java deleted file mode 100644 index a702d53..0000000 --- a/src/main/java/com/mindbright/ssh/SSHVersionSpySocket.java +++ /dev/null @@ -1,139 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh; - -import java.net.Socket; -import java.net.SocketException; -import java.net.InetAddress; -import java.io.*; - -public class SSHVersionSpySocket extends Socket { - PushbackInputStream pbIn; - Socket origSocket; - - public SSHVersionSpySocket(Socket origSocket) throws IOException { - this.origSocket = origSocket; - pbIn = new PushbackInputStream(origSocket.getInputStream(), 256); - } - - public int getMajorVersion() throws IOException { - byte[] buf = new byte[256]; - int len = 0; - int c = 0; - String verStr = null; - int srvVersionMajor; - int srvVersionMinor; - int hyphenCnt = 0; - - while(hyphenCnt < 2) { - c = pbIn.read(); - if(c == -1) - throw new IOException("Server closed connection before sending identifaction"); - if(c == '-') - hyphenCnt++; - buf[len++] = (byte)c; - } - verStr = new String(buf, 0, len); - - srvVersionMajor = getMajor(verStr); - srvVersionMinor = getMinor(verStr); - if(srvVersionMinor == 99) - srvVersionMajor = 2; - - pbIn.unread(buf, 0, len); - - return srvVersionMajor; - } - - private static int getMajor(String versionStr) throws IOException { - try { - int r = versionStr.indexOf('.', 4); - return Integer.parseInt(versionStr.substring(4, r)); - } catch (NumberFormatException e) { - throw new IOException("corrupt version string: " + versionStr); - } - } - - private static int getMinor(String versionStr) throws IOException { - try { - int l = versionStr.indexOf('.', 4) + 1; - int r = versionStr.indexOf('-', l); - return Integer.parseInt(versionStr.substring(l, r)); - } catch (NumberFormatException e) { - throw new IOException("corrupt version string: " + versionStr); - } - } - - public InetAddress getInetAddress() { - return origSocket.getInetAddress(); - } - - - public InetAddress getLocalAddress() { - return origSocket.getLocalAddress(); - } - - public int getPort() { - return origSocket.getPort(); - } - - public int getLocalPort() { - return origSocket.getLocalPort(); - } - - public InputStream getInputStream() throws IOException { - return pbIn; - } - - public OutputStream getOutputStream() throws IOException { - return origSocket.getOutputStream(); - } - - public void setTcpNoDelay(boolean on) throws SocketException { - origSocket.setTcpNoDelay(on); - } - - public boolean getTcpNoDelay() throws SocketException { - return origSocket.getTcpNoDelay(); - } - - public void setSoLinger(boolean on, - int val) throws SocketException { - origSocket.setSoLinger(on, val); - } - - public int getSoLinger() throws SocketException { - return origSocket.getSoLinger(); - } - - public synchronized void setSoTimeout(int timeout) throws SocketException { - origSocket.setSoTimeout(timeout); - } - - public synchronized int getSoTimeout() throws SocketException { - return origSocket.getSoTimeout(); - } - - public synchronized void close() throws IOException { - origSocket.close(); - } - - public String toString() { - return origSocket.toString(); - } - - -} diff --git a/src/main/java/com/mindbright/ssh/Version.java b/src/main/java/com/mindbright/ssh/Version.java deleted file mode 100644 index 7805b79..0000000 --- a/src/main/java/com/mindbright/ssh/Version.java +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh; - -public class Version { - public static String version = "2.1 (non-commercial)"; - public static String copyright = - "Copyright (c) AppGate 1998-2001, All rights reserved."; - public static String licenseMessage = - "This copy of MindTerm is for non-commercial and personal use only."; -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2.java b/src/main/java/com/mindbright/ssh2/SSH2.java deleted file mode 100644 index c9c14f5..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2.java +++ /dev/null @@ -1,295 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public abstract class SSH2 { - public final static int SSH_VER_MAJOR = 2; - public final static int SSH_VER_MINOR = 0; - public final static int PKG_VER_MAJOR = 2; - public final static int PKG_VER_MINOR = 1; - public final static String PKG_NAME = "MindTerm"; - - public final static String getPackageVersion(String pkgName, - int pkgMajor, int pkgMinor, - String comment) { - return pkgName + "_" + pkgMajor + "." + pkgMinor + " " + comment; - } - - public final static String getVersionId() { - return getVersionId(getPackageVersion(PKG_NAME, - PKG_VER_MAJOR, PKG_VER_MINOR, - "(Mindbright SSH2)")); - } - - public final static String getVersionId(String pkgVersion) { - String idStr; - if(pkgVersion == null) { - idStr = getVersionId(); - } else { - idStr = "SSH-" + SSH_VER_MAJOR + "." + SSH_VER_MINOR + "-" + - pkgVersion; - } - return idStr; - } - - public final static String msgTypeString(int msgType) { - String msgStr = null; - switch(msgType) { - case MSG_DISCONNECT: - msgStr = "MSG_DISCONNECT"; - break; - case MSG_IGNORE: - msgStr = "MSG_IGNORE"; - break; - case MSG_UNIMPLEMENTED: - msgStr = "MSG_UNIMPLEMENTED"; - break; - case MSG_DEBUG: - msgStr = "MSG_DEBUG"; - break; - case MSG_SERVICE_REQUEST: - msgStr = "MSG_SERVICE_REQUEST"; - break; - case MSG_SERVICE_ACCEPT: - msgStr = "MSG_SERVICE_ACCEPT"; - break; - case MSG_KEXINIT: - msgStr = "MSG_KEXINIT"; - break; - case MSG_NEWKEYS: - msgStr = "MSG_NEWKEYS"; - break; - case 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 LAST_KEX_PACKET: - msgStr = "KEX_METHOD_PACKET_" + msgType; - break; - - case MSG_USERAUTH_REQUEST: - msgStr = "MSG_USERAUTH_REQUEST"; - break; - case MSG_USERAUTH_FAILURE: - msgStr = "MSG_USERAUTH_FAILURE"; - break; - case MSG_USERAUTH_SUCCESS: - msgStr = "MSG_USERAUTH_SUCCESS"; - break; - case MSG_USERAUTH_BANNER: - msgStr = "MSG_USERAUTH_BANNER"; - break; - case 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 LAST_USERAUTH_METHOD_PACKET: - msgStr = "USERAUTH_METHOD_PACKET_" + msgType; - break; - - case MSG_GLOBAL_REQUEST: - msgStr = "MSG_GLOBAL_REQUEST"; - break; - case MSG_REQUEST_SUCCESS: - msgStr = "MSG_REQUEST_SUCCESS"; - break; - case MSG_REQUEST_FAILURE: - msgStr = "MSG_REQUEST_FAILURE"; - break; - case MSG_CHANNEL_OPEN: - msgStr = "MSG_CHANNEL_OPEN"; - break; - - case MSG_CHANNEL_OPEN_CONFIRMATION: - msgStr = "MSG_CHANNEL_OPEN_CONFIRMATION"; - break; - case MSG_CHANNEL_OPEN_FAILURE: - msgStr = "MSG_CHANNEL_OPEN_FAILURE"; - break; - case MSG_CHANNEL_WINDOW_ADJUST: - msgStr = "MSG_CHANNEL_WINDOW_ADJUST"; - break; - case MSG_CHANNEL_DATA: - msgStr = "MSG_CHANNEL_DATA"; - break; - case MSG_CHANNEL_EXTENDED_DATA: - msgStr = "MSG_CHANNEL_EXTENDED_DATA"; - break; - case MSG_CHANNEL_EOF: - msgStr = "MSG_CHANNEL_EOF"; - break; - case MSG_CHANNEL_CLOSE: - msgStr = "MSG_CHANNEL_CLOSE"; - break; - case MSG_CHANNEL_REQUEST: - msgStr = "MSG_CHANNEL_REQUEST"; - break; - case MSG_CHANNEL_SUCCESS: - msgStr = "MSG_CHANNEL_SUCCESS"; - break; - case MSG_CHANNEL_FAILURE: - msgStr = "MSG_CHANNEL_FAILURE"; - break; - default: - msgStr = ""; - break; - } - return msgStr; - } - - /* Maximum length of packet payload, including packet type. */ - public static final int MAX_PAYLOAD_LENGTH = 32768; - - /* Packet numbers for the SSH transport layer protocol. */ - public static final int MSG_DISCONNECT = 1; - public static final int MSG_IGNORE = 2; - public static final int MSG_UNIMPLEMENTED = 3; - public static final int MSG_DEBUG = 4; - public static final int MSG_SERVICE_REQUEST = 5; - public static final int MSG_SERVICE_ACCEPT = 6; - - public static final int MSG_KEXINIT = 20; - public static final int MSG_NEWKEYS = 21; - - - /* Numbers 30-49 for KEX packets. Different KEX methods may reuse - message numbers in this range. */ - public static final int FIRST_KEX_PACKET = 30; - - /* Diffie-Hellman group1 key exchange */ - public static final int MSG_KEXDH_INIT = 30; - public static final int MSG_KEXDH_REPLY = 31; - - /* Diffie-Hellman group and key exchange */ - public static final int MSG_KEXDH_GEX_REQUEST = 30; - public static final int MSG_KEXDH_GEX_GROUP = 31; - public static final int MSG_KEXDH_GEX_INIT = 32; - public static final int MSG_KEXDH_GEX_REPLY = 33; - - public static final int LAST_KEX_PACKET = 49; - - - public static final int FIRST_SERVICE_PACKET = 50; - - /* Packet numbers for the SSH userauth protocol. */ - public static final int MSG_USERAUTH_REQUEST = 50; - public static final int MSG_USERAUTH_FAILURE = 51; - public static final int MSG_USERAUTH_SUCCESS = 52; - public static final int MSG_USERAUTH_BANNER = 53; - - - public static final int FIRST_USERAUTH_METHOD_PACKET = 60; - public static final int LAST_USERAUTH_METHOD_PACKET = 79; - - /* Packet numbers for various authentication methods. */ - /* Password authentication */ - public static final int MSG_USERAUTH_PASSWD_CHANGEREQ = 60; - - /* Challenge-response authentication */ - public static final int MSG_USERAUTH_CHALLENGE = 60; - - /* SecurID authentication */ - public static final int MSG_USERAUTH_SECURID_PINREQ = 60; - public static final int MSG_USERAUTH_SECURID_PINREPLY = 61; - - /* Public key authentication */ - public static final int MSG_USERAUTH_PK_OK = 60; - - /* Keyboard interactive authentication */ - public static final int MSG_USERAUTH_INFO_REQUEST = 60; - public static final int MSG_USERAUTH_INFO_RESPONSE = 61; - - - /* Packet numbers for the SSH connection protocol. */ - public static final int MSG_GLOBAL_REQUEST = 80; - public static final int MSG_REQUEST_SUCCESS = 81; - public static final int MSG_REQUEST_FAILURE = 82; - public static final int MSG_CHANNEL_OPEN = 90; - public static final int MSG_CHANNEL_OPEN_CONFIRMATION = 91; - public static final int MSG_CHANNEL_OPEN_FAILURE = 92; - public static final int MSG_CHANNEL_WINDOW_ADJUST = 93; - public static final int MSG_CHANNEL_DATA = 94; - public static final int MSG_CHANNEL_EXTENDED_DATA = 95; - public static final int MSG_CHANNEL_EOF = 96; - public static final int MSG_CHANNEL_CLOSE = 97; - public static final int MSG_CHANNEL_REQUEST = 98; - public static final int MSG_CHANNEL_SUCCESS = 99; - public static final int MSG_CHANNEL_FAILURE = 100; - - public static final int MSG_RESERVED = 255; - - - /* Debug message types */ - public static final int DEBUG_DEBUG = 0; - public static final int DEBUG_DISPLAY = 1; - - /* Disconnection reasons */ - public static final int DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT = 1; - public static final int DISCONNECT_PROTOCOL_ERROR = 2; - public static final int DISCONNECT_KEY_EXCHANGE_FAILED = 3; - public static final int DISCONNECT_RESERVED = 4; - public static final int DISCONNECT_MAC_ERROR = 5; - public static final int DISCONNECT_COMPRESSION_ERROR = 6; - public static final int DISCONNECT_SERVICE_NOT_AVAILABLE = 7; - public static final int DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED = 8; - public static final int DISCONNECT_HOST_KEY_NOT_VERIFIABLE = 9; - public static final int DISCONNECT_CONNECTION_LOST = 10; - public static final int DISCONNECT_BY_APPLICATION = 11; - public static final int DISCONNECT_TOO_MANY_CONNECTIONS = 12; - public static final int DISCONNECT_AUTH_CANCELLED_BY_USER = 13; - public static final int DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE = 14; - public static final int DISCONNECT_ILLEGAL_USER_NAME = 15; - - /* Extended channel data types. */ - public static final int EXTENDED_DATA_STDERR = 1; - - /* Channel open result codes. */ - public static final int OPEN_OK = 0; - public static final int OPEN_ADMINISTRATIVELY_PROHIBITED = 1; - public static final int OPEN_CONNECT_FAILED = 2; - public static final int OPEN_UNKNOWN_CHANNEL_TYPE = 3; - public static final int OPEN_RESOURCE_SHORTAGE = 4; -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2AccessDeniedException.java b/src/main/java/com/mindbright/ssh2/SSH2AccessDeniedException.java deleted file mode 100644 index 4c77d76..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2AccessDeniedException.java +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public class SSH2AccessDeniedException extends SSH2Exception { - public SSH2AccessDeniedException(String message) { - super(message); - } -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2AuthKbdInteract.java b/src/main/java/com/mindbright/ssh2/SSH2AuthKbdInteract.java deleted file mode 100644 index c8c11e0..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2AuthKbdInteract.java +++ /dev/null @@ -1,99 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -/** - * This class implements a module for keyboard-interactive authentication as - * defined in the auth-kbdinteract protocol spec. It uses the interface - * SSH2Interactor for all interactions generated in the - * authentication process. The keyboard-interactive method is suitable for any - * authentication mechanism where the user enters authentication data via the - * keyboard (e.g. SecureID and CryptoCard). No specifics about the - * authentication mechanism is needed in the authentication module itself making - * it a very flexible way of authentication. - * - * @see SSH2AuthModule - * @see SSH2Interactor - */ -public class SSH2AuthKbdInteract implements SSH2AuthModule { - SSH2Interactor interactor; - String language; - String submethods; - - public SSH2AuthKbdInteract(SSH2Interactor interactor) { - this(interactor, null, null); - } - - public SSH2AuthKbdInteract(SSH2Interactor interactor, String language, - String submethods) { - if(language == null) - language = ""; - if(submethods == null) - submethods = ""; - this.interactor = interactor; - this.language = language; - this.submethods = submethods; - } - - public SSH2TransportPDU processMethodMessage(SSH2UserAuth userAuth, - SSH2TransportPDU pdu) - throws SSH2UserCancelException - { - switch(pdu.getType()) { - case SSH2.MSG_USERAUTH_INFO_REQUEST: - String name = new String(pdu.readString()); - String instruction = new String(pdu.readString()); - String peerLang = new String(pdu.readString()); - int numPrompts = pdu.readInt(); - int i; - - if(numPrompts > 128) { - numPrompts = 128; - } - String[] prompts = new String[numPrompts]; - boolean[] echos = new boolean[numPrompts]; - for(i = 0; i < numPrompts; i++) { - prompts[i] = new String(pdu.readString()); - echos[i] = pdu.readBoolean(); - } - - String[] answers = interactor.promptMultiFull(name, instruction, - prompts, echos); - pdu = SSH2TransportPDU. - createOutgoingPacket(SSH2.MSG_USERAUTH_INFO_RESPONSE); - pdu.writeInt(answers.length); - for(i = 0; i < answers.length; i++) { - pdu.writeString(answers[i]); - } - break; - - default: - userAuth.getTransport().getLog(). - warning("SSH2AuthKbdInteract", - "received unexpected packet of type: " + pdu.getType()); - pdu = null; - } - return pdu; - } - - public SSH2TransportPDU startAuthentication(SSH2UserAuth userAuth) { - SSH2TransportPDU pdu = userAuth.createUserAuthRequest("keyboard-interactive"); - pdu.writeString(language); - pdu.writeString(submethods); - return pdu; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2AuthModule.java b/src/main/java/com/mindbright/ssh2/SSH2AuthModule.java deleted file mode 100644 index d967d8a..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2AuthModule.java +++ /dev/null @@ -1,84 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -/** - * This interface defines an authentication module implementing an - * authentication method (as defined in the userauth protocol - * spec.). Since authentication methods can be very different this - * interface is very simple and the class implementing it must handle - * the processing and formatting of the packets specific to the - * authentication method it implements. Each authentication module is - * associated with an authentication method name when adding it to the - * SSH2Authenticator with which it should be used. - *

- * An authentication module is started when SSH2UserAuth - * calls its startAuthentication method which must return - * the first packet to send to the peer to initiate this - * authentication method. After this the module gets all incoming - * method specific packets passed to its - * processMethodMessage method. This method is expected - * to return formatted packets which the peer end of the - * authentication wants in response. Exceptions that occur during the - * execution of a module is reported to the corresponding - * SSH2Authenticator. The special exception - * SSH2UserCancelException can be thrown to indicate that - * the user canceled this authentication method and that - * authentication should not continue. - *

- * Request packets can created with the convenience method - * createUserAuthRequest in - * SSH2UserAuth. Method specific packets are created with - * the ordinary createOutgoingPacket method in - * SSH2TransportPDU. - * - * @see SSH2UserAuth - * @see SSH2Authenticator - * @see SSH2TransportPDU - */ -public interface SSH2AuthModule { - - /** - * Starts the execution of this module, called from the given - * SSH2UserAuth. - * - * @param userAuth the authentication layer responsible - * - * @return the packet which starts this authentication method - * (i.e. when sent to peer) - * - * @exception SSH2Exception if an error occurs - */ - public SSH2TransportPDU startAuthentication(SSH2UserAuth userAuth) - throws SSH2Exception; - - /** - * Processes the given method specific packet and returns a new - * packet which will be sent to peer to continue the authentication. - * - * @param userAuth the authentication layer responsible - * @param pdu the method specific packet - * - * @return the new packet to send to peer, or null if no packet - * should be sent. - * - * @exception SSH2Exception if an error occurs - */ - public SSH2TransportPDU processMethodMessage(SSH2UserAuth userAuth, - SSH2TransportPDU pdu) - throws SSH2Exception; - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2AuthPassword.java b/src/main/java/com/mindbright/ssh2/SSH2AuthPassword.java deleted file mode 100644 index d8d6cc7..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2AuthPassword.java +++ /dev/null @@ -1,118 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -/** - * This class implements a module for password authentication as defined in the - * userauth protocol spec. It can either be used passively (i.e. the password is - * known beforehand), or it can be used interactively through the - * SSH2Interactor callback interface. - * - * @see SSH2AuthModule - */ -public class SSH2AuthPassword implements SSH2AuthModule { - private String password; - private String newPassword; - private SSH2Interactor interactor; - - public SSH2AuthPassword(String password) { - setPassword(password); - } - - public SSH2AuthPassword(SSH2Interactor interactor) { - this.interactor = interactor; - } - - public void setPassword(String password) { - this.password = password; - } - - public void setNewPassword(String newPassword) { - this.newPassword = newPassword; - } - - protected String getPassword() throws SSH2UserCancelException { - if(password != null) - return password; - if(interactor != null) { - password = interactor.promptLine("Password: ", false); - } else { - password = ""; - } - return password; - } - - protected String getNewPassword(String prompt, String language) - throws SSH2UserCancelException - { - if(newPassword != null) - return newPassword; - if(interactor != null) { - // !!! TODO how is one expected to give user a chance to - // rewrite password... (given only one prompt) - // - // TODO 2 language tag - // - newPassword = interactor.promptLine(prompt, false); - } else { - newPassword = ""; - } - return newPassword; - } - - public SSH2TransportPDU processMethodMessage(SSH2UserAuth userAuth, - SSH2TransportPDU pdu) - throws SSH2UserCancelException - { - switch(pdu.getType()) { - case SSH2.MSG_USERAUTH_PASSWD_CHANGEREQ: - String prompt = pdu.readJavaString(); - String language = pdu.readJavaString(); - pdu = createChangeRequest(userAuth, prompt, language); - break; - - default: - userAuth.getTransport().getLog(). - warning("SSH2AuthPassword", - "received unexpected packet of type: " + pdu.getType()); - pdu = null; - } - - return pdu; - } - - public SSH2TransportPDU startAuthentication(SSH2UserAuth userAuth) - throws SSH2UserCancelException - { - SSH2TransportPDU pdu = userAuth.createUserAuthRequest("password"); - pdu.writeBoolean(false); - pdu.writeString(getPassword()); - return pdu; - } - - private SSH2TransportPDU createChangeRequest(SSH2UserAuth userAuth, - String prompt, - String language) - throws SSH2UserCancelException - { - SSH2TransportPDU pdu = userAuth.createUserAuthRequest("password"); - pdu.writeBoolean(true); - pdu.writeString(getPassword()); - pdu.writeString(getNewPassword(prompt, language)); - return pdu; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2AuthPublicKey.java b/src/main/java/com/mindbright/ssh2/SSH2AuthPublicKey.java deleted file mode 100644 index 21b79ef..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2AuthPublicKey.java +++ /dev/null @@ -1,123 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -/** - * This class implements a module for publickey authentication as defined in the - * userauth protocol spec. It uses the interface SSH2PKISigner to - * access an abstract PKI signing mechanism (e.g. implemented with simple file - * based public/private keys without certificates). - * - * @see SSH2AuthModule - * @see SSH2PKISigner - */ -public class SSH2AuthPublicKey implements SSH2AuthModule { - - private SSH2PKISigner signer; - private boolean test; - - public SSH2AuthPublicKey(SSH2PKISigner signer) { - this(signer, true); - } - - public SSH2AuthPublicKey(SSH2PKISigner signer, boolean test) { - this.signer = signer; - this.test = test; - } - - protected SSH2PKISigner getSigner() { - return signer; - } - - public SSH2TransportPDU processMethodMessage(SSH2UserAuth userAuth, - SSH2TransportPDU pdu) { - switch(pdu.getType()) { - case SSH2.MSG_USERAUTH_PK_OK: - try { - pdu = createRequest(userAuth, false); - } catch (SSH2SignatureException e) { - // !!! TODO how do we want to handle this? - pdu = null; - } - break; - - default: - userAuth.getTransport().getLog(). - warning("SSH2AuthPublicKey", - "received unexpected packet of type: " + pdu.getType()); - pdu = null; - } - return pdu; - } - - public SSH2TransportPDU startAuthentication(SSH2UserAuth userAuth) - throws SSH2SignatureException - { - return createRequest(userAuth, test); - } - - private SSH2TransportPDU createRequest(SSH2UserAuth userAuth, boolean test) - throws SSH2SignatureException - { - SSH2TransportPDU pdu = userAuth.createUserAuthRequest("publickey"); - SSH2PKISigner signer = getSigner(); - byte[] keyBlob = signer.getPublicKeyBlob(); - - pdu.writeBoolean(!test); - pdu.writeString(signer.getAlgorithmName()); - pdu.writeString(keyBlob); - - if(!test) { - signPDU(userAuth, pdu, signer, keyBlob); - } - - return pdu; - } - - private void signPDU(SSH2UserAuth userAuth, SSH2TransportPDU targetPDU, - SSH2PKISigner signer, byte[] keyBlob) - throws SSH2SignatureException - { - SSH2TransportPDU sigPDU = targetPDU; - - if(userAuth.getTransport().incompatiblePublicKeyAuth) { - sigPDU = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_USERAUTH_REQUEST); - sigPDU.writeString(userAuth.user); - sigPDU.writeString("ssh-userauth"); - sigPDU.writeString("publickey"); - sigPDU.writeBoolean(true); - sigPDU.writeString(signer.getAlgorithmName()); - sigPDU.writeString(keyBlob); - } - - byte[] sessionId = userAuth.getTransport().getSessionId(); - - int payloadLength = sigPDU.wPos - sigPDU.getPayloadOffset(); - byte[] signData = new byte[payloadLength + sessionId.length]; - - System.arraycopy(sessionId, 0, signData, 0, sessionId.length); - System.arraycopy(sigPDU.data, sigPDU.getPayloadOffset(), - signData, sessionId.length, payloadLength); - - signer.setIncompatibility(userAuth.getTransport()); - - byte[] sig = signer.sign(signData); - - targetPDU.writeString(sig); - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2Authenticator.java b/src/main/java/com/mindbright/ssh2/SSH2Authenticator.java deleted file mode 100644 index edc84e3..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2Authenticator.java +++ /dev/null @@ -1,219 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.util.Hashtable; -import java.util.Vector; - -/** - * This is the base class for an "authenticator" representing a user and the - * methods available to authenticate that user. This class is also used to - * receive callbacks from the SSH2UserAuth with which it is - * used. Since this class is not abstract it can be used as is, however to be - * able to monitor the authentication process it is recommeded to subclass it. - *

- * The ordered list of available authentication methods is created by adding - * each method together with its SSH2AuthModule. The order in which - * modules are added is the order in which they will be used. - * - * @see SSH2UserAuth - * @see SSH2AuthModule - */ -public class SSH2Authenticator { - - private Hashtable authModules = new Hashtable(); - private Vector methodList = new Vector(); - - private String username; - - /** - * Special constructor for creating an "anonymouse" authenticator. Note, - * when using this constructor the username has to be set before - * authentication using the method setUsername. - */ - public SSH2Authenticator() { - } - - /** - * Basic constructor most commonly used. - * - * @param username the name of the user we represent - */ - public SSH2Authenticator(String username) { - this.username = username; - } - - /** - * Gets a comma separated list of the authentication methods currently set. - * - * @return a comma separated list of authentication methods - */ - public synchronized String getMethods() { - StringBuffer buf = new StringBuffer(); - for(int i = 0; i < methodList.size(); i++) { - buf.append(methodList.elementAt(i)); - if(i < methodList.size() - 1) - buf.append(","); - } - return buf.toString(); - } - - /** - * Gets the name of the user we represent. - * - * @return the name of the user we represent - */ - public String getUsername() { - return username; - } - - /** - * Sets the name of the user to be represented. - * - * @param username the name of the user to be represented - */ - public void setUsername(String username) { - this.username = username; - } - - /** - * Callback from SSH2UserAuth which gives a banner message as - * part of the authentication (as defined in the spec. of the userauth - * protocol). This method does nothing, it should be implemented in a - * subclass. - * - * @param banner the banner message - */ - public void displayBanner(String banner) { - } - - /** - * Gets the SSH2AuthModule implementing the given - * authentication method. - * - * @param method the authentication method wanted - */ - public synchronized SSH2AuthModule getModule(String method) { - return (SSH2AuthModule)authModules.get(method); - } - - /** - * Callback from SSH2UserAuth which gives the available - * authentication methods as reported by peer. The list is comma - * separated. This method does nothing, it should be implemented in a - * subclass. - * - * @param methods the comma separated list of methods - */ - public void peerMethods(String methods) { - } - - /** - * Callback from SSH2UserAuth which reports that there are no - * more authentication methods left to try to authenticate with. This - * method does nothing, it should be implemented in a subclass. - */ - public void noMoreMethods() { - } - - /** - * Callback from SSH2UserAuth which reports that an exception - * occured while running the given authentication method. This method does - * nothing, it should be implemented in a subclass. - * - * @param method the authentication method that failed - * @param e the exception that occured in that method's module - */ - public void moduleFailure(String method, SSH2Exception e) { - } - - /** - * Callback from SSH2UserAuth which reports that the user - * canceled the given authentication method (i.e. a - * SSH2UserCancelException was thrown from the current - * SSH2AuthModule). This method does nothing, it should be - * implemented in a subclass. - * - * @param method the authentication method that was canceled - * @param reason a string giving the reason for cancelation if any - */ - public void moduleCancel(String method, String reason) { - } - - /** - * Callback from SSH2UserAuth which reports that the given - * authentication method failed (i.e. not an error, authentication will - * continue if more methods are available). This method does nothing, it - * should be implemented in a subclass. - * - * @param method the authentication method that failed - * @param partial a boolean indicating if this failure was a partial success - * or not (i.e. the method succeeded but more methods are needed for full - * authentication). - */ - public void authFailure(String method, boolean partial) { - } - - /** - * Callback from SSH2UserAuth which reports that the given - * authentication method succeeded and that the user is now authenticated. - * This method does nothing, it should be implemented in a subclass. - * - * @param method the authentication method that succeeded - */ - public void authSuccess(String method) { - } - - /** - * Callback from SSH2UserAuth which reports that an error has - * occured (e.g. the server disconnected) or that the authentication has - * been explicitly terminated (someone called the method - * terminate in SSH2UserAuth) and that the - * authentication is aborted. This method does nothing, it should be - * implemented in a subclass. - */ - public void authError() { - } - - /** - * Adds an authentication module (a class implementing - * SSH2AuthModule) to the list of available authentication - * methods and associates the module with the given method name. The module - * is added last in the current list, hence modules must be added in the - * order of preference. - * - * @param method the name of the method this module implements - * @param module the authentication module - */ - public final synchronized void addModule(String method, - SSH2AuthModule module) - { - if(method == null || module == null) - return; - authModules.put(method, module); - methodList.addElement(method); - } - - /** - * Removes the module associated with the given authentication method from - * the list of available methods. - */ - public final synchronized void removeModule(String method) { - authModules.remove(method); - methodList.removeElement(method); - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2Channel.java b/src/main/java/com/mindbright/ssh2/SSH2Channel.java deleted file mode 100644 index cf78e13..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2Channel.java +++ /dev/null @@ -1,297 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -/** - * This is the abstract base class for all channels as defined in the connection - * protocol spec. Each channel has a specific type (e.g. session). Each channel - * type is implemented by a subclass to this class. This base class makes no - * assumptions as to how data is handled by the channel it only implements - * methods which are used from the multiplexing code in - * SSH2Connection. - *

- * When implementing a new channel type or implementing an existing one - * differntly from what available one typically subclasses - * SSH2StreamChannel instead of SSH2Channel directly - * since it implements the notion of streams (through use of - * java.io.InputStream and java.io.OutputStream) and - * flow control. Only a very specific implementation of a channel would need to - * subclass SSH2Channel directly. - - * - * @see SSH2Connection - * @see SSH2StreamChannel - */ -public abstract class SSH2Channel { - public final static int STATUS_UNDEFINED = 0; - public final static int STATUS_OPEN = 1; - public final static int STATUS_CLOSED = 2; - public final static int STATUS_FAILED = 3; - - protected SSH2Connection connection; - - protected int channelType; - - protected int channelId; - protected int peerChanId; - - protected int rxMaxPktSz; - protected int rxInitWinSz; - protected int rxCurrWinSz; - - protected int txInitWinSz; - protected int txCurrWinSz; - protected int txMaxPktSz; - - protected volatile boolean eofSent; - protected volatile boolean eofReceived; - protected volatile boolean closeReceived; - protected volatile boolean closeSent; - protected volatile boolean deleted; - - protected Object creator; - - protected Object openMonitor; - protected int openStatus; - - protected SSH2Channel(int channelType, SSH2Connection connection, - Object creator) - { - SSH2ConnectionPreferences prefs = connection.getPreferences(); - this.channelType = channelType; - this.connection = connection; - this.creator = creator; - this.rxInitWinSz = prefs.getRxInitWinSz(channelType); - this.rxCurrWinSz = this.rxInitWinSz; - this.rxMaxPktSz = prefs.getRxMaxPktSz(channelType); - this.openStatus = STATUS_UNDEFINED; - this.openMonitor = new Object(); - connection.addChannel(this); - } - - protected synchronized final void openConfirmation(SSH2TransportPDU pdu) { - int peerChanId = pdu.readInt(); - int txInitWinSz = pdu.readInt(); - int txMaxPktSz = pdu.readInt(); - init(peerChanId, txInitWinSz, txMaxPktSz); - openConfirmationImpl(pdu); - - switch(channelType) { - case SSH2Connection.CH_TYPE_FWD_TCPIP: - connection.getEventHandler().localForwardedConnect(connection, - (SSH2Listener)creator, - this); - break; - case SSH2Connection.CH_TYPE_DIR_TCPIP: - connection.getEventHandler().localDirectConnect(connection, - (SSH2Listener)creator, - this); - break; - case SSH2Connection.CH_TYPE_SESSION: - connection.getEventHandler().localSessionConnect(connection, - this); - break; - case SSH2Connection.CH_TYPE_X11: - connection.getEventHandler().localX11Connect(connection, - (SSH2Listener)creator, - this); - break; - /* !!! TODO - case SSH2Connection.CH_TYPE_AUTH_AGENT: - connection.getEventHandler().localDirectConnect(connection, - (SSH2Listener)creator, - this); - break; */ - } - - synchronized (openMonitor) { - this.openStatus = STATUS_OPEN; - openMonitor.notifyAll(); - } - - connection.getLog().notice("SSH2Channel", - "open confirmation, ch. #" + channelId + - ", init-winsz = " + txInitWinSz + - ", max-pktsz = " + txMaxPktSz); - } - - protected synchronized final void openFailure(int reasonCode, - String reasonText, - String langTag) { - closeSent = true; - eofSent = true; - - boolean keepChannel = openFailureImpl(reasonCode, reasonText, langTag); - - connection.getEventHandler().localChannelOpenFailure(connection, - this, - reasonCode, - reasonText, - langTag); - if(!keepChannel) { - connection.delChannel(this); - } - - synchronized (openMonitor) { - this.openStatus = STATUS_FAILED; - openMonitor.notifyAll(); - } - - connection.getLog().notice("SSH2Channel", "open failure on ch. #" + - channelId + ", reason: " + reasonText); - } - - protected final void windowAdjust(SSH2TransportPDU pdu) { - int inc = pdu.readInt(); - windowAdjustImpl(inc); - } - - protected void data(SSH2TransportPDU pdu) { - } - - protected void extData(SSH2TransportPDU pdu) { - } - - protected final void handleRequest(SSH2TransportPDU pdu) { - String reqType = new String(pdu.readString()); - boolean wantReply = pdu.readBoolean(); - handleRequestImpl(reqType, wantReply, pdu); - } - - protected void requestSuccess(SSH2TransportPDU pdu) { - } - - protected void requestFailure(SSH2TransportPDU pdu) { - } - - private final void checkTermination() { - if(closeSent && closeReceived && !deleted) { - deleted = true; - connection.delChannel(this); - } - } - - protected final void recvEOF() { - if(eofReceived) { - connection.getLog().debug("SSH2Channel", "ch. # " + channelId + - " received multiple EOFs"); - } - eofReceived = true; - eofImpl(); - if(eofSent) { - sendClose(); - } - } - - protected final synchronized void recvClose() { - if(!closeReceived) { - closeReceived = true; - eofSent = true; - closeImpl(); - sendClose(); - connection.getLog().debug("SSH2Channel", - "closing ch. #" + channelId + - " (" + getType() + ")"); - connection.getEventHandler().channelClosed(connection, this); - } - checkTermination(); - } - - protected final void sendEOF() { - if(!eofSent && !closeSent) { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_CHANNEL_EOF); - pdu.writeInt(peerChanId); - connection.transmit(pdu); - eofSent = true; - } - } - - protected final synchronized void sendClose() { - if(!closeSent) { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_CHANNEL_CLOSE); - pdu.writeInt(peerChanId); - connection.transmit(pdu); - closeSent = true; - synchronized (openMonitor) { - openStatus = STATUS_CLOSED; - openMonitor.notifyAll(); - } - } - checkTermination(); - } - - protected void init(int peerChanId, int txInitWinSz, int txMaxPktSz) { - this.peerChanId = peerChanId; - this.txInitWinSz = txInitWinSz; - this.txMaxPktSz = txMaxPktSz; - this.txCurrWinSz = txInitWinSz; - } - - protected void transmit(SSH2TransportPDU pdu) { - if(!closeSent) { - connection.transmit(pdu); - } - } - - public int openStatus() { - synchronized (openMonitor) { - if(openStatus == STATUS_UNDEFINED) { - try { - openMonitor.wait(); - } catch (InterruptedException e) { - /* don't care, someone interrupted us on purpose */ - } - } - return openStatus; - } - } - - public final synchronized void close() { - if(!connection.getTransport().isConnected()) { - recvClose(); - } - sendClose(); - } - - public String getType() { - return SSH2Connection.channelTypes[channelType]; - } - - public int getId() { - return channelId; - } - - public int getPeerId() { - return peerChanId; - } - - public Object getCreator() { - return creator; - } - - protected abstract void openConfirmationImpl(SSH2TransportPDU pdu); - protected abstract boolean openFailureImpl(int reasonCode, - String reasonText, - String langTag); - protected abstract void windowAdjustImpl(int inc); - protected abstract void eofImpl(); - protected abstract void closeImpl(); - protected abstract void handleRequestImpl(String reqType, boolean wantReply, - SSH2TransportPDU pdu); - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2CompressionException.java b/src/main/java/com/mindbright/ssh2/SSH2CompressionException.java deleted file mode 100644 index 931b185..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2CompressionException.java +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public class SSH2CompressionException extends SSH2FatalException { - - public SSH2CompressionException(String message) { - super(message, null); - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2Compressor.java b/src/main/java/com/mindbright/ssh2/SSH2Compressor.java deleted file mode 100644 index a34040b..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2Compressor.java +++ /dev/null @@ -1,56 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public abstract class SSH2Compressor { - - public final static int COMPRESS_MODE = 1; - public final static int UNCOMPRESS_MODE = 2; - - // !!! TODO - public static SSH2Compressor getInstance(String algorithm, int mode) - throws SSH2CompressionException - { - return getInstance(algorithm, mode, -1); - } - - public static SSH2Compressor getInstance(String algorithm, - int mode, int level) - throws SSH2CompressionException - { - if("zlib".equals(algorithm)) { - try { - Class compCl = - Class.forName("com.mindbright.ssh2.SSH2CompressorZLib"); - SSH2Compressor comp = (SSH2Compressor)compCl.newInstance(); - comp.init(mode, level); - return comp; - } catch (Exception e) { - throw new SSH2CompressionException(e.getMessage()); - } - } - return null; - } - - public abstract void init(int mode, int level); - public abstract void compress(SSH2DataBuffer data) - throws SSH2CompressionException; - public abstract int uncompress(SSH2DataBuffer data, int len) - throws SSH2CompressionException; - public abstract long numOfCompressedBytes(); - public abstract long numOfUncompressedBytes(); - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2CompressorZLib.java b/src/main/java/com/mindbright/ssh2/SSH2CompressorZLib.java deleted file mode 100644 index ff8b5d4..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2CompressorZLib.java +++ /dev/null @@ -1,116 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import com.jcraft.jzlib.ZStream; -import com.jcraft.jzlib.JZlib; - -public class SSH2CompressorZLib extends SSH2Compressor { - - private final static int DEFLATE_BUF_SIZE = 49152; - private final static int INFLATE_BUF_SIZE = 65536; - - private ZStream dStream; - private ZStream iStream; - private byte[] dBuf; - private byte[] iBuf; - - public SSH2CompressorZLib() { - } - - public void init(int mode, int level) { - switch(mode) { - case COMPRESS_MODE: - dStream = new ZStream(); - dStream.deflateInit(level); - dStream.next_out = dBuf = new byte[DEFLATE_BUF_SIZE]; - break; - case UNCOMPRESS_MODE: - iStream = new ZStream(); - iStream.inflateInit(); - iStream.next_out = iBuf = new byte[INFLATE_BUF_SIZE]; - break; - default: - throw new Error("Unknown mode sent to SSH2CompressorZLib"); - } - } - - public void compress(SSH2DataBuffer data) throws SSH2CompressionException { - dStream.next_in = data.getData(); - dStream.next_in_index = 9; - dStream.avail_in = data.getWPos() - 9; - dStream.next_out_index = 0; - dStream.avail_out = DEFLATE_BUF_SIZE; - - int status = dStream.deflate(JZlib.Z_PARTIAL_FLUSH); - - if(status != JZlib.Z_OK) { - throw new SSH2CompressionException("Error in zlib deflate: " + - status); - } - - int dLen = DEFLATE_BUF_SIZE - dStream.avail_out; - - if((dStream.next_in.length - 256) < dLen) { - data.setData(new byte[dLen + (dStream.next_in.length >>> 1)]); - } - - System.arraycopy(dBuf, 0, data.getData(), 9, dLen); - data.setWPos(9 + dLen); - } - - public int uncompress(SSH2DataBuffer data, int len) - throws SSH2CompressionException - { - iStream.next_in = data.getData(); - iStream.next_in_index = 9; - iStream.avail_in = len; - iStream.next_out_index = 0; - iStream.avail_out = INFLATE_BUF_SIZE; - - int status = iStream.inflate(JZlib.Z_PARTIAL_FLUSH); - - if(status != JZlib.Z_OK) { - throw new SSH2CompressionException("Error in zlib inflate: " + - status); - } - - int iLen = INFLATE_BUF_SIZE - iStream.avail_out; - - if((iStream.next_in.length - 256) < iLen) { - data.setData(new byte[iLen + (iStream.next_in.length >>> 1)]); - } - - System.arraycopy(iBuf, 0, data.getData(), 9, iLen); - - return iLen; - } - - public long numOfCompressedBytes() { - if(iStream != null) { - return iStream.total_in; - } - return dStream.total_out; - } - - public long numOfUncompressedBytes() { - if(iStream != null) { - return iStream.total_out; - } - return dStream.total_in; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2ConnectException.java b/src/main/java/com/mindbright/ssh2/SSH2ConnectException.java deleted file mode 100644 index d3d4c6c..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2ConnectException.java +++ /dev/null @@ -1,25 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public class SSH2ConnectException extends SSH2Exception { - public SSH2ConnectException(String message) { - this(message, null); - } - public SSH2ConnectException(String message, Throwable rootCause) { - super(message, rootCause); - } -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2Connection.java b/src/main/java/com/mindbright/ssh2/SSH2Connection.java deleted file mode 100644 index 53b955f..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2Connection.java +++ /dev/null @@ -1,852 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.IOException; -import java.util.Hashtable; -import java.util.Vector; -import java.util.Enumeration; - -import com.mindbright.jca.security.SecureRandom; - -import com.mindbright.util.SecureRandomAndPad; -import com.mindbright.util.Log; - -/** - * This class implements the connection layer of the secure shell version 2 - * (ssh2) protocol stack. This layer contains the multiplexing of the secure - * connection to the server into several different channels which can be used - * for port forwarding and terminal sessions as defined in the connection - * protocol spec. - *

- * To create a SSH2Connection instance a connected - * SSH2Transport along with an authenticated - * SSH2UserAuth must be created first to be passed to the - * constructor. Optionally a SSH2ConnectionEventHandler and/or a - * SSH2ConnectionPreferences can be supplied to be able to monitor - * and control the connection layer. A log handler can also be set, though by - * default the connection layer uses the same log handler as the transport - * layer. - *

- * The connection layer must be hooked into the transport layer explicitly by - * calling the method setConnection on the - * SSH2Transport. Once the connection layer is hooked up to the - * transport layer channels can be created. There are basically four types of - * channels: session, local forward, remote forward, and X11 forward. There are - * methods for creating local and remote forwards aswell as session channels, - * however, X11 channels must be created through session channels. - * - * @see SSH2Transport - * @see SSH2UserAuth - * @see SSH2ConnectionEventHandler - * @see SSH2ConnectionPreferences - * @see SSH2Channel - * @see SSH2Connector - * @see SSH2Listener - */ -public final class SSH2Connection { - public final static int MAX_ACTIVE_CHANNELS = 1024; - - public final static String GL_REQ_START_FORWARD = "tcpip-forward"; - public final static String GL_REQ_CANCEL_FORWARD = "cancel-tcpip-forward"; - - public final static String CH_REQ_PTY = "pty-req"; - public final static String CH_REQ_X11 = "x11-req"; - public final static String CH_REQ_ENV = "env"; - public final static String CH_REQ_SHELL = "shell"; - public final static String CH_REQ_EXEC = "exec"; - public final static String CH_REQ_SUBSYSTEM = "subsystem"; - public final static String CH_REQ_WINCH = "window-change"; - public final static String CH_REQ_XONOFF = "xon-xoff"; - public final static String CH_REQ_SIGNAL = "signal"; - public final static String CH_REQ_EXIT_STAT = "exit-status"; - public final static String CH_REQ_EXIT_SIG = "exit-signal"; - public final static String CH_REQ_AUTH_AGENT = "auth-agent-req"; - public final static String CH_REQ_AUTH_AGENT1 = "auth-ssh1-agent-req"; - - public final static String CHAN_FORWARDED_TCPIP = "forwarded-tcpip"; - public final static String CHAN_DIRECT_TCPIP = "direct-tcpip"; - public final static String CHAN_SESSION = "session"; - public final static String CHAN_X11 = "x11"; - public final static String CHAN_AUTH_AGENT = "auth-agent"; - - final static int CH_TYPE_FWD_TCPIP = 0; - final static int CH_TYPE_DIR_TCPIP = 1; - final static int CH_TYPE_SESSION = 2; - final static int CH_TYPE_X11 = 3; - final static int CH_TYPE_AUTH_AGENT = 4; - - final static String[] channelTypes = { - CHAN_FORWARDED_TCPIP, - CHAN_DIRECT_TCPIP, - CHAN_SESSION, - CHAN_X11, - CHAN_AUTH_AGENT - }; - - private class SSH2ChannelReaper implements Runnable { - - private Vector life; - private Vector death; - - private volatile boolean keepKilling; - - protected SSH2ChannelReaper() { - this.life = new Vector(); - this.death = new Vector(); - this.keepKilling = true; - Thread reaper = new Thread(this); - reaper.setDaemon(true); - reaper.setPriority(Thread.MIN_PRIORITY); - reaper.start(); - } - - public void run() { - while(keepKilling) { - try { - Thread.sleep(3000); - } catch (InterruptedException e) { - /* Don't care really, somebody interrupted us? */ - } - while(!death.isEmpty()) { - SSH2Channel toBeKilled = (SSH2Channel)death.firstElement(); - killChannel(toBeKilled); - death.removeElementAt(0); - } - Vector limbo = death; - death = life; - life = limbo; - } - } - - protected void kill(SSH2Channel chan) { - life.addElement(chan); - } - - protected void die() { - keepKilling = false; - } - - } - - private SSH2Transport transport; - private SSH2UserAuth userAuth; - - private SSH2ConnectionEventHandler eventHandler; - private SSH2ConnectionPreferences connPrefs; - - private SSH2Channel[] channels; - private int totalChannels; - private int nextEmptyChan; - - private SSH2Connector connector; - private SSH2ChannelReaper reaper; - - private Hashtable remoteForwards; - private Hashtable remoteFilters; - private Hashtable localForwards; - - private byte[] x11FakeCookie; - private boolean x11Single; - private int x11Mappings; - - private Object reqMonitor; - private boolean reqStatus; - - private Log connLog; - - /** - * Basic constructor used when there is no need for event handler or special - * preferences. - * - * @param userAuth the authentication layer - * @param transport the transport layer - */ - public SSH2Connection(SSH2UserAuth userAuth, SSH2Transport transport) { - this(userAuth, transport, null, null); - } - - /** - * Constructor used when there need for event handler and/or special - * preferences. - * - * @param userAuth the authentication layer - * @param transport the transport layer - * @param eventHandler the event handler (may be null) - * @param connPrefs the connection preferences (may be null) - */ - public SSH2Connection(SSH2UserAuth userAuth, SSH2Transport transport, - SSH2ConnectionEventHandler eventHandler, - SSH2ConnectionPreferences connPrefs) { - this.userAuth = userAuth; - this.transport = transport; - this.eventHandler = (eventHandler != null ? eventHandler : - new SSH2ConnectionEventAdapter()); - this.connPrefs = (connPrefs != null ? connPrefs : - new SSH2ConnectionPreferences()); - this.channels = new SSH2Channel[64]; - this.totalChannels = 0; - this.nextEmptyChan = 0; - this.remoteForwards = new Hashtable(); - this.remoteFilters = new Hashtable(); - this.localForwards = new Hashtable(); - - this.x11FakeCookie = null; - this.x11Single = false; - this.x11Mappings = 0; - - this.connLog = transport.getLog(); - - this.reqMonitor = new Object(); - } - - void processGlobalMessage(SSH2TransportPDU pdu) { - switch(pdu.pktType) { - case SSH2.MSG_GLOBAL_REQUEST: - String type = new String(pdu.readString()); - boolean wantReply = pdu.readBoolean(); - if(type.equals(GL_REQ_START_FORWARD)) { - - } else if(type.equals(GL_REQ_CANCEL_FORWARD)) { - - } else { - - } - break; - - case SSH2.MSG_REQUEST_SUCCESS: - synchronized(reqMonitor) { - reqStatus = true; - reqMonitor.notify(); - } - break; - - case SSH2.MSG_REQUEST_FAILURE: - synchronized(reqMonitor) { - reqStatus = false; - reqMonitor.notify(); - } - break; - - case SSH2.MSG_CHANNEL_OPEN: - getConnector().channelOpen(pdu); - break; - } - } - - void processChannelMessage(SSH2TransportPDU pdu) { - int channelId = pdu.readInt(); - SSH2Channel channel = channels[channelId]; - - if(channel == null) { - String msg = "Error, received message to non-existent channel"; - connLog.error("SSH2Connection", "processChannelMessage", msg); - connLog.debug2("SSH2Connection", - "processChannelMessage", - "got message of type: " + - SSH2.msgTypeString(pdu.pktType), - pdu.getData(), - pdu.getPayloadOffset(), - pdu.getPayloadLength()); - fatalDisconnect(SSH2.DISCONNECT_PROTOCOL_ERROR, msg); - return; - } - - switch(pdu.pktType) { - case SSH2.MSG_CHANNEL_OPEN_CONFIRMATION: - channel.openConfirmation(pdu); - break; - - case SSH2.MSG_CHANNEL_OPEN_FAILURE: - int reasonCode = pdu.readInt(); - String reasonText; - String langTag; - if(transport.incompatibleChannelOpenFail) { - reasonText = ""; - langTag = ""; - } else { - reasonText = pdu.readJavaString(); - langTag = pdu.readJavaString(); - } - channel.openFailure(reasonCode, reasonText, langTag); - break; - - case SSH2.MSG_CHANNEL_WINDOW_ADJUST: - channel.windowAdjust(pdu); - break; - - case SSH2.MSG_CHANNEL_DATA: - channel.data(pdu); - break; - - case SSH2.MSG_CHANNEL_EXTENDED_DATA: - channel.extData(pdu); - break; - - case SSH2.MSG_CHANNEL_EOF: - channel.recvEOF(); - break; - - case SSH2.MSG_CHANNEL_CLOSE: - channel.recvClose(); - break; - - case SSH2.MSG_CHANNEL_REQUEST: - channel.handleRequest(pdu); - break; - - case SSH2.MSG_CHANNEL_SUCCESS: - channel.requestSuccess(pdu); - break; - - case SSH2.MSG_CHANNEL_FAILURE: - channel.requestFailure(pdu); - break; - } - } - - /** - * Gets our transport layer. - * - * @return the transport layer - */ - public SSH2Transport getTransport() { - return transport; - } - - /** - * Sets the event handler to use. - * - * @param eventHandler the event handler to use - */ - public void setEventHandler(SSH2ConnectionEventHandler eventHandler) { - if(eventHandler != null) { - this.eventHandler = eventHandler; - } - } - - /** - * Gets the event handler currently in use. - * - * @return the event handler currently in use - */ - public SSH2ConnectionEventHandler getEventHandler() { - return eventHandler; - } - - /** - * Sets the preferences to use. - * - * @param connPrefs the event handler to use - */ - public void setPreferences(SSH2ConnectionPreferences connPrefs) { - if(connPrefs != null) { - this.connPrefs = connPrefs; - } - } - - /** - * Gets the preferences currently in use. - * - * @return the preferences currently in use - */ - public SSH2ConnectionPreferences getPreferences() { - return connPrefs; - } - - /** - * Gets the log handler currently in use. - * - * @return the log handler currently in use - */ - public Log getLog() { - return connLog; - } - - /** - * Sets the log handler to use. - * - * @param the log handler to use - */ - public void setLog(Log log) { - connLog = log; - } - - /** - * Gets the SecureRandom currently in use (i.e. from the - * transport layer). - * - * @return the SecureRandom in use - */ - public SecureRandom getSecureRandom() { - return transport.getSecureRandom(); - } - - /** - * Transmits the given PDU (by sending it to the transport layer, no - * processing is needed at this point). - * - * @param pdu packet to send - */ - public void transmit(SSH2TransportPDU pdu) { - transport.transmit(pdu); - } - - /** - * Disconnects from peer using the DISCONNECT packet type with the given - * reason and description. See the class SSH2 for reason codes. - * This is only a convenience method which calls the same method on the - * transport layer. - * - * @param reason the reason code - * @param description the textual description for the cause of disconnect - * - * @see SSH2 - */ - public void fatalDisconnect(int reason, String description) { - transport.fatalDisconnect(reason, description); - } - - /** - * Gets the singleton instance of the SSH2Connector which is - * used by the connection layer to connect remote forwards through to local - * hosts when they are opened. - * - * @return the singleton connector - */ - public SSH2Connector getConnector() { - if(connector == null) { - connector = new SSH2Connector(this); - } - return connector; - } - - /** - * Gets the local target host address and port pair of a remote forward - * identified by the given remote address and port pair. This function is - * used to locate the local target of a remote forward when it is opened. - * - * @param remoteAddr the remote address of the forward - * @param remotePort the remote port of the forward - * - * @return the address and port, the address beeing at index 0 and the port - * beeing at inde 1. - */ - public synchronized String[] getForwardTarget(String remoteAddr, - int remotePort) { - String[] target = null; - String tgStr = (String)remoteForwards.get(remoteAddr + ":" + - remotePort); - if(tgStr != null) { - target = new String[2]; - int i = tgStr.indexOf(":"); - target[0] = tgStr.substring(0, i); - target[1] = tgStr.substring(i + 1); - } - - return target; - } - - /** - * Gets the filter factory instance for a remote forward identified by the - * given remote address and port pair. - * - * @param remoteAddr the remote address of the forward - * @param remotePort the remote port of the forward - * - * @return the stream filter factory instance - */ - - public synchronized SSH2StreamFilterFactory - getForwardFilterFactory(String remoteAddr, int remotePort) - { - return (SSH2StreamFilterFactory)remoteFilters.get(remoteAddr + ":" + - remotePort); - } - - /** - * Creates a new remote forward from the given remote address and port on - * the server to the local address and port. - * - * @param remoteAddr the remote address where the server listens - * @param remotePort the remote port where the server listens - * @param localAddr the local address to connect through to - * @param localAddr the local port to connect through to - */ - public synchronized void newRemoteForward(String remoteAddr, - int remotePort, - String localAddr, - int localPort) { - newRemoteForward(remoteAddr, remotePort, localAddr, localPort, - (SSH2StreamFilterFactory)null); - } - - /** - * Creates a new remote forward from the given remote address and port on - * the server to the local address and port using the given filter factory - * to insert filters in the input/output streams of the forwarded channels. - * - * @param remoteAddr the remote address where the server listens - * @param remotePort the remote port where the server listens - * @param localAddr the local address to connect through to - * @param localAddr the local port to connect through to - * @param filterFactory the filter factory instance to use for producing - * filters. - */ - public synchronized void - newRemoteForward(String remoteAddr, int remotePort, - String localAddr, int localPort, - SSH2StreamFilterFactory filterFactory) - { - newRemoteForward(remoteAddr, remotePort, localAddr, localPort, - filterFactory, false); - } - - /** - * Creates a new remote forward from the given remote address and port on - * the server to the local address and port using the given filter factory - * to insert filters in the input/output streams of the forwarded - * channel. This is a blocking version of the method - * newRemoteForward with the same parameters which waits until - * a result is reported from the server which indicates whether the forward - * could be set up or not. - * - * @param remoteAddr the remote address where the server listens - * @param remotePort the remote port where the server listens - * @param localAddr the local address to connect through to - * @param localAddr the local port to connect through to - * @param filterFactory the filter factory instance to use for producing - * filters. - */ - public boolean newRemoteForwardBlocking(String remoteAddr, int remotePort, - String localAddr, int localPort, - SSH2StreamFilterFactory - filterFactory) - { - synchronized(reqMonitor) { - newRemoteForward(remoteAddr, remotePort, localAddr, localPort, - filterFactory, true); - try { - reqMonitor.wait(); - } catch (InterruptedException e) { - /* don't care, someone interrupted us on purpose */ - } - return reqStatus; - } - } - - synchronized void - newRemoteForward(String remoteAddr, int remotePort, - String localAddr, int localPort, - SSH2StreamFilterFactory filterFactory, - boolean wantReply) - { - connLog.debug("SSH2Connection", "newRemoteForward", - remoteAddr + ":" + remotePort + "->" + - localAddr + ":" + localPort); - - remoteForwards.put(remoteAddr + ":" + remotePort, - localAddr + ":" + localPort); - if(filterFactory != null) { - remoteFilters.put(remoteAddr + ":" + remotePort, - filterFactory); - } - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_GLOBAL_REQUEST); - pdu.writeString(GL_REQ_START_FORWARD); - pdu.writeBoolean(wantReply); - pdu.writeString(remoteAddr); - pdu.writeInt(remotePort); - transport.transmit(pdu); - } - - /** - * Deletes the remote forward identified by the given remote address and - * port pair. Note that the channels that was previously opened through this - * forward are not deleted, only a CANCEL_FORWARD request is sent to the - * server which deletes the forward on the server preventing further - * channels to be opened through this forward. - * - * @param remoteAddr the remote address of the forward - * @param remotePort the remote port of the forward - */ - public synchronized void deleteRemoteForward(String remoteAddr, - int remotePort) { - connLog.debug("SSH2Connection", "deleteRemoteForward", - remoteAddr + ":" + remotePort); - - String tgStr = (String)remoteForwards.get(remoteAddr + ":" + - remotePort); - if(tgStr != null) { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_GLOBAL_REQUEST); - pdu.writeString(GL_REQ_CANCEL_FORWARD); - pdu.writeBoolean(true); - pdu.writeString(remoteAddr); - pdu.writeInt(remotePort); - transport.transmit(pdu); - remoteForwards.remove(remoteAddr + ":" + remotePort); - } - } - - /** - * Creates a new local forward from the given local address and port to - * the remote address and port on the server side. - * - * @param localAddr the local address to listen to - * @param localAddr the local port to listen to - * @param remoteAddr the remote address where the connects to - * @param remotePort the remote port where the connects to - * - * @return a listener instance accepting connections to forward - */ - public synchronized SSH2Listener newLocalForward(String localAddr, - int localPort, - String remoteAddr, - int remotePort) - throws IOException - { - return newLocalForward(localAddr, localPort, remoteAddr, remotePort, - (SSH2StreamFilterFactory)null); - } - - /** - * Creates a new local forward from the given local address and port to the - * remote address and port on the server side using the given filter factory - * to insert filters in the input/output streams of the forwarded channels. - * - * @param localAddr the local address to listen to - * @param localAddr the local port to listen to - * @param remoteAddr the remote address where the connects to - * @param remotePort the remote port where the connects to - * @param filterFactory the filter factory instance to use for producing - * filters. - * - * @return a listener instance accepting connections to forward - */ - public synchronized SSH2Listener - newLocalForward(String localAddr, int localPort, - String remoteAddr, int remotePort, - SSH2StreamFilterFactory filterFactory) - throws IOException - { - connLog.debug("SSH2Connection", "newLocalForward", - localAddr + ":" + localPort + "->" + - remoteAddr + ":" + remotePort); - - SSH2Listener listener = new SSH2Listener(localAddr, localPort, - remoteAddr, remotePort, - this, filterFactory); - localForwards.put(localAddr + ":" + localPort, listener); - - return listener; - } - - /** - * Deletes the local forward identified by the given local address and port - * pair. Note that the channels that was previously opened through this - * forward are not deleted, only the corresponding listener is stopped - * preventing further channels to be opened through this forward. - * - * @param localAddr the local address of the forward - * @param localAddr the local port of the forward - */ - public synchronized void deleteLocalForward(String localAddr, - int localPort) { - connLog.debug("SSH2Connection", "deleteLocalForward", - localAddr + ":" + localPort); - - SSH2Listener listener = - (SSH2Listener)localForwards.get(localAddr + ":" + - localPort); - if(listener != null) { - listener.stop(); - localForwards.remove(localAddr + ":" + localPort); - } - } - - /** - * Creates a new session channel. - * - * @return the new session channel - */ - public synchronized SSH2SessionChannel newSession() { - return newSession((SSH2StreamFilter)null); - } - - /** - * Creates a new session channel using the given filter for filtering the - * standard input/output streams of the session. - * - * @param filter the filter to use - * - * @return the new session channel - */ - public synchronized SSH2SessionChannel newSession(SSH2StreamFilter filter) - { - SSH2SessionChannel channel = new SSH2SessionChannel(this); - - channel.applyFilter(filter); - - SSH2TransportPDU pdu = getChannelOpenPDU(channel); - transmit(pdu); - return channel; - } - - /** - * Creates a new session channel attaching its standard input/output streams - * to the given terminal adapter. It is up to the terminal adapter - * implementation to attach itself to the I/O streams of the session - * channel. For this purpose the interface method attach is - * called before the channel open message is sent to the server so the - * terminal adapter is attached before I/O is started. - * - * @param termAdapter the terminal adapter to attach to the session - * - * @return the new session channel - */ - public synchronized SSH2SessionChannel - newTerminal(SSH2TerminalAdapter termAdapter) - { - SSH2SessionChannel channel = new SSH2SessionChannel(this); - SSH2TransportPDU pdu = getChannelOpenPDU(channel); - - termAdapter.attach(channel); - - transmit(pdu); - return channel; - } - - synchronized boolean hasX11Mapping() { - boolean hasMapping = (x11Mappings > 0); - if(x11Single) { - x11Mappings--; - } - return hasMapping; - } - - synchronized void setX11Mapping(boolean single) { - x11Single = single; - x11Mappings++; - } - - synchronized void clearX11Mapping() { - if(x11Mappings > 0) { - x11Mappings--; - } - } - - byte[] getX11FakeCookie() { - if(x11FakeCookie == null) { - x11FakeCookie = new byte[16]; - SecureRandomAndPad srap = (SecureRandomAndPad) - transport.getSecureRandom(); - srap.nextPadBytes(x11FakeCookie, 0, 16); - } - return x11FakeCookie; - } - - byte[] getX11RealCookie() { - byte[] x11RealCookie = connPrefs.getX11Cookie(); - if(x11RealCookie == null) { - x11RealCookie = getX11FakeCookie(); - } - return x11RealCookie; - } - - synchronized void terminate() { - if(connector != null) { - connector.stop(); - } - Enumeration listeners = localForwards.elements(); - while(listeners.hasMoreElements()) { - ((SSH2Listener)listeners.nextElement()).stop(); - } - for(int i = 0; i < channels.length; i++) { - if(channels[i] != null) { - channels[i].close(); - } - } - if(reaper != null) { - reaper.die(); - } - } - - synchronized void addChannel(SSH2Channel channel) { - int newChan = nextEmptyChan; - if(nextEmptyChan < channels.length) { - int i; - for(i = nextEmptyChan + 1; i < channels.length; i++) - if(channels[i] == null) - break; - nextEmptyChan = i; - } else { - if(channels.length + 16 > MAX_ACTIVE_CHANNELS) { - fatalDisconnect(SSH2.DISCONNECT_TOO_MANY_CONNECTIONS, - "Number of channels exceeded maximum"); - return; - } - SSH2Channel[] tmp = new SSH2Channel[channels.length + 16]; - System.arraycopy(channels, 0, tmp, 0, channels.length); - channels = tmp; - nextEmptyChan++; - } - channel.channelId = newChan; - channels[newChan] = channel; - totalChannels++; - eventHandler.channelAdded(this, channel); - } - - synchronized void killChannel(SSH2Channel channel) { - if(channel == null || channel.channelId == -1 || - channel.channelId >= channels.length || - channels[channel.channelId] == null) { - connLog.error("SSH2Connection", "killChannel", - "ch. # " + (channel != null ? - String.valueOf(channel.getId()) : - "") + - " not present"); - return; - } - totalChannels--; - channels[channel.channelId] = null; - if(channel.channelId < nextEmptyChan) - nextEmptyChan = channel.channelId; - eventHandler.channelDeleted(this, channel); - } - - void delChannel(SSH2Channel channel) { - getReaper().kill(channel); - } - - private SSH2ChannelReaper getReaper() { - if(reaper == null) { - reaper = new SSH2ChannelReaper(); - } - return reaper; - } - - SSH2TransportPDU getChannelOpenPDU(SSH2Channel channel) { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_CHANNEL_OPEN); - pdu.writeString(channelTypes[channel.channelType]); - pdu.writeInt(channel.channelId); - pdu.writeInt(channel.rxInitWinSz); - pdu.writeInt(channel.rxMaxPktSz); - return pdu; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2ConnectionEventAdapter.java b/src/main/java/com/mindbright/ssh2/SSH2ConnectionEventAdapter.java deleted file mode 100644 index f86b65d..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2ConnectionEventAdapter.java +++ /dev/null @@ -1,83 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.net.Socket; - -/** - * This class is an adapter for the interface - * SSH2ConnectionEventHandler. - * - * @see SSH2ConnectionEventHandler - */ -public class SSH2ConnectionEventAdapter implements SSH2ConnectionEventHandler -{ - public void channelAdded(SSH2Connection connection, SSH2Channel channel) { - } - public void channelDeleted(SSH2Connection connection, SSH2Channel channel) { - } - public void channelClosed(SSH2Connection connection, SSH2Channel channel) { - } - - public void listenerAccept(SSH2Listener listener, Socket fwdSocket) { - listener.doConnect(fwdSocket); - } - public void listenerConnect(SSH2Listener listener, Socket fwdSocket) { - } - - public void localForwardedConnect(SSH2Connection connection, - SSH2Listener listener, - SSH2Channel channel) { - } - public void localDirectConnect(SSH2Connection connection, - SSH2Listener listener, - SSH2Channel channel) { - } - public void localSessionConnect(SSH2Connection connection, - SSH2Channel channel) { - } - public void localX11Connect(SSH2Connection connection, - SSH2Listener listener, - SSH2Channel channel) { - } - public void localChannelOpenFailure(SSH2Connection connection, - SSH2Channel channel, - int reasonCode, String reasonText, - String languageTag) { - } - - public void remoteForwardedConnect(SSH2Connection connection, - String remoteAddr, int remotePort, - SSH2Channel channel) { - } - public void remoteDirectConnect(SSH2Connection connection, - SSH2Channel channel) { - } - public void remoteSessionConnect(SSH2Connection connection, - String remoteAddr, int remotePort, - SSH2Channel channel) { - } - public void remoteX11Connect(SSH2Connection connection, - SSH2Channel channel) { - } - public void remoteChannelOpenFailure(SSH2Connection connection, - String channelType, - String targetAddr, int targetPort, - String originAddr, int originPort, - SSH2Exception cause) { - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2ConnectionEventHandler.java b/src/main/java/com/mindbright/ssh2/SSH2ConnectionEventHandler.java deleted file mode 100644 index e2c76e6..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2ConnectionEventHandler.java +++ /dev/null @@ -1,204 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.net.Socket; - -/** - * This interface is an event callback interface used to monitor the connection - * layer of an ssh2 connection. It is used with the class - * SSH2Connection to get info on the progress and status of all - * forwards and resulting channels through the connection. - *

- * All callback methods which indicates channel open confirmation or channel - * open failure uses the naming convention that when it begins with "local" - * (e.g. localDirectConnect) it is coupled to a channel originating - * locally and conversly when it begins with "remote" - * (e.g. remoteForwardedConnect) it is coupled to a channel - * originating remotely. The naming of the channel types in the connection - * protocol specification is used to identify whether a channel is a local - * forward or a remote forward. This means that local forwards are called - * "direct" and remote forwards are called "forwarded". This naming can be - * somewhat confusing for example the method localForwardedConnect - * might be the one might expect to be called when a local forward channel is - * confirmed to be open, instead the call is - * localDirectConnect. The reason for this is to have a symmetrical - * naming for all callbacks which are valid on both client and server side, - * hence check each callback and see if it applies to youe need (i.e. client or - * server). - * - * @see SSH2Connection - * @see SSH2ConnectionEventAdapter - * @see SSH2Listener - * @see SSH2Channel - */ -public interface SSH2ConnectionEventHandler -{ - // !!! TODO add globalRequest calls... ??? - // public void globalRequest(SSH2Connection conn, String type); - - /** - * Called when a new channel is added (i.e. a new channel has been opened - * through a port forward). - * - * @param connection the connection layer responsible - * @param channel the channel which was added - * - */ - public void channelAdded(SSH2Connection connection, SSH2Channel channel); - - /** - * Called when a channel is deleted (i.e. a channel has been finally - * removed). - * - * @param connection the connection layer responsible - * @param channel the channel which was deleted - */ - public void channelDeleted(SSH2Connection connection, SSH2Channel channel); - - /** - * Called when a channel is closed (i.e. the channel has been closed and - * will be flushed and then removed). - * - * @param connection the connection layer responsible - * @param channel the channel which was deleted - */ - public void channelClosed(SSH2Connection connection, SSH2Channel channel); - - /** - * Called when a listener accepts a new connection (i.e. a local forward is - * opened). - * - * @param listener the responsible listener - * @param fwdSocket the socket which resulted - */ - public void listenerAccept(SSH2Listener listener, Socket fwdSocket); - - /** - * Called when a listener connects a channel through a local forward by - * creating the new channel instance and sending a CHANNEL_OPEN request to - * the server. - * - * @param listener the responsible listener - * @param fwdSocket the socket which resulted - */ - public void listenerConnect(SSH2Listener listener, Socket fwdSocket); - - /** - * Called on the server side when a remote forward channel is confirmed to - * be open. - * - * @param connection the connection layer responsible - * @param listener the responsible listener - * @param channel the channel which was opened - */ - public void localForwardedConnect(SSH2Connection connection, - SSH2Listener listener, - SSH2Channel channel); - /** - * Called on the client side when a local forward channel is confirmed to - * be open. - * - * @param connection the connection layer responsible - * @param listener the responsible listener - * @param channel the channel which was opened - */ - public void localDirectConnect(SSH2Connection connection, - SSH2Listener listener, - SSH2Channel channel); - - /** - * Called on the client side when a session channel is confirmed to be open. - * - * @param connection the connection layer responsible - * @param channel the channel which was opened - */ - public void localSessionConnect(SSH2Connection connection, - SSH2Channel channel); - - /** - * Called on the server side when an X11 channel is confirmed to be open. - * - * @param connection the connection layer responsible - * @param listener the responsible listener - * @param channel the channel which was opened - */ - public void localX11Connect(SSH2Connection connection, - SSH2Listener listener, - SSH2Channel channel); - - /** - * Called on either side when a locally originating channel gets a channel - * open failure indication from peer. See the class SSH2 for - * reason codes. - * - * @param connection the connection layer responsible - * @param channel the channel which was opened - * @param reasonCode the reason code - * @param reasonText - * @param languageTag - * - * @see SSH2 - */ - public void localChannelOpenFailure(SSH2Connection connection, - SSH2Channel channel, - int reasonCode, String reasonText, - String languageTag); - - /** - * Called on the client side when a remote forward channel has been - * confirmed to be open. - * - * @param connection the connection layer responsible - * @param remoteAddr - * @param remotePort - * @param channel the channel which was opened - */ - public void remoteForwardedConnect(SSH2Connection connection, - String remoteAddr, int remotePort, - SSH2Channel channel); - - public void remoteDirectConnect(SSH2Connection connection, - SSH2Channel channel); - - public void remoteSessionConnect(SSH2Connection connection, - String remoteAddr, int remotePort, - SSH2Channel channel); - - public void remoteX11Connect(SSH2Connection connection, - SSH2Channel channel); - - /** - * Called on either side when there is a problem opening a remotely - * originating channel resulting in a channel open failure indication beeing - * sent back to peer. The exception which was the cause of the problem is - * provided aswell as the type of channel and relevant addresses and ports. - * - * @param connection the connection layer responsible - * @param channelType the type of channel - * @param targetAddr the address which should have been connected to - * @param targetPort the port which should have been connected to - * @param originAddr the address where the channel originated (depends on type) - * @param originPort the port where the channel originated (depends on type) - * @param cause the exception which was the cause of the problem - */ - public void remoteChannelOpenFailure(SSH2Connection connection, - String channelType, - String targetAddr, int targetPort, - String originAddr, int originPort, - SSH2Exception cause); - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2ConnectionPreferences.java b/src/main/java/com/mindbright/ssh2/SSH2ConnectionPreferences.java deleted file mode 100644 index e5c338f..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2ConnectionPreferences.java +++ /dev/null @@ -1,186 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.net.Socket; - -/** - * This class is used to control the preferences of the connection - * layer. Besides controlling pure preferences this class controls socket - * options on sockets used in port forward channels, this behaviour must be - * implemented in a subclass though. - * - * @see SSH2Connection - */ -public class SSH2ConnectionPreferences { - - public static final int DEFAULT_INIT_WINSZ = 32768; - public static final int DEFAULT_MAX_PKTSZ = 8192; - - public static final String DEFAULT_X11_LOCALADDR = "127.0.0.1"; - public static final int DEFAULT_X11_LOCALPORT = 6000; - - private int initWinSz; - private int maxPktSz; - - private String x11LocalAddr; - private int x11LocalPort; - private byte[] x11Cookie; - - /** - * Constructor setting default values to all preferences. The defaults are: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
PreferenceValue
Initial window size32768 bytes
Max packet size8192 bytes
Local address for X11 display127.0.0.1
Local port for X11 display6000
- */ - public SSH2ConnectionPreferences() { - this.initWinSz = DEFAULT_INIT_WINSZ; - this.maxPktSz = DEFAULT_MAX_PKTSZ; - this.x11LocalAddr = DEFAULT_X11_LOCALADDR; - this.x11LocalPort = DEFAULT_X11_LOCALPORT; - this.x11Cookie = null; - } - - /** - * Called to set socket options on newly connected port forward channels - * - * @param channelType the type of the channel - * @param s socket to manipulate - */ - public void setSocketOptions(int channelType, Socket s) { - // Do nothing by default, derive this class to change - } - - /** - * Sets initial window size for the given channel type. This class doesn't - * implement different sizes for different types, it must be sub classed to - * implement this behaviour. - * - * @param channelType the type of the channel - * @param initWinSz new initial window size - */ - public void setRxInitWinSz(int channelType, int initWinSz) { - this.initWinSz = initWinSz; - } - - /** - * Gets initial window size for the given channel type. This class doesn't - * implement different sizes for different types, it must be sub classed to - * implement this behaviour. - * - * @return the initial window size - */ - public int getRxInitWinSz(int channelType) { - return initWinSz; - } - - /** - * Sets max packet size for the given channel type. This class doesn't - * implement different sizes for different types, it must be sub classed to - * implement this behaviour. - * - * @param channelType the type of the channel - * @param maxPktSz new max packet size - */ - public void setRxMaxPktSz(int channelType, int maxPktSz) { - this.maxPktSz = maxPktSz; - } - - /** - * Gets max packet size for the given channel type. This class doesn't - * implement different sizes for different types, it must be sub classed to - * implement this behaviour. - * - * @return the max packet size - */ - public int getRxMaxPktSz(int channelType) { - return maxPktSz; - } - - /** - * Sets the address for the local X11 display. - * - * @param x11LocalAddr the local address to use - */ - public void setX11LocalAddr(String x11LocalAddr) { - if(x11LocalAddr != null) { - this.x11LocalAddr = x11LocalAddr; - } - } - - /** - * Gets the local address of the X11 display. - * - * @return the local address of the X11 display - */ - public String getX11LocalAddr() { - return x11LocalAddr; - } - - /** - * Sets the port for the local X11 display. - * - * @param x11LocalPort the local port to use - */ - public void setX11LocalPort(int x11LocalPort) { - if(x11LocalPort > 0) { - this.x11LocalPort = x11LocalPort; - } - } - - /** - * Gets the local port of the X11 display. - * - * @return the local port of the X11 display - */ - public int getX11LocalPort() { - return x11LocalPort; - } - - /** - * Sets the X11 authentication cookie as a byte array. - * - * @param x11Cookie a byte array containing the authentication cookie - */ - public void setX11Cookie(byte[] x11Cookie) { - this.x11Cookie = x11Cookie; - } - - /** - * Gets the X11 authentication cookie. - * - * @return a byte array containing the X11 authentication cookie - */ - public byte[] getX11Cookie() { - return x11Cookie; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2Connector.java b/src/main/java/com/mindbright/ssh2/SSH2Connector.java deleted file mode 100644 index 48cf974..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2Connector.java +++ /dev/null @@ -1,277 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; - -import com.mindbright.util.Queue; - -/** - * This class takes care of all incoming CHANNEL_OPEN messages. It contains a - * thread which utilizes a queue to fetch the channel open requests. It creates - * new channels according to type requested. Only a single instance of - * SSH2Connector exists for each instance of the ssh2 stack. - * - * @see SSH2Connection - */ -public final class SSH2Connector implements Runnable { - - private Queue openQueue; - private Thread myThread; - - private SSH2Connection connection; - - private volatile boolean keepRunning; - - public SSH2Connector(SSH2Connection connection) { - this.connection = connection; - this.openQueue = new Queue(); - this.keepRunning = true; - - myThread = new Thread(this, "SSH2Connector"); - myThread.setDaemon(true); - myThread.start(); - } - - public void run() { - try { - netscape.security.PrivilegeManager.enablePrivilege("TerminalEmulator"); - } catch (netscape.security.ForbiddenTargetException e) { - // !!! - } - - while(keepRunning) { - SSH2TransportPDU pdu = null; - SSH2Channel channel = null; - - String channelType = ""; - int peerChanId = -1; - int txInitWinSz = -1; - int txMaxPktSz = -1; - String targetAddr = ""; - int targetPort = -1; - String originAddr = ""; - int originPort = -1; - - try { - pdu = (SSH2TransportPDU)openQueue.getFirst(); - - if(pdu == null) { - keepRunning = false; - continue; - } - - channelType = new String(pdu.readString()); - peerChanId = pdu.readInt(); - txInitWinSz = pdu.readInt(); - txMaxPktSz = pdu.readInt(); - - if(channelType.equals(SSH2Connection.CHAN_FORWARDED_TCPIP)) { - String remoteAddr = new String(pdu.readString()); - int remotePort = pdu.readInt(); - originAddr = new String(pdu.readString()); - originPort = pdu.readInt(); - - connection.getLog().debug("SSH2Connection", "run", - "remote connect on " + - remoteAddr + ":" + remotePort + - " (orig. " + - originAddr + ":" + originPort + - ")"); - - String[] localTarget = - connection.getForwardTarget(remoteAddr, remotePort); - - SSH2StreamFilterFactory filterFactory = - connection.getForwardFilterFactory(remoteAddr, - remotePort); - - if(localTarget == null) { - throw new IOException("Unsolicited forward attempted"); - } - - targetAddr = localTarget[0]; - targetPort = Integer.valueOf(localTarget[1]).intValue(); - - connection.getLog().notice("SSH2Connector", - "connect: " + - localTarget[0] + ":" + - localTarget[1] + " (peerid: " + - peerChanId + ")"); - - channel = connect(channelType, peerChanId, - txInitWinSz, txMaxPktSz, - remoteAddr, remotePort, - targetAddr, targetPort, - originAddr, originPort, - filterFactory); - connection.getEventHandler().remoteForwardedConnect(connection, - remoteAddr, - remotePort, - channel); - - } else if(channelType.equals(SSH2Connection.CHAN_DIRECT_TCPIP)) { - targetAddr = new String(pdu.readString()); - targetPort = pdu.readInt(); - originAddr = new String(pdu.readString()); - originPort = pdu.readInt(); - channel = connect(channelType, peerChanId, - txInitWinSz, txMaxPktSz, - targetAddr, targetPort, - originAddr, originPort, - null); - connection.getEventHandler().remoteDirectConnect(connection, - channel); - - } else if(channelType.equals(SSH2Connection.CHAN_X11)) { - targetAddr = connection.getPreferences().getX11LocalAddr(); - targetPort = connection.getPreferences().getX11LocalPort(); - originAddr = new String(pdu.readString()); - originPort = pdu.readInt(); - - if(!connection.hasX11Mapping()) { - throw new IOException("Unexpected X11 channel open"); - } - - channel = connect(channelType, peerChanId, - txInitWinSz, txMaxPktSz, - targetAddr, targetPort, - originAddr, originPort, - SSH2X11Filter.getFilterFactory()); - - connection.getEventHandler().remoteX11Connect(connection, - channel); - - } else if(channelType.equals(SSH2Connection.CHAN_SESSION)) { - throw new IOException("Unexpected session channel open"); - } else if(channelType.equals(SSH2Connection.CHAN_AUTH_AGENT)) { - throw new IOException("Agent forwarding not supported"); - } else { - throw new IOException("Unknown channel type: " + channelType); - } - - } catch (IOException e) { - String msg = "open failed: " + e.getMessage(); - connection.getLog().error("SSH2Connector", "run", msg); - sendOpenFailure(peerChanId, 2, msg); - connection.getEventHandler().remoteChannelOpenFailure( - connection, channelType, - targetAddr, targetPort, - originAddr, originPort, - new SSH2ConnectException("Failed in SSH2Connector", e)); - } finally { - if(pdu != null) - pdu.release(); - } - } - } - - public void channelOpen(SSH2TransportPDU pdu) { - openQueue.putLast(pdu); - } - - public void setThreadPriority(int prio) { - myThread.setPriority(prio); - } - - public void stop() { - keepRunning = false; - openQueue.setBlocking(false); - } - - private SSH2Channel connect(String channelType, int peerChanId, - int txInitWinSz, int txMaxPktSz, - String targetAddr, int targetPort, - String originAddr, int originPort, - SSH2StreamFilterFactory filterFactory) - throws IOException - { - return connect(channelType, peerChanId, txInitWinSz, txMaxPktSz, - "", 0, - targetAddr, targetPort, originAddr, originPort, - filterFactory); - } - - private SSH2Channel connect(String channelType, int peerChanId, - int txInitWinSz, int txMaxPktSz, - String remoteAddr, int remotePort, - String targetAddr, int targetPort, - String originAddr, int originPort, - SSH2StreamFilterFactory filterFactory) - throws IOException - { - Socket fwdSocket = new Socket(targetAddr, targetPort); - - int ch = 0; - for(ch = 0; ch < SSH2Connection.channelTypes.length; ch++) { - if(SSH2Connection.channelTypes[ch].equals(channelType)) - break; - } - if(ch == SSH2Connection.channelTypes.length) { - throw new IOException("Invalid channelType: " + channelType); - } - - connection.getPreferences().setSocketOptions(ch, fwdSocket); - - SSH2TCPChannel channel = new SSH2TCPChannel(ch, connection, this, - fwdSocket, - remoteAddr, remotePort, - originAddr, originPort); - - channel.init(peerChanId, txInitWinSz, txMaxPktSz); - - if(filterFactory != null) { - channel.applyFilter(filterFactory.createFilter(connection, - channel)); - } - - // MUST send confirmation BEFORE starting streams - // - sendOpenConfirmation(channel); - - channel.startStreams(); - - return channel; - } - - private void sendOpenConfirmation(SSH2Channel channel) { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_CHANNEL_OPEN_CONFIRMATION); - pdu.writeInt(channel.peerChanId); - pdu.writeInt(channel.channelId); - pdu.writeInt(channel.rxInitWinSz); - pdu.writeInt(channel.rxMaxPktSz); - connection.transmit(pdu); - } - - private void sendOpenFailure(int peerChanId, - int reason, String description) { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_CHANNEL_OPEN_FAILURE); - pdu.writeInt(peerChanId); - pdu.writeInt(reason); - - if(!connection.getTransport().incompatibleChannelOpenFail) { - pdu.writeString(description); - pdu.writeString(""); // !!! TODO: Language tags again... - } - - connection.transmit(pdu); - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2ConsoleRemote.java b/src/main/java/com/mindbright/ssh2/SSH2ConsoleRemote.java deleted file mode 100644 index 903d81f..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2ConsoleRemote.java +++ /dev/null @@ -1,127 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.File; - -import com.mindbright.sshcommon.SSHConsoleRemote; - -/** - * This class implements a console to a remote command or shell. The underlying - * mechanism is a session channel which is created on demand from the provided - * connection layer. It can be used to execute single commands and/or control - * input/output to/from a shell. It is for example extended to control an SCP1 - * client in the class SSH2SCP1Client. - *

- * To create a SSH2ConsoleRemote instance a complete connected ssh2 - * stack is needed from which one provides the SSH2Connection to - * the constructor. - * - * @see SSH2Connection - * @see SSH2SimpleClient - */ -public class SSH2ConsoleRemote implements SSHConsoleRemote { - - protected SSH2Connection connection; - protected SSH2SessionChannel session; - protected OutputStream stderr; - - /** - * Basic constrctor. - * - * @param connection connected connection layer - */ - public SSH2ConsoleRemote(SSH2Connection connection) { - this(connection, null); - } - - /** - * Constrctor which takes an extra argument for specifying a stderr stream. - * - * @param connection connected connection layer - * @param stderr output stream where stder should be sent - */ - public SSH2ConsoleRemote(SSH2Connection connection, OutputStream stderr) { - this.connection = connection; - this.stderr = stderr; - } - - /** - * Runs single command on server. - * - * @param command command line to run - * - * @return a boolean indicating success or failure - */ - public boolean command(String command) { - session = connection.newSession(); - if(stderr != null) { - session.changeStdErr(stderr); - } - return session.doSingleCommand(command); - } - - /** - * Starts an interactive shell on the server - * - * @return a boolean indicating success or failure - */ - public boolean connect() { - session = connection.newSession(); - return session.doShell(); - } - - /** - * Closes the session channel. - */ - public void close() { - session.close(); - session = null; - } - - /** - * Changes the output stream where stdout is written to in the underlying - * session channel. - * - * @param out new stdout stream - */ - public void changeStdOut(OutputStream out) { - session.changeStdOut(out); - } - - /** - * Gets the stdout stream of the underlying session channel. Note, this is - * an input stream since one wants to read from stdout. - * - * @return the input stream of stdout stream - */ - public InputStream getStdOut() { - return session.getStdOut(); - } - - /** - * Gets the stdin stream of the underlying session channel. Note, this is - * an output stream since one wants to write to stdin. - * - * @return the input stream of stdout stream - */ - public OutputStream getStdIn() { - return session.getStdIn(); - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2CorruptPacketException.java b/src/main/java/com/mindbright/ssh2/SSH2CorruptPacketException.java deleted file mode 100644 index a8a1d64..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2CorruptPacketException.java +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public class SSH2CorruptPacketException extends SSH2FatalException { - - public SSH2CorruptPacketException(String message) { - super(message, null); - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2DSS.java b/src/main/java/com/mindbright/ssh2/SSH2DSS.java deleted file mode 100644 index 059aa6b..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2DSS.java +++ /dev/null @@ -1,83 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.math.BigInteger; - -import com.mindbright.jca.security.KeyFactory; -import com.mindbright.jca.security.PublicKey; -import com.mindbright.jca.security.spec.DSAPublicKeySpec; -import com.mindbright.jca.security.interfaces.DSAPublicKey; -import com.mindbright.jca.security.interfaces.DSAParams; - -public final class SSH2DSS extends SSH2SimpleSignature { - public final static String SSH2_KEY_FORMAT = "ssh-dss"; - - public SSH2DSS() { - super("SHA1withDSA", SSH2_KEY_FORMAT); - } - - public byte[] encodePublicKey(PublicKey publicKey) throws SSH2Exception { - SSH2DataBuffer buf = new SSH2DataBuffer(8192); - - if(!(publicKey instanceof DSAPublicKey)) { - throw new SSH2FatalException("SSH2DSS, invalid public key type: " + - publicKey); - } - - DSAPublicKey dsaPubKey = (DSAPublicKey)publicKey; - DSAParams dsaParams = dsaPubKey.getParams(); - - buf.writeString(SSH2_KEY_FORMAT); - buf.writeBigInt(dsaParams.getP()); - buf.writeBigInt(dsaParams.getQ()); - buf.writeBigInt(dsaParams.getG()); - buf.writeBigInt(dsaPubKey.getY()); - - return buf.readRestRaw(); - } - - public PublicKey decodePublicKey(byte[] pubKeyBlob) throws SSH2Exception { - BigInteger p, q, g, y; - SSH2DataBuffer buf = new SSH2DataBuffer(pubKeyBlob.length); - - buf.writeRaw(pubKeyBlob); - - String type = buf.readJavaString(); - if(!type.equals(SSH2_KEY_FORMAT)) { - throw new SSH2FatalException("SSH2DSS, keyblob type mismatch, got '" - + type + ", (execpted + '" + - SSH2_KEY_FORMAT + "')"); - } - - p = buf.readBigInt(); - q = buf.readBigInt(); - g = buf.readBigInt(); - y = buf.readBigInt(); - - try { - KeyFactory dsaKeyFact = KeyFactory.getInstance("DSA"); - DSAPublicKeySpec dsaPubSpec = new DSAPublicKeySpec(y, p, q, g); - - return dsaKeyFact.generatePublic(dsaPubSpec); - - } catch (Exception e) { - throw new SSH2FatalException("SSH2DSS, error decoding public key blob: " + - e); - } - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2DataBuffer.java b/src/main/java/com/mindbright/ssh2/SSH2DataBuffer.java deleted file mode 100644 index 532a23d..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2DataBuffer.java +++ /dev/null @@ -1,214 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.math.BigInteger; - -/** - * This class implements a read/write buffer with all protocol specific - * formatting (as defined in the architecture spec.). It is mainly used in the - * form of a protocol data unit (derived class SSH2TransportPDU). - */ -public class SSH2DataBuffer { - public final static int BOOLEAN_TRUE = 1; - public final static int BOOLEAN_FALSE = 0; - - protected byte[] data; - protected int rPos; - protected int wPos; - - protected SSH2DataBuffer() { - this(0); - } - - public SSH2DataBuffer(int bufSize) { - this.data = new byte[bufSize]; - reset(); - } - - public final void reset() { - this.rPos = 0; - this.wPos = 0; - } - - public final byte[] getData() { - return data; - } - - public final void setData(byte[] data) { - this.data = data; - } - - public final void setWPos(int wPos) { - this.wPos = wPos; - } - - public final int getWPos() { - return wPos; - } - - public final void setRPos(int rPos) { - this.rPos = rPos; - } - - public final int getRPos() { - return rPos; - } - - public final int getMaxReadSize() { - return wPos - rPos; - } - - public final int getMaxWriteSize() { - return data.length - wPos; - } - - public final int readByte() { - return ((int)data[rPos++]) & 0xff; - } - - public final void writeByte(int b) { - data[wPos++] = (byte)b; - } - - public final boolean readBoolean() { - if(readByte() != BOOLEAN_FALSE) - return true; - return false; - } - - public final void writeBoolean(boolean b) { - if(b) { - writeByte(BOOLEAN_TRUE); - } else { - writeByte(BOOLEAN_FALSE); - } - } - - public final int readInt() { - int b1 = readByte(); - int b2 = readByte(); - int b3 = readByte(); - int b4 = readByte(); - return ((b1 << 24) + (b2 << 16) + (b3 << 8) + (b4 << 0)); - } - - public final void writeInt(int i) { - writeByte((i >>> 24) & 0xFF); - writeByte((i >>> 16) & 0xFF); - writeByte((i >>> 8) & 0xFF); - writeByte((i >>> 0) & 0xFF); - } - - public final BigInteger readBigInt() { - byte[] raw = readString(); - if(raw.length > 0) - return new BigInteger(raw); - return BigInteger.valueOf(0); - } - - public final BigInteger readBigIntBits() { - int bits = readInt(); - byte[] raw = new byte[(bits + 7) / 8 + 1]; - - raw[0] = 0; - readRaw(raw, 1, raw.length - 1); - return new BigInteger(raw); - } - - public final void writeBigInt(BigInteger bi) { - byte[] raw = bi.toByteArray(); - if(raw.length == 1 && raw[0] == (byte)0x00) - raw = new byte[0]; - writeString(raw); - } - - public final void writeBigIntBits(BigInteger bi) { - int bytes = ((bi.bitLength() + 7) / 8); - byte[] raw = bi.toByteArray(); - if(raw.length == 1 && raw[0] == (byte)0x00) { - writeInt(0); - return; - } - writeInt(bi.bitLength()); - if(raw[0] == 0) { - writeRaw(raw, 1, bytes); - } else { - writeRaw(raw, 0, bytes); - } - } - - public final String readJavaString() { - return new String(readString()); - } - - public final byte[] readString() { - int len = readInt(); - if(len < 0 || len > (data.length - rPos)) { - throw new Error("Error in SSH2DataBuffer, corrupt string on read"); - } - byte[] str = new byte[len]; - System.arraycopy(data, rPos, str, 0, len); - rPos += len; - return str; - } - - public final int readString(byte[] str, int off) { - int len = readInt(); - System.arraycopy(data, rPos, str, off, len); - rPos += len; - return len; - } - - public final void writeString(String str) { - writeString(str.getBytes()); - } - - public final void writeString(byte[] str) { - writeString(str, 0, str.length); - } - - public final void writeString(byte[] str, int off, int len) { - writeInt(len); - System.arraycopy(str, off, data, wPos, len); - wPos += len; - } - - public final byte[] readRestRaw() { - return readRaw(wPos - rPos); - } - - public final byte[] readRaw(int len) { - byte[] raw = new byte[len]; - readRaw(raw, 0, len); - return raw; - } - - public final void readRaw(byte[] raw, int off, int len) { - System.arraycopy(data, rPos, raw, off, len); - rPos += len; - } - - public final void writeRaw(byte[] raw) { - writeRaw(raw, 0, raw.length); - } - - public final void writeRaw(byte[] raw, int off, int len) { - System.arraycopy(raw, off, data, wPos, len); - wPos += len; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2EOFException.java b/src/main/java/com/mindbright/ssh2/SSH2EOFException.java deleted file mode 100644 index 92bf97e..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2EOFException.java +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public class SSH2EOFException extends SSH2Exception { - - public SSH2EOFException(String message) { - super(message, null); - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2Exception.java b/src/main/java/com/mindbright/ssh2/SSH2Exception.java deleted file mode 100644 index 68eb083..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2Exception.java +++ /dev/null @@ -1,36 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public abstract class SSH2Exception extends Exception { - - protected Throwable rootCause; - - public SSH2Exception(String message) { - this(message, null); - } - - public SSH2Exception(String message, Throwable rootCause) { - super(message); - this.rootCause = rootCause; - } - - public Throwable getRootCause() { - return rootCause; - } - -} - diff --git a/src/main/java/com/mindbright/ssh2/SSH2FTPOverSFTP.java b/src/main/java/com/mindbright/ssh2/SSH2FTPOverSFTP.java deleted file mode 100644 index 8f77f3a..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2FTPOverSFTP.java +++ /dev/null @@ -1,315 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.IOException; - -import com.mindbright.net.ftp.FTPServer; -import com.mindbright.net.ftp.FTPServerEventHandler; -import com.mindbright.net.ftp.FTPException; - -public class SSH2FTPOverSFTP implements FTPServerEventHandler { - - private SSH2Connection connection; - private SSH2SFTPClient sftp; - private FTPServer ftp; - private String remoteDir; - private String renameFrom; - private String user; - - private SSH2SFTP.FileAttributes attrs; - - public SSH2FTPOverSFTP(SSH2Connection connection, - InputStream ftpInput, OutputStream ftpOutput, - String identity) - throws SSH2SFTP.SFTPException - { - this.connection = connection; - this.attrs = null; - try { - this.sftp = new SSH2SFTPClient(connection, false); - } catch (SSH2SFTP.SFTPException e) { - try { ftpOutput.close(); } - catch (IOException ee) { /* don't care */ } - try { ftpInput.close(); } - catch (IOException ee) { /* don't care */ } - throw e; - } - this.ftp = new FTPServer(identity, this, ftpInput, ftpOutput, - false); - } - - public boolean login(String user, String pass) { - connection.getLog().info("SSH2FTPOverSFTP", "user " + user + " login"); - try { - attrs = sftp.realpath("."); - } catch (SSH2SFTP.SFTPException e) { - // !!! TODO, should disconnect ??? - return false; - } - remoteDir = attrs.lname; - this.user = user; - return true; - } - - public void quit() { - connection.getLog().info("SSH2FTPOverSFTP", "user " + user + " logout"); - sftp.terminate(); - } - - public boolean isPlainFile(String file) { - try { - file = expandRemote(file); - attrs = sftp.lstat(file); - return attrs.isFile(); - } catch (SSH2SFTP.SFTPException e) { - return false; - } - } - - public void changeDirectory(String dir) throws FTPException { - if(dir != null) { - String newDir = expandRemote(dir); - try { - attrs = sftp.realpath(newDir); - } catch (SSH2SFTP.SFTPException e) { - throw new FTPException(550, - dir + ": No such directory."); - } - newDir = attrs.lname; - try { - SSH2SFTP.FileHandle f = sftp.opendir(newDir); - sftp.close(f); - } catch (SSH2SFTP.SFTPException e) { - throw new FTPException(550, dir + ": Not a directory."); - } - remoteDir = newDir; - } - } - - public void renameFrom(String from) throws FTPException { - try { - String fPath = expandRemote(from); - attrs = sftp.lstat(fPath); - renameFrom = fPath; - } catch (SSH2SFTP.SFTPException e) { - throw new FTPException(550, from + ": No such file or directory."); - } - } - - public void renameTo(String to) throws FTPException { - if(renameFrom != null) { - try { - sftp.rename(renameFrom, expandRemote(to)); - } catch (SSH2SFTP.SFTPException e) { - throw new FTPException(550, "rename: Operation failed."); - } finally { - renameFrom = null; - } - } else { - throw new FTPException(503, "Bad sequence of commands."); - } - } - - public void delete(String file) throws FTPException { - try { - sftp.remove(expandRemote(file)); - } catch (SSH2SFTP.SFTPException e) { - String msg = (e instanceof SSH2SFTP.SFTPPermissionDeniedException) ? - "access denied." : file + ": no such file."; - throw new FTPException(550, msg); - } - } - - public void rmdir(String dir) throws FTPException { - try { - sftp.rmdir(expandRemote(dir)); - } catch (SSH2SFTP.SFTPException e) { - String msg = (e instanceof SSH2SFTP.SFTPPermissionDeniedException) ? - "access denied." : dir + ": no such directory."; - throw new FTPException(550, msg); - } - } - - public void mkdir(String dir) throws FTPException { - try { - sftp.mkdir(expandRemote(dir), new SSH2SFTP.FileAttributes()); - } catch (SSH2SFTP.SFTPException e) { - - } - } - - public String pwd() { - return remoteDir; - } - - public String system() { - return "UNIX Type: L8"; - } - - public long modTime(String file) throws FTPException { - return (timeAndSize(file))[0]; - } - - public long size(String file) throws FTPException { - return (timeAndSize(file))[1]; - } - - private long[] timeAndSize(String file) throws FTPException { - try { - long[] ts = new long[2]; - String fPath = expandRemote(file); - attrs = sftp.lstat(fPath); - if(!attrs.hasSize || !attrs.hasModTime) { - throw new FTPException(550, - "SFTP server don't return time/size."); - } - ts[0] = attrs.mtime * 1000L; - ts[1] = attrs.size; - return ts; - } catch (SSH2SFTP.SFTPException e) { - throw new FTPException(550, file + ": No such file or directory."); - } - } - - public void store(String file, InputStream data, boolean binary) - throws FTPException - { - SSH2SFTP.FileHandle handle = null; - try { - file = expandRemote(file); - handle = sftp.open(file, SSH2SFTP.SSH_FXF_WRITE | - SSH2SFTP.SSH_FXF_TRUNC | - SSH2SFTP.SSH_FXF_CREAT, - new SSH2SFTP.FileAttributes()); - - sftp.writeFully(handle, data); - - } catch (IOException e) { - throw new FTPException(425, "Error writing to data connection: " + - e.getMessage()); - } catch (SSH2SFTP.SFTPPermissionDeniedException e) { - throw new FTPException(553, file + ": Permission denied."); - } catch (SSH2SFTP.SFTPException e) { - throw new FTPException(550, file + ": Error in sftp connection, " + - e.getMessage()); - } finally { - try { data.close(); } catch (Exception e) { /* don't care */ } - } - } - - public void retrieve(String file, OutputStream data, boolean binary) - throws FTPException - { - SSH2SFTP.FileHandle handle = null; - try { - String eFile = expandRemote(file); - handle = sftp.open(eFile, SSH2SFTP.SSH_FXF_READ, - new SSH2SFTP.FileAttributes()); - sftp.readFully(handle, data); - - } catch (SSH2SFTP.SFTPNoSuchFileException e) { - throw new FTPException(550, file + ": No such file or directory."); - } catch (SSH2SFTP.SFTPException e) { - throw new FTPException(550, file + ": Error in sftp connection, " + - e.getMessage()); - } catch (IOException e) { - throw new FTPException(550, file + ": Error in sftp connection, " + - e.getMessage()); - } finally { - try { data.close(); } catch (Exception e) { /* don't care */ } - } - } - - public void list(String path, OutputStream data) throws FTPException { - try { - SSH2SFTP.FileAttributes[] list = dirList(path); - for(int i = 0; i < list.length; i++) { - if(".".equals(list[i].name) || "..".equals(list[i].name)) { - continue; - } - String row = list[i].lname; - if(row.endsWith("/")) { - row = row.substring(0, row.length() - 1); - } - row += "\r\n"; - data.write(row.getBytes()); - } - } catch (IOException e) { - throw new FTPException(425, "Error writing to data connection: " + - e.getMessage()); - } - } - - public void nameList(String path, OutputStream data) throws FTPException { - // !!! TODO some *-expansion maybe - try { - SSH2SFTP.FileAttributes[] list = dirList(path); - for(int i = 0; i < list.length; i++) { - if(".".equals(list[i].name) || "..".equals(list[i].name)) { - continue; - } - String row = list[i].name + "\r\n"; - data.write(row.getBytes()); - } - } catch (IOException e) { - throw new FTPException(425, "Error writing to data connection: " + - e.getMessage()); - } - } - - private SSH2SFTP.FileAttributes[] dirList(String path) throws FTPException { - SSH2SFTP.FileHandle handle = null; - SSH2SFTP.FileAttributes[] list = new SSH2SFTP.FileAttributes[0]; - - try { - String fPath = expandRemote(path); - attrs = sftp.lstat(fPath); - if(attrs.isDirectory()) { - handle = sftp.opendir(fPath); - list = sftp.readdir(handle); - return list; - } else { - list = new SSH2SFTP.FileAttributes[1]; - attrs.name = path; - attrs.lname = attrs.toString(path); - } - } catch (SSH2SFTP.SFTPException e) { - throw new FTPException(550, path + ": Not a directory."); - } finally { - try { if(handle != null) sftp.close(handle); } - catch (Exception e) { /* don't care */ } - } - - return list; - } - - public void abort() { - // !!! TODO !!! - } - - private String expandRemote(String name) { - if(name == null || name.length() == 0) { - return remoteDir; - } - if(name.charAt(0) != '/') - name = remoteDir + "/" + name; - return name; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2FTPProxyFilter.java b/src/main/java/com/mindbright/ssh2/SSH2FTPProxyFilter.java deleted file mode 100644 index 4b5d096..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2FTPProxyFilter.java +++ /dev/null @@ -1,254 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.FilterInputStream; -import java.io.FilterOutputStream; -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Random; - -public class SSH2FTPProxyFilter implements SSH2StreamFilter, - SSH2StreamFilterFactory -{ - class FTPInput extends FilterInputStream { - - Random portRandomizer; - int lastBoundPort; - - public FTPInput(InputStream toBeFiltered) { - super(toBeFiltered); - portRandomizer = new Random(); - lastBoundPort = -1; - } - - public int read(byte b[], int off, int len) throws IOException { - len = in.read(b, off, len); - if(len < 0) { - return len; - } - String msg = new String(b, off, len); - - if(msg.startsWith("PASV") || msg.startsWith("pasv")) { - waitingPASVResponse = true; - } else if(msg.startsWith("PORT ") || msg.startsWith("port ")) { - msg = msg.substring(5); - int[] d = new int[6]; - if(parseHostAndPort(msg, d)) { - String toHost = d[0] + "." + d[1] + "." + d[2] + "." + d[3]; - int toPort = (d[4] << 8) | d[5]; - - if(lastBoundPort > 0) { - connection.deleteRemoteForward(serverLocalAddr, - lastBoundPort); - } - - int port = 0; - boolean success = false; - while(!success) { - port = Math.abs(portRandomizer.nextInt()); - port %= (65536 - 1024); - port += 1024; - success = - connection.newRemoteForwardBlocking(serverLocalAddr, - port, - toHost, toPort, - null); - } - lastBoundPort = port; - - int p1 = (port >>> 8) & 0xff; - int p2 = port & 0xff; - - msg = "PORT " + 127 + "," + 0 + "," + 0 + "," + 1 + "," + - p1 + "," + p2 + "\n"; - byte[] newmsg = msg.getBytes(); - len = newmsg.length; - System.arraycopy(newmsg, 0, b, off, len); - } else { - connection.getLog().warning("SSH2FTPProxyFilter", - "error in FTP proxy filter (port) for: " + - msg); - } - } - return len; - } - - } - - class FTPOutput extends FilterOutputStream { - - public FTPOutput(OutputStream toBeFiltered) { - super(toBeFiltered); - } - - public void write(byte b[], int off, int len) throws IOException { - SSH2Listener listener = null; - String msg = new String(b, off, len); - - if(waitingPASVResponse && msg.startsWith("227 ")) { - byte[] newmsg; - waitingPASVResponse = false; - msg = msg.substring(27); - int[] d = new int[6]; - if(parseHostAndPort(msg, d)) { - String toHost = d[0] + "." + d[1] + "." + d[2] + "." + d[3]; - int toPort = (d[4] << 8) | d[5]; - int localPort; - try { - listener = - connection.newLocalForward( - localHost.getHostAddress(), - 0, toHost, toPort); - // !!! TODO should have a blocking listener.ready() - Thread.sleep(250); - } catch(InterruptedException e) { - connection.getLog().warning("SSH2FTPProxyFilter", - "interrupted in FTP proxy filter: " + - e.toString()); - listener = null; - } catch(IOException e) { - connection.getLog().warning("SSH2FTPProxyFilter", - "error in FTP proxy filter: " + - e.toString()); - listener = null; - } - if(listener != null) { - listener.setAcceptMax(1); // Go away after next accept... - localPort = listener.getListenPort(); - int p1 = (localPort >>> 8) & 0xff; - int p2 = localPort & 0xff; - msg = "227 Entering Passive Mode (" + - localAddrPASVStr + "," + p1 + "," + p2 + ")\n"; - newmsg = msg.getBytes(); - out.write(newmsg, 0, newmsg.length); - } - } else { - connection.getLog().warning("SSH2FTPProxyFilter", - "error in FTP proxy filter (pasv) for: " + - msg); - } - } else { - out.write(b, off, len); - } - } - - } - - private boolean parseHostAndPort(String msg, int[] d) { - boolean ok = true; - int cl = 0; - int cn = 0; - try { - for(int i = 0; i < 6; i++) { - String num; - if(i == 5) { - cn = msg.indexOf(')', cl); - if(cn == -1) - cn = msg.indexOf('\r', cl); - else if(cn == -1) - cn = msg.indexOf('\n', cl); - } else - cn = msg.indexOf(',', cl); - num = msg.substring(cl, cn); - cl = cn + 1; - d[i] = Integer.parseInt(num); - } - } catch (Exception e) { - ok = false; - } - return ok; - } - - private String localAddrPASVStr; - private String serverLocalAddr; - private InetAddress localHost; - - public SSH2FTPProxyFilter(String localHost) throws UnknownHostException { - // - // Factory instance constructor - // - this(InetAddress.getByName(localHost)); - } - - public SSH2FTPProxyFilter(InetAddress localHost) { - // - // Factory instance constructor - // - byte[] localAddrArr = null; - - this.localHost = localHost; - localAddrArr = localHost.getAddress(); - - // !!! TODO: want to be able to get actual connected adress - // i.e. through call to our stream ("instanceof TCP") - if((localAddrArr[0] & 0xff) == 0) { - try { - localAddrArr = InetAddress.getLocalHost().getAddress(); - } catch (UnknownHostException e) { - throw new Error("Error in SSH2FTPProxyFilter: " + e); - } - } - - int a1 = localAddrArr[0] & 0xff; - int a2 = localAddrArr[1] & 0xff; - int a3 = localAddrArr[2] & 0xff; - int a4 = localAddrArr[3] & 0xff; - localAddrPASVStr = a1 + "," + a2 + "," + a3 + "," + a4; - - // !!! TODO: want to be able to set this !!! - serverLocalAddr = "0.0.0.0"; - } - - protected SSH2Connection connection; - protected SSH2StreamChannel channel; - protected FTPInput ftpIn; - protected FTPOutput ftpOut; - - protected volatile boolean waitingPASVResponse; - - protected SSH2FTPProxyFilter(SSH2Connection connection, - SSH2StreamChannel channel, - SSH2FTPProxyFilter factory) { - this.connection = connection; - this.channel = channel; - - this.localAddrPASVStr = factory.localAddrPASVStr; - this.serverLocalAddr = factory.serverLocalAddr; - this.localHost = factory.localHost; - - this.waitingPASVResponse = false; - } - - public SSH2StreamFilter createFilter(SSH2Connection connection, - SSH2StreamChannel channel) { - return new SSH2FTPProxyFilter(connection, channel, this); - } - - public InputStream getInputFilter(InputStream toBeFiltered) { - this.ftpIn = new FTPInput(toBeFiltered); - return this.ftpIn; - } - - public OutputStream getOutputFilter(OutputStream toBeFiltered) { - this.ftpOut = new FTPOutput(toBeFiltered); - return this.ftpOut; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2FatalException.java b/src/main/java/com/mindbright/ssh2/SSH2FatalException.java deleted file mode 100644 index 83933f1..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2FatalException.java +++ /dev/null @@ -1,28 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public class SSH2FatalException extends SSH2Exception { - - public SSH2FatalException(String message) { - this(message, null); - } - - public SSH2FatalException(String message, Throwable rootCause) { - super(message, rootCause); - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2Interactor.java b/src/main/java/com/mindbright/ssh2/SSH2Interactor.java deleted file mode 100644 index 4604e49..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2Interactor.java +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -/** - * This interface defines the different types of prompts which are needed for - * interactive authentication. It's made generic to be able to allow flexibility - * in the level of sofistication one wants for user interaction. - */ -public interface SSH2Interactor { - public String promptLine(String prompt, boolean echo) - throws SSH2UserCancelException; - public String[] promptMulti(String[] prompts, boolean[] echos) - throws SSH2UserCancelException; - public String[] promptMultiFull(String name, String instruction, - String[] prompts, boolean[] echos) - throws SSH2UserCancelException; - public int promptList(String name, String instruction, String[] choices) - throws SSH2UserCancelException; -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2KEXDHGroup1SHA1.java b/src/main/java/com/mindbright/ssh2/SSH2KEXDHGroup1SHA1.java deleted file mode 100644 index cee83b8..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2KEXDHGroup1SHA1.java +++ /dev/null @@ -1,205 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.math.BigInteger; - -import com.mindbright.jca.security.MessageDigest; -import com.mindbright.jca.security.KeyFactory; -import com.mindbright.jca.security.KeyPair; -import com.mindbright.jca.security.KeyPairGenerator; - -import javax.crypto.KeyAgreement; -import javax.crypto.interfaces.DHPublicKey; -import javax.crypto.interfaces.DHPrivateKey; -import javax.crypto.spec.DHParameterSpec; -import javax.crypto.spec.DHPublicKeySpec; - -public class SSH2KEXDHGroup1SHA1 extends SSH2KeyExchanger { - - public final static BigInteger group1P = - com.mindbright.security.publickey.ModPGroups.oakleyGroup2P; - - public final static BigInteger group1G = - com.mindbright.security.publickey.ModPGroups.oakleyGroup2G; - - protected SSH2Transport transport; - protected DHPublicKey dhPublicKey; - protected DHPrivateKey dhPrivateKey; - protected byte[] serverHostKey; - protected BigInteger serverF; - protected BigInteger clientE; - protected byte[] sharedSecret_K; - protected byte[] exchangeHash_H; - protected MessageDigest sha1; - - public void init(SSH2Transport transport) throws SSH2Exception { - this.transport = transport; - this.sha1 = createHash(); - - DHParameterSpec group1Params = new DHParameterSpec(group1P, group1G); - generateDHKeyPair(group1Params); - - if(!transport.isServer()) { - sendDHINIT(SSH2.MSG_KEXDH_INIT); - } - } - - public void processKEXMethodPDU(SSH2TransportPDU pdu) throws SSH2Exception { - if(pdu.getType() == SSH2.MSG_KEXDH_REPLY) { - if(transport.isServer()) { - throw new SSH2KEXFailedException("Unexpected KEXDH_REPLY"); - } - - serverHostKey = pdu.readString(); - serverF = pdu.readBigInt(); - byte[] serverSigH = pdu.readString(); - - DHPublicKeySpec srvPubSpec = new DHPublicKeySpec(serverF, - group1P, group1G); - - computeSharedSecret_K(srvPubSpec); - computeExchangeHash_H(); - - transport.authenticateHost(serverHostKey, serverSigH, - exchangeHash_H); - - transport.sendNewKeys(); - - } else if(pdu.getType() == SSH2.MSG_KEXDH_INIT) { - // !!! TODO SERVER - } - } - - public MessageDigest getExchangeHashAlgorithm() { - sha1.reset(); - return sha1; - } - - public byte[] getSharedSecret_K() { - SSH2DataBuffer buf = new SSH2DataBuffer(1024); - buf.writeString(sharedSecret_K); - return buf.readRestRaw(); - } - - public byte[] getExchangeHash_H() { - return exchangeHash_H; - } - - public String getHostKeyAlgorithms() { - return "ssh-dss,ssh-rsa"; - } - - protected void computeExchangeHash_H() { - SSH2DataBuffer buf = new SSH2DataBuffer(4096); - - if(transport.isServer()) { - serverF = dhPublicKey.getY(); - } else { - clientE = dhPublicKey.getY(); - } - - buf.writeString(transport.getClientVersion()); - buf.writeString(transport.getServerVersion()); - buf.writeString(transport.getClientKEXINITPDU().getData(), - transport.getClientKEXINITPDU().getPayloadOffset(), - transport.getClientKEXINITPDU().getPayloadLength()); - buf.writeString(transport.getServerKEXINITPDU().getData(), - transport.getServerKEXINITPDU().getPayloadOffset(), - transport.getServerKEXINITPDU().getPayloadLength()); - buf.writeString(serverHostKey); - buf.writeBigInt(clientE); - buf.writeBigInt(serverF); - buf.writeString(sharedSecret_K); - - sha1.reset(); - sha1.update(buf.getData(), 0, buf.getWPos()); - exchangeHash_H = sha1.digest(); - - transport.getLog().debug2("SSH2KEXDHGroup1SHA1", - "computeExchangeHash_H", "E: ", - clientE.toByteArray()); - transport.getLog().debug2("SSH2KEXDHGroup1SHA1", - "computeExchangeHash_H", "F: ", - serverF.toByteArray()); - transport.getLog().debug2("SSH2KEXDHGroup1SHA1", - "computeExchangeHash_H", "K: ", - sharedSecret_K); - transport.getLog().debug2("SSH2KEXDHGroup1SHA1", - "computeExchangeHash_H", "Hash over: ", - buf.getData(), 0, buf.getWPos()); - transport.getLog().debug2("SSH2KEXDHGroup1SHA1", - "computeExchangeHash_H", "H: ", - exchangeHash_H); - } - - protected void computeSharedSecret_K(DHPublicKeySpec peerPubSpec) - throws SSH2Exception - { - try { - KeyFactory dhKeyFact = KeyFactory.getInstance("DH"); - KeyAgreement dhKEX = KeyAgreement.getInstance("DH"); - - DHPublicKey peerPubKey = - (DHPublicKey)dhKeyFact.generatePublic(peerPubSpec); - - dhKEX.init(dhPrivateKey); - dhKEX.doPhase(peerPubKey, true); - - sharedSecret_K = dhKEX.generateSecret(); - } catch (Exception e) { - - e.printStackTrace(); - - throw new SSH2FatalException("Error computing shared secret: " - + e); - } - } - - protected void sendDHINIT(int type) throws SSH2Exception { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(type); - - pdu.writeBigInt(dhPublicKey.getY()); - - transport.transmitInternal(pdu); - } - - protected MessageDigest createHash() throws SSH2Exception { - try { - return MessageDigest.getInstance("SHA1"); - } catch (Exception e) { - throw new SSH2KEXFailedException("SHA1 not implemented", e); - } - } - - protected void generateDHKeyPair(DHParameterSpec dhParams) throws SSH2Exception { - try { - KeyPairGenerator dhKeyPairGen = KeyPairGenerator.getInstance("DH"); - - dhKeyPairGen.initialize(dhParams, transport.getSecureRandom()); - - KeyPair dhKeyPair = dhKeyPairGen.generateKeyPair(); - - dhPrivateKey = (DHPrivateKey)dhKeyPair.getPrivate(); - dhPublicKey = (DHPublicKey)dhKeyPair.getPublic(); - } catch (Exception e) { - throw new SSH2FatalException("Error generating DiffieHellman keys: " - + e); - } - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2KEXDHGroupXSHA1.java b/src/main/java/com/mindbright/ssh2/SSH2KEXDHGroupXSHA1.java deleted file mode 100644 index 2d2b313..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2KEXDHGroupXSHA1.java +++ /dev/null @@ -1,161 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.math.BigInteger; - -import javax.crypto.spec.DHParameterSpec; -import javax.crypto.spec.DHPublicKeySpec; - -public class SSH2KEXDHGroupXSHA1 extends SSH2KEXDHGroup1SHA1 { - - private int reqBits; - private BigInteger p; - private BigInteger g; - - public void init(SSH2Transport transport) throws SSH2Exception { - this.transport = transport; - this.sha1 = createHash(); - if(!transport.isServer()) { - sendGEXRequest(); - } - } - - public void processKEXMethodPDU(SSH2TransportPDU pdu) throws SSH2Exception { - switch(pdu.getType()) { - case SSH2.MSG_KEXDH_GEX_REQUEST: - // !!! TODO - break; - - case SSH2.MSG_KEXDH_GEX_GROUP: - if(transport.isServer()) { - throw new SSH2KEXFailedException("Unexpected KEXDH_GEX_GROUP"); - } - p = pdu.readBigInt(); - g = pdu.readBigInt(); - - DHParameterSpec dhParams = new DHParameterSpec(p, g); - generateDHKeyPair(dhParams); - - sendDHINIT(SSH2.MSG_KEXDH_GEX_INIT); - break; - - case SSH2.MSG_KEXDH_GEX_INIT: - // !!! TODO - break; - - case SSH2.MSG_KEXDH_GEX_REPLY: - if(transport.isServer()) { - throw new SSH2KEXFailedException("Unexpected KEXDH_GEX_REPLY"); - } - serverHostKey = pdu.readString(); - serverF = pdu.readBigInt(); - byte[] serverSigH = pdu.readString(); - - DHPublicKeySpec srvPubSpec = new DHPublicKeySpec(serverF, p, g); - - computeSharedSecret_K(srvPubSpec); - computeExchangeHash_H(); - - transport.authenticateHost(serverHostKey, serverSigH, - exchangeHash_H); - - transport.sendNewKeys(); - break; - } - } - - protected void computeExchangeHash_H() { - SSH2DataBuffer buf = new SSH2DataBuffer(8192); - - if(transport.isServer()) { - serverF = dhPublicKey.getY(); - } else { - clientE = dhPublicKey.getY(); - } - - buf.writeString(transport.getClientVersion()); - buf.writeString(transport.getServerVersion()); - buf.writeString(transport.getClientKEXINITPDU().getData(), - transport.getClientKEXINITPDU().getPayloadOffset(), - transport.getClientKEXINITPDU().getPayloadLength()); - buf.writeString(transport.getServerKEXINITPDU().getData(), - transport.getServerKEXINITPDU().getPayloadOffset(), - transport.getServerKEXINITPDU().getPayloadLength()); - buf.writeString(serverHostKey); - buf.writeInt(reqBits); - buf.writeBigInt(p); - buf.writeBigInt(g); - buf.writeBigInt(clientE); - buf.writeBigInt(serverF); - buf.writeString(sharedSecret_K); - - sha1.reset(); - sha1.update(buf.getData(), 0, buf.getWPos()); - exchangeHash_H = sha1.digest(); - - transport.getLog().debug2("SSH2KEXDHGroup1SHA1", - "computeExchangeHash_H", "E: ", - clientE.toByteArray()); - transport.getLog().debug2("SSH2KEXDHGroup1SHA1", - "computeExchangeHash_H", "F: ", - serverF.toByteArray()); - transport.getLog().debug2("SSH2KEXDHGroup1SHA1", - "computeExchangeHash_H", "K: ", - sharedSecret_K); - transport.getLog().debug2("SSH2KEXDHGroup1SHA1", - "computeExchangeHash_H", "Hash over: ", - buf.getData(), 0, buf.getWPos()); - transport.getLog().debug2("SSH2KEXDHGroup1SHA1", - "computeExchangeHash_H", "H: ", - exchangeHash_H); - } - - protected void sendGEXRequest() throws SSH2Exception { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_KEXDH_GEX_REQUEST); - - reqBits = estimateGroupBits(); - pdu.writeInt(reqBits); - - transport.transmitInternal(pdu); - } - - /* - * Estimates the group order for a Diffie-Hellman group that has an attack - * complexity approximately the same as O(2**bits) where bits is the longest - * of transmitter and receiver cipher keys. - * - * Estimate with: O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3))) - * - * (This code snippet is from OpenSSH2) - */ - private int estimateGroupBits() { - SSH2TransportPreferences pref = transport.getOurPreferences(); - int rKLen = pref.getCipherKeyLen(pref.getReceiverCipher()); - int tKLen = pref.getCipherKeyLen(pref.getTransmitterCipher()); - int bits = (rKLen > tKLen ? rKLen : tKLen) * 8; - - if (bits < 64) - return (512); /* O(2**63) */ - if (bits < 128) - return (1024); /* O(2**86) */ - if (bits < 192) - return (2048); /* O(2**116) */ - return (4096); /* O(2**156) */ - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2KEXFailedException.java b/src/main/java/com/mindbright/ssh2/SSH2KEXFailedException.java deleted file mode 100644 index b89c920..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2KEXFailedException.java +++ /dev/null @@ -1,25 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public class SSH2KEXFailedException extends SSH2Exception { - public SSH2KEXFailedException(String message) { - super(message); - } - public SSH2KEXFailedException(String message, Throwable rootCause) { - super(message, rootCause); - } -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2KeyExchanger.java b/src/main/java/com/mindbright/ssh2/SSH2KeyExchanger.java deleted file mode 100644 index f99df8f..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2KeyExchanger.java +++ /dev/null @@ -1,70 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.util.Hashtable; - -import com.mindbright.jca.security.MessageDigest; - -public abstract class SSH2KeyExchanger { - - private static Hashtable algorithms; - - static { - algorithms = new Hashtable(); - - algorithms.put("diffie-hellman-group1-sha1", - SSH2KEXDHGroup1SHA1.class); - algorithms.put("diffie-hellman-group-exchange-sha1", - SSH2KEXDHGroupXSHA1.class); - } - - protected SSH2KeyExchanger() { - } - - public static SSH2KeyExchanger getInstance(String algorithm) - throws SSH2KEXFailedException - { - Class alg = (Class)algorithms.get(algorithm); - SSH2KeyExchanger kex = null; - if(alg != null) { - try { - kex = (SSH2KeyExchanger)alg.newInstance(); - } catch (Throwable t) { - kex = null; - } - } - if(kex == null) { - throw new SSH2KEXFailedException("Unknown kex algorithm: " + - algorithm); - } - return kex; - } - - public abstract void init(SSH2Transport transport) throws SSH2Exception; - - public abstract void processKEXMethodPDU(SSH2TransportPDU pdu) - throws SSH2Exception; - - public abstract MessageDigest getExchangeHashAlgorithm(); - - public abstract byte[] getSharedSecret_K(); - - public abstract byte[] getExchangeHash_H(); - - public abstract String getHostKeyAlgorithms(); - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2KeyPairFile.java b/src/main/java/com/mindbright/ssh2/SSH2KeyPairFile.java deleted file mode 100644 index ea3b8f7..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2KeyPairFile.java +++ /dev/null @@ -1,820 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.PushbackInputStream; -import java.io.IOException; -import java.math.BigInteger; - -import com.mindbright.jca.security.KeyPair; -import com.mindbright.jca.security.PublicKey; -import com.mindbright.jca.security.PrivateKey; -import com.mindbright.jca.security.KeyFactory; -import com.mindbright.jca.security.MessageDigest; -import com.mindbright.jca.security.SecureRandom; -import com.mindbright.jca.security.InvalidKeyException; -import com.mindbright.jca.security.NoSuchAlgorithmException; -import com.mindbright.jca.security.interfaces.DSAParams; -import com.mindbright.jca.security.interfaces.DSAPublicKey; -import com.mindbright.jca.security.interfaces.RSAPublicKey; -import com.mindbright.jca.security.interfaces.DSAPrivateKey; -import com.mindbright.jca.security.interfaces.RSAPrivateCrtKey; -import com.mindbright.jca.security.spec.KeySpec; -import com.mindbright.jca.security.spec.DSAPublicKeySpec; -import com.mindbright.jca.security.spec.DSAPrivateKeySpec; -import com.mindbright.jca.security.spec.RSAPublicKeySpec; -import com.mindbright.jca.security.spec.RSAPrivateCrtKeySpec; - -import javax.crypto.Cipher; -import javax.crypto.spec.SecretKeySpec; -import javax.crypto.spec.IvParameterSpec; - -import com.mindbright.asn1.ASN1Object; -import com.mindbright.asn1.ASN1Sequence; -import com.mindbright.asn1.ASN1Integer; -import com.mindbright.asn1.ASN1DER; - -import com.mindbright.security.publickey.RSAAlgorithm; - -import com.mindbright.util.ASCIIArmour; -import com.mindbright.util.HexDump; - -/** - * This class implements the file formats commonly used for storing key pairs - * for public key authentication. It can handle both OpenSSH's PEM file format - * aswell as SSH Communications proprietary format for DSA keys. When - * importing/exporting use the appropriate constructor and the load/store - * methods. Note that this class can also be used to convert key pair files - * between the formats. - * - * @see SSH2PublicKeyFile - */ -public class SSH2KeyPairFile { - - private final static int TYPE_PEM_DSA = 0; - private final static int TYPE_PEM_RSA = 1; - private final static int TYPE_SSHCOM_DSA = 2; - - public final static String[] BEGIN_PRV_KEY = { - "-----BEGIN DSA PRIVATE KEY-----", - "-----BEGIN RSA PRIVATE KEY-----", - "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----" - }; - - public final static String[] END_PRV_KEY = { - "-----END DSA PRIVATE KEY-----", - "-----END RSA PRIVATE KEY-----", - "---- END SSH2 ENCRYPTED PRIVATE KEY ----" - }; - - public final static int SSH_PRIVATE_KEY_MAGIC = 0x3f6ff9eb; - - public final static String PRV_PROCTYPE = "Proc-Type"; - public final static String PRV_DEKINFO = "DEK-Info"; - - public final static String FILE_SUBJECT = "Subject"; - public final static String FILE_COMMENT = "Comment"; - - private KeyPair keyPair; - private ASCIIArmour armour; - private String subject; - private String comment; - private boolean sshComFormat; - - /** - * From OpenSSL doc for dsa. - *

- *

-     * PEMDSAPrivate ::= SEQUENCE {
-     *   version  Version,
-     *   p        INTEGER,
-     *   q        INTEGER,
-     *   g        INTEGER,
-     *   y        INTEGER,
-     *   x        INTEGER
-     * }
-     *
-     * Version ::= INTEGER { openssl(0) }
-     * 
- * (OpenSSL currently hardcodes version to 0) - */ - public static final class PEMDSAPrivate extends ASN1Sequence { - - public ASN1Integer version; - public ASN1Integer p; - public ASN1Integer q; - public ASN1Integer g; - public ASN1Integer y; - public ASN1Integer x; - - public PEMDSAPrivate() { - super(6); - version = new ASN1Integer(); - p = new ASN1Integer(); - q = new ASN1Integer(); - g = new ASN1Integer(); - y = new ASN1Integer(); - x = new ASN1Integer(); - setComponent(0, version); - setComponent(1, p); - setComponent(2, q); - setComponent(3, g); - setComponent(4, y); - setComponent(5, x); - } - - public PEMDSAPrivate(int version, - BigInteger p, BigInteger q, BigInteger g, - BigInteger y, BigInteger x) { - this(); - this.version.setValue(version); - this.p.setValue(p); - this.q.setValue(q); - this.g.setValue(g); - this.y.setValue(y); - this.x.setValue(x); - } - - } - - /** - * From PKCS#1 (v2.1 draft) (OpenSSL just refers to PKCS#1). - *

- * NOTE: In OpenSSL's PEM we only need to support version 0 (i.e. PKCS#1 - * v2.0) hence we leave out the OPTIONAL 'otherPrimeInfos' here. - *

- *

-     * RSAPrivateKey ::= SEQUENCE {
-     *   version                 Version,
-     *   modulus                 INTEGER, -- (Usually large) n
-     *   publicExponent          INTEGER, -- (Usually small) e
-     *   privateExponent         INTEGER, -- (Usually large) d
-     *   prime1                  INTEGER, -- (Usually large) p
-     *   prime2                  INTEGER, -- (Usually large) q
-     *   exponent1               INTEGER, -- (Usually large) d mod (p-1)
-     *   exponent2               INTEGER, -- (Usually large) d mod (q-1)
-     *   coefficient             INTEGER, -- (Usually large) (inverse of q) mod p
-     *   otherPrimeInfos         OtherPrimeInfos OPTIONAL
-     * }
-     *
-     * Version ::= INTEGER { two-prime(0), multi(1) }
-     *   (CONSTRAINED BY {-- version must be multi if otherPrimeInfos present --})
-     *
-     * OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
-     *
-     * OtherPrimeInfo ::= SEQUENCE {
-     *   prime INTEGER,  -- ri
-     *   exponent INTEGER, -- di
-     *   coefficient INTEGER -- ti 
-     * }
-     * 
- */ - public static final class PEMRSAPrivate extends ASN1Sequence { - - public ASN1Integer version; - public ASN1Integer n; - public ASN1Integer e; - public ASN1Integer d; - public ASN1Integer p; - public ASN1Integer q; - public ASN1Integer pe; - public ASN1Integer qe; - public ASN1Integer u; - - public PEMRSAPrivate() { - super(9); - version = new ASN1Integer(); - n = new ASN1Integer(); - e = new ASN1Integer(); - d = new ASN1Integer(); - p = new ASN1Integer(); - q = new ASN1Integer(); - pe = new ASN1Integer(); - qe = new ASN1Integer(); - u = new ASN1Integer(); - setComponent(0, version); - setComponent(1, n); - setComponent(2, e); - setComponent(3, d); - setComponent(4, p); - setComponent(5, q); - setComponent(6, pe); - setComponent(7, qe); - setComponent(8, u); - } - - public PEMRSAPrivate(int version, - BigInteger n, BigInteger e, BigInteger d, - BigInteger p, BigInteger q, - BigInteger u) { - this(version, n, e, d, p, q, - RSAAlgorithm.getPrimeExponent(d, p), - RSAAlgorithm.getPrimeExponent(d, q), - u); - } - - public PEMRSAPrivate(int version, - BigInteger n, BigInteger e, BigInteger d, - BigInteger p, BigInteger q, - BigInteger pe, BigInteger qe, - BigInteger u) { - this(); - this.version.setValue(version); - this.n.setValue(n); - this.e.setValue(e); - this.d.setValue(d); - this.p.setValue(p); - this.q.setValue(q); - this.pe.setValue(pe); - this.qe.setValue(qe); - this.u.setValue(u); - } - - } - - /** - * This is the constructor used for storing a key pair. - * - * @param keyPair the key pair to store - * @param subject the subject name of the key owner - * @param comment a comment to accompany the key - */ - public SSH2KeyPairFile(KeyPair keyPair, String subject, String comment) { - this.keyPair = keyPair; - this.armour = new ASCIIArmour("----"); - this.subject = subject; - this.comment = comment; - } - - /** - * This is the constructor used for loading a key pair. - */ - public SSH2KeyPairFile() { - this(null, null, null); - } - - public KeyPair getKeyPair() { - return keyPair; - } - - public String getSubject() { - return subject; - } - - public void setSubject(String subject) { - this.subject = subject; - } - - public String getComment() { - return comment; - } - - public void setComment(String comment) { - this.comment = comment; - } - - public ASCIIArmour getArmour() { - return armour; - } - - public boolean isSSHComFormat() { - return sshComFormat; - } - - public String getAlgorithmName() { - PublicKey publicKey = keyPair.getPublic(); - String alg = null; - if(publicKey instanceof DSAPublicKey) { - alg = "ssh-dss"; - } else if(publicKey instanceof RSAPublicKey) { - alg = "ssh-rsa"; - } - return alg; - } - - public int getBitLength() { - PublicKey publicKey = keyPair.getPublic(); - if(publicKey instanceof DSAPublicKey) { - return ((DSAPublicKey)publicKey).getParams().getP().bitLength(); - } else { - return ((RSAPublicKey)publicKey).getModulus().bitLength(); - } - } - - public static byte[] writeKeyPair(ASCIIArmour armour, String password, - SecureRandom random, - KeyPair keyPair) - throws SSH2FatalException - { - ASN1Object pem; - PublicKey publicKey = keyPair.getPublic(); - int headType; - - if(publicKey instanceof DSAPublicKey) { - DSAPublicKey pubKey = (DSAPublicKey)keyPair.getPublic(); - DSAPrivateKey prvKey = (DSAPrivateKey)keyPair.getPrivate(); - DSAParams params = pubKey.getParams(); - - PEMDSAPrivate dsa = new PEMDSAPrivate(0, - params.getP(), - params.getQ(), - params.getG(), - pubKey.getY(), - prvKey.getX()); - pem = dsa; - headType = TYPE_PEM_DSA; - - } else if(publicKey instanceof RSAPublicKey) { - RSAPublicKey pubKey = (RSAPublicKey)keyPair.getPublic(); - RSAPrivateCrtKey prvKey = (RSAPrivateCrtKey)keyPair.getPrivate(); - - PEMRSAPrivate rsa = new PEMRSAPrivate(0, - pubKey.getModulus(), - pubKey.getPublicExponent(), - prvKey.getPrivateExponent(), - prvKey.getPrimeP(), - prvKey.getPrimeQ(), - prvKey.getCrtCoefficient()); - pem = rsa; - headType = TYPE_PEM_RSA; - - } else { - throw new SSH2FatalException("Unsupported key type: " + publicKey); - } - - armour.setHeaderLine(BEGIN_PRV_KEY[headType]); - armour.setTailLine(END_PRV_KEY[headType]); - - ByteArrayOutputStream enc = new ByteArrayOutputStream(128); - ASN1DER der = new ASN1DER(); - - try { - der.encode(enc, pem); - } catch (IOException e) { - throw new SSH2FatalException("Error while DER encoding"); - } - - byte[] keyBlob = enc.toByteArray(); - - if(password != null && password.length() > 0) { - byte[] iv = new byte[8]; - byte[] key; - - random.setSeed(keyBlob); - - for(int i = 0; i < 8; i++) { - byte[] r = new byte[1]; - do { - random.nextBytes(r); - iv[i] = r[0]; - } while(iv[i] == 0x00); - } - - key = expandPasswordToKey(password, 192 / 8, iv); - - armour.setHeaderField(PRV_PROCTYPE, "4,ENCRYPTED"); - armour.setHeaderField(PRV_DEKINFO, "DES-EDE3-CBC," + - HexDump.toString(iv).toUpperCase()); - - int encLen = (8 - (keyBlob.length % 8)) + keyBlob.length; - byte[] encBuf = new byte[encLen]; - - doCipher(Cipher.ENCRYPT_MODE, password, - keyBlob, keyBlob.length, encBuf, iv); - - keyBlob = encBuf; - } - - return keyBlob; - } - - public static byte[] writeKeyPairSSHCom(String password, - String cipher, KeyPair keyPair) - throws SSH2FatalException - { - SSH2DataBuffer toBeEncrypted = new SSH2DataBuffer(8192); - int totLen = 0; - - DSAPublicKey pubKey = (DSAPublicKey)keyPair.getPublic(); - DSAPrivateKey prvKey = (DSAPrivateKey)keyPair.getPrivate(); - DSAParams params = pubKey.getParams(); - - if(!(pubKey instanceof DSAPublicKey)) { - throw new SSH2FatalException("Unsupported key type: " + pubKey); - } - - toBeEncrypted.writeInt(0); // unenc length (filled in below) - - toBeEncrypted.writeInt(0); // type 0 is explicit params (as opposed to predefined) - toBeEncrypted.writeBigIntBits(params.getP()); - toBeEncrypted.writeBigIntBits(params.getG()); - toBeEncrypted.writeBigIntBits(params.getQ()); - toBeEncrypted.writeBigIntBits(pubKey.getY()); - toBeEncrypted.writeBigIntBits(prvKey.getX()); - - totLen = toBeEncrypted.getWPos(); - toBeEncrypted.setWPos(0); - toBeEncrypted.writeInt(totLen - 4); - - if(!cipher.equals("none")) { - try { - int keyLen = - SSH2TransportPreferences.getCipherKeyLen(cipher); - String cipherName = - SSH2TransportPreferences.ssh2ToJCECipher(cipher); - byte[] key = expandPasswordToKeySSHCom(password, keyLen); - Cipher encrypt = Cipher.getInstance(cipherName); - encrypt.init(Cipher.ENCRYPT_MODE, - new SecretKeySpec(key, encrypt.getAlgorithm())); - byte[] data = toBeEncrypted.getData(); - int bs = encrypt.getBlockSize(); - totLen += (bs - (totLen % bs)) % bs; - totLen = encrypt.doFinal(data, 0, totLen, data, 0); - } catch (NoSuchAlgorithmException e) { - throw new SSH2FatalException("Invalid cipher in " + - "SSH2KeyPairFile.writeKeyPair: " + cipher); - } catch (InvalidKeyException e) { - throw new SSH2FatalException("Invalid key derived in " + - "SSH2KeyPairFile.writeKeyPair: " + e); - } - } - - SSH2DataBuffer buf = new SSH2DataBuffer(512 + totLen); - - buf.writeInt(SSH_PRIVATE_KEY_MAGIC); - buf.writeInt(0); // total length (filled in below) - buf.writeString("dl-modp{sign{dsa-nist-sha1},dh{plain}}"); - buf.writeString(cipher); - buf.writeString(toBeEncrypted.getData(), 0, totLen); - - totLen = buf.getWPos(); - buf.setWPos(4); - buf.writeInt(totLen); - - byte[] keyBlob = new byte[totLen]; - System.arraycopy(buf.data, 0, keyBlob, 0, totLen); - - return keyBlob; - } - - public static KeyPair readKeyPair(ASCIIArmour armour, byte[] keyBlob, - String password) - throws SSH2Exception - { - String procType = armour.getHeaderField(PRV_PROCTYPE); - - if(procType != null && password != null) { - String dekInfo = armour.getHeaderField(PRV_DEKINFO); - if(dekInfo == null || !dekInfo.startsWith("DES-EDE3-CBC,")) { - throw new SSH2FatalException("Proc type not supported: " + - procType); - } - dekInfo = dekInfo.substring(13); - BigInteger dekI = new BigInteger(dekInfo, 16); - - byte[] iv = dekI.toByteArray(); - if(iv.length > 8) { - byte[] tmp = iv; - iv = new byte[8]; - System.arraycopy(tmp, 1, iv, 0, 8); - } - doCipher(Cipher.DECRYPT_MODE, password, - keyBlob, keyBlob.length, keyBlob, iv); - } - - ByteArrayInputStream enc = new ByteArrayInputStream(keyBlob); - ASN1DER der = new ASN1DER(); - KeySpec prvSpec = null; - KeySpec pubSpec = null; - String keyFactType = null; - - String head = armour.getHeaderLine(); - if(head.indexOf("DSA") != -1) { - keyFactType = "DSA"; - } else if(head.indexOf("RSA") != -1) { - keyFactType = "RSA"; - } - - try { - if("DSA".equals(keyFactType)) { - PEMDSAPrivate dsa = new PEMDSAPrivate(); - der.decode(enc, dsa); - - BigInteger p, q, g, x, y; - p = dsa.p.getValue(); - q = dsa.q.getValue(); - g = dsa.g.getValue(); - y = dsa.y.getValue(); - x = dsa.x.getValue(); - - prvSpec = new DSAPrivateKeySpec(x, p, q, g); - pubSpec = new DSAPublicKeySpec(y, p, q, g); - - } else if("RSA".equals(keyFactType)) { - PEMRSAPrivate rsa = new PEMRSAPrivate(); - der.decode(enc, rsa); - - BigInteger n, e, d, p, q, pe, qe, u; - - n = rsa.n.getValue(); - e = rsa.e.getValue(); - d = rsa.d.getValue(); - p = rsa.p.getValue(); - q = rsa.q.getValue(); - pe = rsa.pe.getValue(); - qe = rsa.qe.getValue(); - u = rsa.u.getValue(); - - prvSpec = new RSAPrivateCrtKeySpec(n, e, d, p, q, pe, qe, u); - pubSpec = new RSAPublicKeySpec(n, e); - - } else { - throw new SSH2FatalException("Unsupported key type: " + keyFactType); - } - } catch (IOException e) { - throw new SSH2AccessDeniedException("Invalid password or corrupt key blob"); - } - - try { - KeyFactory keyFact = KeyFactory.getInstance(keyFactType); - return new KeyPair(keyFact.generatePublic(pubSpec), - keyFact.generatePrivate(prvSpec)); - } catch (Exception e) { - throw new SSH2FatalException("Error in readKeyPair: " + e ); - } - } - - public static KeyPair readKeyPairSSHCom(byte[] keyBlob, String password) - throws SSH2Exception - { - SSH2DataBuffer buf = new SSH2DataBuffer(keyBlob.length); - - buf.writeRaw(keyBlob); - - int magic = buf.readInt(); - int privateKeyLen = buf.readInt(); - String type = buf.readJavaString(); - String cipher = buf.readJavaString(); - int bufLen = buf.readInt(); - - if(type.indexOf("dl-modp") == -1) { - // !!! TODO: keyformaterror exception? - throw new SSH2FatalException("Unknown key type '" + type + "'"); - } - - if(magic != SSH_PRIVATE_KEY_MAGIC) { - // !!! TODO: keyformaterror exception? - throw new SSH2FatalException("Invalid magic in private key: " + - magic); - } - - if(!cipher.equals("none")) { - try { - int keyLen = - SSH2TransportPreferences.getCipherKeyLen(cipher); - String cipherName = - SSH2TransportPreferences.ssh2ToJCECipher(cipher); - byte[] key = expandPasswordToKeySSHCom(password, keyLen); - Cipher decrypt = Cipher.getInstance(cipherName); - decrypt.init(Cipher.DECRYPT_MODE, - new SecretKeySpec(key, decrypt.getAlgorithm())); - byte[] data = buf.getData(); - int offset = buf.getRPos(); - decrypt.doFinal(data, offset, bufLen, data, offset); - } catch (NoSuchAlgorithmException e) { - throw new SSH2FatalException("Invalid cipher in " + - "SSH2KeyPairFile.readKeyPairSSHCom: " + - cipher); - } catch (InvalidKeyException e) { - throw new SSH2FatalException("Invalid key derived in " + - "SSH2KeyPairFile.readKeyPairSSHCom: " + e); - } - } - - int parmLen = buf.readInt(); - if(parmLen > buf.getMaxReadSize() || parmLen < 0) { - throw new SSH2AccessDeniedException("Invalid password or corrupt key blob"); - } - - int value = buf.readInt(); - BigInteger p, q, g, x, y; - - if(value == 0) { - p = buf.readBigIntBits(); - g = buf.readBigIntBits(); - q = buf.readBigIntBits(); - y = buf.readBigIntBits(); - x = buf.readBigIntBits(); - } else { - // !!! TODO: predefined params - throw new Error("Predefined DSA params not implemented (" + - value + ") '" + buf.readJavaString() + "'"); - } - - try { - KeyFactory keyFact = KeyFactory.getInstance("DSA"); - return new KeyPair(keyFact.generatePublic( - new DSAPublicKeySpec(y, p, q, g)), - keyFact.generatePrivate( - new DSAPrivateKeySpec(x, p, q, g))); - } catch (Exception e) { - throw new SSH2FatalException( - "Error in SSH2KeyPairFile.readKeyPair: " + e ); - } - } - - public void store(String fileName, SecureRandom random, String password) - throws IOException, SSH2FatalException - { - store(fileName, random, password, sshComFormat); - } - - public void store(String fileName, SecureRandom random, String password, - boolean sshComFormat) - throws IOException, SSH2FatalException - { - armour.setBlankHeaderSep(!sshComFormat); - armour.setLineLength(sshComFormat ? - ASCIIArmour.DEFAULT_LINE_LENGTH : 64); - - armour.setHeaderField(PRV_PROCTYPE, null); - armour.setHeaderField(PRV_DEKINFO, null); - armour.setHeaderField(FILE_SUBJECT, null); - armour.setHeaderField(FILE_COMMENT, null); - - byte[] keyBlob = null; - - if(sshComFormat) { - if(!(keyPair.getPublic() instanceof DSAPublicKey)) { - throw new SSH2FatalException( - "Only DSA keys supported when saving in compatibility mode"); - } - String cipher = ((password != null && password.length() > 0) ? - "3des-cbc" : "none"); - armour.setHeaderLine(BEGIN_PRV_KEY[TYPE_SSHCOM_DSA]); - armour.setTailLine(END_PRV_KEY[TYPE_SSHCOM_DSA]); - comment = "\"" + comment + "\""; - keyBlob = writeKeyPairSSHCom(password, cipher, keyPair); - } else { - keyBlob = writeKeyPair(armour, password, random, keyPair); - } - - armour.setHeaderField(FILE_SUBJECT, subject); - armour.setHeaderField(FILE_COMMENT, comment); - - FileOutputStream out = new FileOutputStream(fileName); - - armour.setCanonicalLineEnd(false); - armour.encode(out, keyBlob); - - out.close(); - } - - public void load(String fileName, String password) - throws IOException, SSH2Exception - { - FileInputStream in = new java.io.FileInputStream(fileName); - PushbackInputStream pbi = new PushbackInputStream(in); - - int c = pbi.read(); - if(c != '-') { - throw new SSH2FatalException("Corrupt or unsupported key file: " + - fileName); - } - pbi.unread(c); - - armour = new ASCIIArmour("----"); - byte[] keyBlob = armour.decode(pbi); - - pbi.close(); - - if(armour.getHeaderLine().indexOf("SSH2") != -1) { - this.sshComFormat = true; - this.keyPair = readKeyPairSSHCom(keyBlob, password); - } else { - this.keyPair = readKeyPair(armour, keyBlob, password); - } - - this.subject = armour.getHeaderField(FILE_SUBJECT); - this.comment = stripQuotes(armour.getHeaderField(FILE_COMMENT)); - } - - public static byte[] expandPasswordToKey(String password, int keyLen, - byte[] salt) - { - try { - MessageDigest md5 = MessageDigest.getInstance("MD5"); - int digLen = md5.getDigestLength(); - byte[] mdBuf = new byte[digLen]; - byte[] key = new byte[keyLen]; - int cnt = 0; - - while(cnt < keyLen) { - if(cnt > 0) { - md5.update(mdBuf); - } - md5.update(password.getBytes()); - md5.update(salt); - md5.digest(mdBuf, 0, digLen); - int n = ((digLen > (keyLen - cnt)) ? keyLen - cnt : digLen); - System.arraycopy(mdBuf, 0, key, cnt, n); - cnt += n; - } - - return key; - - } catch (Exception e) { - throw new Error("Error in SSH2KeyPairFile.expandPasswordToKey: " + - e); - } - } - - public static byte[] expandPasswordToKeySSHCom(String password, int keyLen) { - try { - if(password == null) { - password = ""; - } - MessageDigest md5 = MessageDigest.getInstance("MD5"); - int digLen = md5.getDigestLength(); - byte[] buf = new byte[((keyLen + digLen) / digLen) * - digLen]; - int cnt = 0; - while(cnt < keyLen) { - md5.update(password.getBytes()); - if(cnt > 0) { - md5.update(buf, 0, cnt); - } - md5.digest(buf, cnt, digLen); - cnt += digLen; - } - byte[] key = new byte[keyLen]; - System.arraycopy(buf, 0, key, 0, keyLen); - return key; - } catch (Exception e) { - throw new Error("Error in SSH2KeyPairFile.expandPasswordToKeySSHCom: " + e); - } - } - - private static void doCipher(int mode, String password, - byte[] input, int len, byte[] output, - byte[] iv) - throws SSH2FatalException - { - byte[] key = expandPasswordToKey(password, 192 / 8, iv); - - try { - Cipher cipher = Cipher.getInstance("3DES/CBC/PKCS5Padding"); - cipher.init(mode, new SecretKeySpec(key, cipher.getAlgorithm()), - new IvParameterSpec(iv)); - cipher.doFinal(input, 0, len, output, 0); - } catch (NoSuchAlgorithmException e) { - throw new SSH2FatalException("Invalid algorithm in " + - "SSH2KeyPairFile.doCipher: " + e); - } catch (InvalidKeyException e) { - throw new SSH2FatalException("Invalid key derived in " + - "SSH2KeyPairFile.doCipher: " + e); - } - } - - private String stripQuotes(String str) throws SSH2FatalException { - if(str != null && str.charAt(0) == '"') { - if(str.charAt(str.length() - 1) != '"') { - throw new SSH2FatalException("Unbalanced quotes in key file comment"); - } - str = str.substring(1, str.length() - 1); - } - return str; - } - - /* !!! DEBUG - public static void main(String[] argv) { - try { - SSH2KeyPairFile kp = new SSH2KeyPairFile(); - SecureRandom rnd = new SecureRandom(); - kp.load("/home/mats/.ssh2/id_dsa_1024_a", ""); - kp.store("/home/mats/id_dsa_1024_a", rnd, null, true); - kp.load("/home/mats/id_dsa", null); - } catch (Exception e) { - e.printStackTrace(); - } - } - */ - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2ListUtil.java b/src/main/java/com/mindbright/ssh2/SSH2ListUtil.java deleted file mode 100644 index 43a7360..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2ListUtil.java +++ /dev/null @@ -1,150 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.util.StringTokenizer; - -// !!! TODO, rewrite this mess to a real list handling class instead !!! -// -public final class SSH2ListUtil { - public static String chooseFromList(String clientList, String serverList) { - String[] cliL = arrayFromList(clientList); - String[] srvL = arrayFromList(serverList); - for(int i = 0; i < cliL.length; i++) { - for(int j = 0; j < srvL.length; j++) { - if(cliL[i].equals(srvL[j])) { - return cliL[i]; - } - } - } - return null; - } - - public static String removeAllFromList(String list, String element) { - StringBuffer buf = new StringBuffer(); - String[] arr = arrayFromList(list); - for(int i = 0; i < arr.length; i++) { - if(arr[i].equals(element)) - continue; - if(buf.length() > 0) - buf.append(","); - buf.append(arr[i]); - } - return buf.toString(); - } - - public static String removeAllPrefixFromList(String list, String prefix) - { - StringBuffer buf = new StringBuffer(); - String[] arr = arrayFromList(list); - for(int i = 0; i < arr.length; i++) { - if(arr[i].startsWith(prefix)) - continue; - if(buf.length() > 0) - buf.append(","); - buf.append(arr[i]); - } - return buf.toString(); - } - - public static String removeFirstFromList(String list, String element) { - StringBuffer buf = new StringBuffer(); - String[] arr = arrayFromList(list); - for(int i = 0; i < arr.length; i++) { - if(arr[i].equals(element)) { - element = ""; - continue; - } - if(buf.length() > 0) - buf.append(","); - buf.append(arr[i]); - } - return buf.toString(); - } - - public static String getFirstInList(String list) { - String[] arr = arrayFromList(list); - if(arr.length == 0) { - return null; - } - return arr[0]; - } - - public static boolean isInList(String list, String element) { - String[] arr = arrayFromList(list); - for(int i = 0; i < arr.length; i++) { - if(arr[i].equals(element)) { - return true; - } - } - return false; - } - - public static boolean isPrefixInList(String list, String prefix) { - String[] arr = arrayFromList(list); - for(int i = 0; i < arr.length; i++) { - if(arr[i].startsWith(prefix)) { - return true; - } - } - return false; - } - - public static String sortList(String list) { - String[] arr = arrayFromList(list); - for(int i = 0; i < arr.length; i++) { - for(int j = i; j < arr.length; j++) { - if(!(arr[i].compareTo(arr[j])< 0)) { - String tmp = arr[j]; - arr[j] = arr[i]; - arr[i] = tmp; - } - } - } - return listFromArray(arr); - } - - public static String[] arrayFromList(String list) { - if(list == null) { - return new String[0]; - } - StringTokenizer st = new StringTokenizer(list, ","); - String[] sa = new String[32]; - int cnt = 0; - while(st.hasMoreTokens()) { - sa[cnt++] = st.nextToken().trim(); - } - String[] tmp = new String[cnt]; - for(cnt = 0; cnt < tmp.length; cnt++) { - tmp[cnt] = sa[cnt]; - } - return tmp; - } - - public static String listFromArray(String[] arr) { - StringBuffer buf = new StringBuffer(); - for(int i = 0; i < arr.length; i++) { - if(arr[i] == null || arr[i].equals("")) { - continue; - } - if(buf.length() > 0) - buf.append(","); - buf.append(arr[i]); - } - return buf.toString(); - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2Listener.java b/src/main/java/com/mindbright/ssh2/SSH2Listener.java deleted file mode 100644 index a8c2942..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2Listener.java +++ /dev/null @@ -1,289 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.IOException; -import java.io.InterruptedIOException; -import java.net.InetAddress; -import java.net.Socket; -import java.net.ServerSocket; - -/** - * This class accepts connections to a single address/port pair for creating - * channels through port forwards. It contains a thread which basically contains - * an accept loop in which new connections are accepted and new channels are - * created along with CHANNEL_OPEN messages to peer. There is one - * SSH2Listener instance for each local forward. - * - * @see SSH2Connection - */ -public final class SSH2Listener implements Runnable { - private final static int LISTEN_QUEUE_SIZE = 32; - - SSH2Connection connection; - SSH2StreamFilterFactory filterFactory; - - private int acceptTimeout; - private boolean isLocalForward; - private int channelType; - - private String localAddr; - private int localPort; - private String remoteAddr; - private int remotePort; - - private ServerSocket listenSocket; - - private int acceptCount; - private int acceptMax; - - private volatile int numOfRetries; - private long retryDelayTime; - - private volatile boolean keepListening; - - private Thread myThread; - - public SSH2Listener(String localAddr, int localPort, - String remoteAddr, int remotePort, - SSH2Connection connection, - SSH2StreamFilterFactory filterFactory, - int acceptTimeout) - throws IOException - { - try { - netscape.security.PrivilegeManager.enablePrivilege("TerminalEmulator"); - } catch (netscape.security.ForbiddenTargetException e) { - // !!! - } - - this.localAddr = localAddr; - this.localPort = localPort; - this.remoteAddr = remoteAddr; - this.remotePort = remotePort; - this.connection = connection; - this.filterFactory = filterFactory; - this.keepListening = true; - this.acceptCount = 0; - this.acceptMax = 0; - this.acceptTimeout = acceptTimeout; - this.numOfRetries = 0; - - this.listenSocket = new ServerSocket(localPort, LISTEN_QUEUE_SIZE, - InetAddress.getByName(localAddr)); - - if(this.acceptTimeout != 0) { - this.listenSocket.setSoTimeout(this.acceptTimeout); - } - - this.isLocalForward = (remoteAddr != null); - - if(this.isLocalForward) { - this.channelType = SSH2Connection.CH_TYPE_DIR_TCPIP; - } else { - this.channelType = SSH2Connection.CH_TYPE_FWD_TCPIP; - } - - this.myThread = new Thread(this, "SSH2Listener_" + localAddr + ":" + - localPort); - this.myThread.setDaemon(true); - this.myThread.start(); - } - - public SSH2Listener(String localAddr, int localPort, - String remoteAddr, int remotePort, - SSH2Connection connection, - SSH2StreamFilterFactory filterFactory) - throws IOException - { - this(localAddr, localPort, remoteAddr, remotePort, - connection, filterFactory, 0); - } - - public SSH2Listener(String localAddr, int localPort, - SSH2Connection connection) throws IOException { - this(localAddr, localPort, null, -1, connection, null, 0); - } - - public void run() { - try { - connection.getLog().debug("SSH2Listener", - "starting listener on " + - localAddr + ":" + localPort); - - try { - netscape.security.PrivilegeManager.enablePrivilege("TerminalEmulator"); - } catch (netscape.security.ForbiddenTargetException e) { - // !!! - } - - while(keepListening) { - Socket fwdSocket = null; - - try { - fwdSocket = listenSocket.accept(); - } catch (InterruptedIOException e) { - continue; - } - - connection.getEventHandler().listenerAccept(this, fwdSocket); - - acceptCount++; - synchronized (this) { - if(acceptCount == acceptMax) { - keepListening = false; - } - } - } - - } catch(IOException e) { - if(keepListening) { - connection.getLog().error("SSH2Listener", "run", - "Error in accept for listener " + - localAddr + ":" + localPort + " : " + - e.getMessage()); - } - } finally { - try { - listenSocket.close(); - } catch (IOException e) { /* don't care */ } - listenSocket = null; - - connection.getLog().debug("SSH2Listener", - "stopping listener on " + - localAddr + ":" + localPort); - - } - } - - public void doConnect(Socket fwdSocket) { - InetAddress originAddr = fwdSocket.getInetAddress(); - int originPort = fwdSocket.getPort(); - - connection.getEventHandler().listenerConnect(this, fwdSocket); - - connection.getPreferences().setSocketOptions(channelType, - fwdSocket); - - try { - SSH2TCPChannel channel = null; - if(numOfRetries > 0) { - SSH2RetryingTCPChannel retryChan = - new SSH2RetryingTCPChannel(channelType, connection, this, - fwdSocket, - remoteAddr, remotePort, - originAddr.getHostName(), - originPort); - retryChan.setRetries(numOfRetries); - if(retryDelayTime > 0) { - retryChan.setRetryDelay(retryDelayTime); - } - channel = retryChan; - } else { - channel = - new SSH2TCPChannel(channelType, connection, this, - fwdSocket, - remoteAddr, remotePort, - originAddr.getHostName(), originPort); - } - - connection.getLog().notice("SSH2Listener", - "connect from: " + - originAddr.getHostAddress() + ":" + - originPort + " on " + - localAddr + ":" + localPort + - ", new ch. #" + channel.getId()); - - if(filterFactory != null) { - channel.applyFilter(filterFactory.createFilter(connection, - channel)); - } - - sendChannelOpen(channel, fwdSocket); - - } catch(IOException e) { - connection.getLog().error("SSH2Listener", "doConnect", - "Error in " + - localAddr + ":" + localPort + " : " + - e.getMessage()); - } - } - - public void sendChannelOpen(SSH2TCPChannel channel, Socket fwdSocket) { - SSH2TransportPDU pdu = connection.getChannelOpenPDU(channel); - - InetAddress originAddr = fwdSocket.getInetAddress(); - int originPort = fwdSocket.getPort(); - - if(isLocalForward) { - pdu.writeString(remoteAddr); - pdu.writeInt(remotePort); - } else { - pdu.writeString(localAddr); - pdu.writeInt(localPort); - } - - pdu.writeString(originAddr.getHostAddress()); - pdu.writeInt(originPort); - - connection.transmit(pdu); - } - - public SSH2Connection getConnection() { - return connection; - } - - public synchronized void setAcceptMax(int acceptMax) { - this.acceptMax = acceptMax; - } - - public void setRetries(int numOfRetries) { - this.numOfRetries = numOfRetries; - } - - public void setRetryDelay(long retryDelayTime) { - this.retryDelayTime = retryDelayTime; - } - - public void setThreadPriority(int prio) { - myThread.setPriority(prio); - } - - public int getListenPort() { - return listenSocket.getLocalPort(); - } - - public String getListenHost() { - return listenSocket.getInetAddress().getHostAddress(); - } - - public int getRemotePort() { - return remotePort; - } - - public String getRemoteHost() { - return remoteAddr; - } - - public void stop() { - keepListening = false; - if(listenSocket != null) { - try { listenSocket.close(); } - catch (IOException e) { /* don't care */ } - } - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2MacCheckException.java b/src/main/java/com/mindbright/ssh2/SSH2MacCheckException.java deleted file mode 100644 index 4b0b953..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2MacCheckException.java +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public class SSH2MacCheckException extends SSH2FatalException { - - public SSH2MacCheckException(String message) { - super(message, null); - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2PKISigner.java b/src/main/java/com/mindbright/ssh2/SSH2PKISigner.java deleted file mode 100644 index d7858a8..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2PKISigner.java +++ /dev/null @@ -1,31 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -/** - * This interface is a simple abstraction of a PKI signing mechanism. An - * implementation of this interface can use certificates or plain public keys, - * this is something which is defined by the ssh2 specific algorithm name used - * to identify it. - * - * @see SSH2AuthPublicKey - */ -public interface SSH2PKISigner { - public String getAlgorithmName(); - public byte[] getPublicKeyBlob() throws SSH2SignatureException; - public byte[] sign(byte[] data) throws SSH2SignatureException; - public void setIncompatibility(SSH2Transport transport); -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2PublicKeyFile.java b/src/main/java/com/mindbright/ssh2/SSH2PublicKeyFile.java deleted file mode 100644 index be98925..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2PublicKeyFile.java +++ /dev/null @@ -1,231 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.FileOutputStream; -import java.io.FileInputStream; -import java.io.PushbackInputStream; -import java.io.IOException; -import java.util.StringTokenizer; -import java.util.NoSuchElementException; - -import com.mindbright.jca.security.PublicKey; -import com.mindbright.jca.security.interfaces.DSAPublicKey; -import com.mindbright.jca.security.interfaces.RSAPublicKey; - -import com.mindbright.util.Base64; -import com.mindbright.util.ASCIIArmour; - -/** - * This class implements the file formats commonly used for storing public keys - * for public key authentication. It can handle both OpenSSH's proprietary file - * format aswell as the (draft) standard format. When importing/exporting use - * the appropriate constructor and the load/store methods. Note that this class - * can also be used to convert key pair files between the formats. - * - * @see SSH2KeyPairFile - */ -public class SSH2PublicKeyFile { - - public final static String BEGIN_PUB_KEY = "---- BEGIN SSH2 PUBLIC KEY ----"; - public final static String END_PUB_KEY = "---- END SSH2 PUBLIC KEY ----"; - - private PublicKey publicKey; - private String subject; - private String comment; - private boolean sshComFormat; - - public final static String FILE_SUBJECT = "Subject"; - public final static String FILE_COMMENT = "Comment"; - - /** - * This is the constructor used for storing a public key. - * - * @param publicKey the public key to store - * @param subject the subject name of the key owner - * @param comment a comment to accompany the key - */ - public SSH2PublicKeyFile(PublicKey publicKey, - String subject, String comment) - { - this.publicKey = publicKey; - this.subject = subject; - this.comment = comment; - } - - /** - * This is the constructor used for loading a public key. - */ - public SSH2PublicKeyFile() { - this(null, null, null); - } - - public String getAlgorithmName() { - String alg = null; - if(publicKey instanceof DSAPublicKey) { - alg = "ssh-dss"; - } else if(publicKey instanceof RSAPublicKey) { - alg = "ssh-rsa"; - } - return alg; - } - - public boolean isSSHComFormat() { - return sshComFormat; - } - - public void load(String fileName) throws IOException, SSH2Exception { - FileInputStream in = new FileInputStream(fileName); - PushbackInputStream pbi = new PushbackInputStream(in); - - int c = pbi.read(); - pbi.unread(c); - - byte[] keyBlob = null; - String format = null; - - if(c == 's') { - int l = pbi.available(); - byte[] buf = new byte[l]; - int o = 0; - while(o < l) { - int n = pbi.read(buf, o, l - o); - if(n == -1) - throw new SSH2FatalException("Corrupt public key file"); - o += n; - } - StringTokenizer st = new StringTokenizer(new String(buf)); - String base64 = null; - try { - format = st.nextToken(); - base64 = st.nextToken(); - this.comment = st.nextToken(); - } catch (NoSuchElementException e) { - throw new SSH2FatalException("Corrupt openssh public key string"); - } - keyBlob = Base64.decode(base64.getBytes()); - } else if(c == '-') { - ASCIIArmour armour = new ASCIIArmour(BEGIN_PUB_KEY, END_PUB_KEY); - - keyBlob = armour.decode(pbi); - format = SSH2SimpleSignature.getKeyFormat(keyBlob); - - this.subject = armour.getHeaderField(FILE_SUBJECT); - this.comment = stripQuotes(armour.getHeaderField(FILE_COMMENT)); - this.sshComFormat = true; - } else { - throw new SSH2FatalException("Corrupt or unknown public key file format"); - } - - in.close(); - - SSH2Signature decoder = SSH2Signature.getEncodingInstance(format); - - this.publicKey = decoder.decodePublicKey(keyBlob); - } - - public String store(String fileName) throws IOException, SSH2Exception { - return store(fileName, sshComFormat); - } - - public String store(String fileName, boolean sshComFormat) - throws IOException, SSH2Exception - { - FileOutputStream out = new FileOutputStream(fileName); - String keyString = store(sshComFormat); - out.write(keyString.getBytes()); - out.close(); - return keyString; - } - - public String store(boolean sshComFormat) throws SSH2Exception { - String format = getAlgorithmName(); - - if(format == null) { - throw new SSH2FatalException("Unknown publickey alg: " + publicKey); - } - - SSH2Signature encoder = SSH2Signature.getEncodingInstance(format); - byte[] keyBlob = encoder.encodePublicKey(publicKey); - String keyString = null; - - if(sshComFormat) { - ASCIIArmour armour = new ASCIIArmour(BEGIN_PUB_KEY, END_PUB_KEY); - armour.setCanonicalLineEnd(false); - armour.setHeaderField(FILE_SUBJECT, subject); - armour.setHeaderField(FILE_COMMENT, "\"" + comment + "\""); - keyString = new String(armour.encode(keyBlob)); - } else { - byte[] base64 = Base64.encode(keyBlob); - StringBuffer buf = new StringBuffer(); - buf.append(format); - buf.append(" "); - buf.append(new String(base64)); - buf.append(" "); - buf.append(comment); - buf.append("\n"); - keyString = buf.toString(); - } - - return keyString; - } - - public PublicKey getPublicKey() { - return publicKey; - } - - public String getSubject() { - return subject; - } - - public void setSubject(String subject) { - this.subject = subject; - } - - public String getComment() { - return comment; - } - - public void setComment(String comment) { - this.comment = comment; - } - - private String stripQuotes(String str) throws SSH2FatalException { - if(str != null && str.charAt(0) == '"') { - if(str.charAt(str.length() - 1) != '"') { - throw new SSH2FatalException("Unbalanced quotes in key file comment"); - } - str = str.substring(1, str.length() - 1); - } - return str; - } - - /* !!! DEBUG - public static void main(String[] argv) { - try { - SSH2PublicKeyFile key = new SSH2PublicKeyFile(); - key.load("/home/mats/.ssh/id_dsa.pub"); - key.store("/home/mats/id_dsa.pub"); - key.load("/home/mats/.ssh/id_rsa.pub"); - key.store("/home/mats/id_rsa.pub"); - key.load("/home/mats/.ssh2/id_dsa_1024_a.pub"); - key.store("/home/mats/id_dsa_a.pub"); - } catch (Exception e) { - e.printStackTrace(); - } - } */ - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2RSA.java b/src/main/java/com/mindbright/ssh2/SSH2RSA.java deleted file mode 100644 index 84bf364..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2RSA.java +++ /dev/null @@ -1,77 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.math.BigInteger; - -import com.mindbright.jca.security.KeyFactory; -import com.mindbright.jca.security.PublicKey; -import com.mindbright.jca.security.spec.RSAPublicKeySpec; -import com.mindbright.jca.security.interfaces.RSAPublicKey; - -public final class SSH2RSA extends SSH2SimpleSignature { - public final static String SSH2_KEY_FORMAT = "ssh-rsa"; - - public SSH2RSA() { - super("SHA1withRSA", SSH2_KEY_FORMAT); - } - - public byte[] encodePublicKey(PublicKey publicKey) throws SSH2Exception { - SSH2DataBuffer buf = new SSH2DataBuffer(8192); - - if(!(publicKey instanceof RSAPublicKey)) { - throw new SSH2FatalException("SSH2RSA, invalid public key type: " + - publicKey); - } - - RSAPublicKey rsaPubKey = (RSAPublicKey)publicKey; - - buf.writeString(SSH2_KEY_FORMAT); - buf.writeBigInt(rsaPubKey.getPublicExponent()); - buf.writeBigInt(rsaPubKey.getModulus()); - - return buf.readRestRaw(); - } - - public PublicKey decodePublicKey(byte[] pubKeyBlob) throws SSH2Exception { - BigInteger e, n; - SSH2DataBuffer buf = new SSH2DataBuffer(pubKeyBlob.length); - - buf.writeRaw(pubKeyBlob); - - String type = buf.readJavaString(); - if(!type.equals(SSH2_KEY_FORMAT)) { - throw new SSH2FatalException("SSH2RSA, keyblob type mismatch, got '" - + type + ", (execpted + '" + - SSH2_KEY_FORMAT + "')"); - } - - e = buf.readBigInt(); - n = buf.readBigInt(); - - try { - KeyFactory rsaKeyFact = KeyFactory.getInstance("RSA"); - RSAPublicKeySpec rsaPubSpec = new RSAPublicKeySpec(n, e); - - return rsaKeyFact.generatePublic(rsaPubSpec); - - } catch (Exception ee) { - throw new SSH2FatalException("SSH2RSA, error decoding public key blob: " + - ee); - } - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2RetryingTCPChannel.java b/src/main/java/com/mindbright/ssh2/SSH2RetryingTCPChannel.java deleted file mode 100644 index 37bf040..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2RetryingTCPChannel.java +++ /dev/null @@ -1,79 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.IOException; -import java.net.Socket; -import java.net.InetAddress; - -public class SSH2RetryingTCPChannel extends SSH2TCPChannel { - - private int numOfRetries; - private long retryDelayTime; - - public SSH2RetryingTCPChannel(int channelType, SSH2Connection connection, - Object creator, - Socket endpoint, - String remoteAddr, int remotePort, - String originAddr, int originPort) - throws IOException - { - super(channelType, connection, creator, - endpoint, remoteAddr, remotePort, originAddr, originPort); - this.numOfRetries = 3; - this.retryDelayTime = 200L; - } - - protected void setRetries(int numOfRetries) { - this.numOfRetries = numOfRetries; - } - - public void setRetryDelay(long retryDelayTime) { - this.retryDelayTime = retryDelayTime; - } - - protected boolean openFailureImpl(int reasonCode, String reasonText, - String langTag) { - boolean retry = true; - if(numOfRetries > 0) { - if(getCreator() instanceof SSH2Listener) { - try { - Thread.sleep(retryDelayTime); - } catch (InterruptedException e) { - } - connection.getLog().notice("SSH2RetryingTCPChannel", - "retry (" + numOfRetries + - ") connection on ch. #" + getId() + - " to " + remoteAddr + ":" + remotePort); - SSH2Listener listener = (SSH2Listener)getCreator(); - listener.sendChannelOpen(this, endpoint); - } else { - connection.getLog().error("SSH2RetryingTCPChannel", - "openFailureImpl", - "unexpected use of this class"); - } - } else { - outputClosed(); - retry = false; - } - numOfRetries--; - - return retry; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2SCP1Client.java b/src/main/java/com/mindbright/ssh2/SSH2SCP1Client.java deleted file mode 100644 index f29b89e..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2SCP1Client.java +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.File; -import java.io.OutputStream; - -import com.mindbright.sshcommon.SSHSCP1; - -public final class SSH2SCP1Client extends SSH2ConsoleRemote { - - private SSHSCP1 scp1; - - public SSH2SCP1Client(File cwd, SSH2Connection connection, - OutputStream stderr, boolean verbose) { - super(connection, stderr); - this.scp1 = new SSHSCP1(cwd, this, verbose); - } - - public SSHSCP1 scp1() { - return scp1; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2SFTP.java b/src/main/java/com/mindbright/ssh2/SSH2SFTP.java deleted file mode 100644 index 0ba12a8..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2SFTP.java +++ /dev/null @@ -1,476 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.IOException; - -import java.util.Date; -import java.text.SimpleDateFormat; - -public class SSH2SFTP { - - private static final int DATA_BUFFER_SIZE = 34000; - - public static final class FileHandle { - - private byte[] handle; - private String name; - private boolean isDirectory; - private boolean isOpen; - private boolean asyncEOF; - private int asyncCnt; - private int reqLeft; - private SFTPException asyncException; - private AsyncListener listener; - - protected volatile long lastOffset; - - public FileHandle(String name, byte[] handle, boolean isDirectory) { - this.name = name; - this.handle = handle; - this.isDirectory = isDirectory; - this.isOpen = true; - this.asyncCnt = 0; - this.reqLeft = 0; - this.asyncException = null; - this.lastOffset = 0L; - } - - public boolean isDirectory() { - return isDirectory; - } - - public boolean isOpen() { - return isOpen; - } - - public String getName() { - return name; - } - - public byte[] getHandle() { - return handle; - } - - public void addAsyncListener(AsyncListener listener) { - this.listener = listener; - } - - protected synchronized void asyncStart(int len) { - asyncCnt++; - } - - protected synchronized void asyncEnd(int len) { - asyncCnt--; - if(asyncCnt <= reqLeft) { - this.notifyAll(); - } - if(listener != null) { - listener.progress((long)len); - } - } - - protected synchronized void asyncReadEOF() { - asyncEOF = true; - asyncEnd(0); - } - - protected synchronized void asyncException(SFTPException e) { - asyncException = e; - this.notifyAll(); - } - - public synchronized void asyncClose() { - if(asyncCnt > 0) { - asyncException(new SFTPAsyncAbortException()); - } - isOpen = false; - } - - public synchronized boolean asyncWait() throws SFTPException { - return asyncWait(0); - } - - public synchronized boolean asyncWait(int reqLeft) - throws SFTPException - { - if(this.reqLeft < reqLeft) { - this.reqLeft = reqLeft; - } - while(asyncCnt > reqLeft && asyncException == null && !asyncEOF) { - try { - this.wait(); - } catch (InterruptedException e) { - } - } - if(asyncException != null) { - throw (SFTPException)asyncException.fillInStackTrace(); - } - boolean eof = asyncEOF; - asyncEOF = false; - return eof; - } - - } - - public static interface AsyncListener { - public void progress(long size); - } - - public static final class FileAttributes { - - char[] types = { 'p', 'c', 'd', 'b', '-', 'l', 's', }; - - public final static int S_IFMT = 0170000; - public final static int S_IFSOCK = 0140000; - public final static int S_IFLNK = 0120000; - public final static int S_IFREG = 0100000; - public final static int S_IFBLK = 0060000; - public final static int S_IFDIR = 0040000; - public final static int S_IFCHR = 0020000; - public final static int S_IFIFO = 0010000; - - public final static int S_ISUID = 0004000; - public final static int S_ISGID = 0002000; - - public final static int S_IRUSR = 00400; - public final static int S_IWUSR = 00200; - public final static int S_IXUSR = 00100; - public final static int S_IRGRP = 00040; - public final static int S_IWGRP = 00020; - public final static int S_IXGRP = 00010; - public final static int S_IROTH = 00004; - public final static int S_IWOTH = 00002; - public final static int S_IXOTH = 00001; - - public boolean hasName; - public boolean hasSize; - public boolean hasUserGroup; - public boolean hasPermissions; - public boolean hasModTime; - public String name; - public String lname; - public long size; - public int uid; - public int gid; - public int permissions; - public int atime; - public int mtime; - - public String toString() { - return toString(hasName ? name : ""); - } - - public String toString(String name) { - StringBuffer str = new StringBuffer(); - str.append(permString()); - str.append(" 1 "); - str.append(uid); - str.append("\t"); - str.append(gid); - str.append("\t"); - str.append(size); - str.append(" "); - str.append(modTimeString()); - str.append(" "); - str.append(name); - return str.toString(); - } - - public String permString() { - StringBuffer str = new StringBuffer(); - str.append(types[(permissions & S_IFMT) >>> 13]); - str.append(rwxString(permissions, 6)); - str.append(rwxString(permissions, 3)); - str.append(rwxString(permissions, 0)); - return str.toString(); - } - - public String modTimeString() { - SimpleDateFormat df; - long mt = (mtime * 1000L); - long now = System.currentTimeMillis(); - if((now - mt) > (6 * 30 * 24 * 60 * 60 * 1000L)) { - df = new SimpleDateFormat("MMM dd yyyy"); - } else { - df = new SimpleDateFormat("MMM dd hh:mm"); - } - return df.format(new Date(mt)); - } - - private String rwxString(int v, int r) { - v >>>= r; - String rwx = ((((v & 0x04) != 0) ? "r" : "-") + - (((v & 0x02) != 0) ? "w" : "-")); - if((r == 6 && isSUID()) || - (r == 3 && isSGID())) { - rwx += (((v & 0x01) != 0) ? "s" : "S"); - } else { - rwx += (((v & 0x01) != 0) ? "x" : "-"); - } - return rwx; - } - - public boolean isSocket() { - return ((permissions & S_IFSOCK) == S_IFSOCK); - } - - public boolean isLink() { - return ((permissions & S_IFLNK) == S_IFLNK); - } - - public boolean isFile() { - return ((permissions & S_IFREG) == S_IFREG); - } - - public boolean isBlock() { - return ((permissions & S_IFBLK) == S_IFBLK); - } - - public boolean isDirectory() { - return ((permissions & S_IFDIR) == S_IFDIR); - } - - public boolean isCharacter() { - return ((permissions & S_IFCHR) == S_IFCHR); - } - - public boolean isFifo() { - return ((permissions & S_IFIFO) == S_IFIFO); - } - - public boolean isSUID() { - return ((permissions & S_ISUID) == S_ISUID); - } - - public boolean isSGID() { - return ((permissions & S_ISGID) == S_ISGID); - } - - } - - public static class SFTPException extends Exception { - public SFTPException() { - } - - public SFTPException(String msg) { - super(msg); - } - } - - public static class SFTPEOFException extends SFTPException { - } - - public static class SFTPNoSuchFileException extends SFTPException { - } - - public static class SFTPPermissionDeniedException extends SFTPException { - } - - public static class SFTPDisconnectException extends SFTPException { - } - - public static class SFTPAsyncAbortException extends SFTPException { - } - - protected static final class SFTPPacket extends SSH2DataBuffer { - - private int type; - private int id; - private int len; - - public SFTPPacket() { - super(DATA_BUFFER_SIZE); - } - - public void reset(int type, int id) { - reset(); - writeInt(0); // dummy length - writeByte(type); - writeInt(id); - this.type = type; - this.id = id; - } - - public int getType() { - return type; - } - - public int getId() { - return id; - } - - public int getLength() { - return len; - } - - public void writeLong(long l) { - writeInt((int)((l >>> 32) & 0xffffffffL)); - writeInt((int)(l & 0xffffffff)); - } - - public long readLong() { - long h = (long)readInt(); - long l = (long)readInt(); - if(h < 0) - h += 0xffffffffL; - if(l < 0) - l += 0xffffffffL; - return (h << 32) | (l & 0xffffffff); - } - - public void writeAttrs(FileAttributes attrs) { - writeInt((attrs.hasSize ? SSH_ATTR_SIZE : 0) | - (attrs.hasUserGroup ? SSH_ATTR_UIDGID : 0) | - (attrs.hasPermissions ? SSH_ATTR_PERM : 0) | - (attrs.hasModTime ? SSH_ATTR_MODTIME : 0)); - if(attrs.hasSize) { - writeLong(attrs.size); - } - if(attrs.hasUserGroup) { - writeInt(attrs.uid); - writeInt(attrs.gid); - } - if(attrs.hasPermissions) { - writeInt(attrs.permissions); - } - if(attrs.hasModTime) { - writeInt(attrs.atime); - writeInt(attrs.mtime); - } - } - - public FileAttributes readAttrs() { - FileAttributes attrs = new FileAttributes(); - int flags = readInt(); - attrs.hasSize = ((flags & SSH_ATTR_SIZE) != 0); - attrs.hasUserGroup = ((flags & SSH_ATTR_UIDGID) != 0); - attrs.hasPermissions = ((flags & SSH_ATTR_PERM) != 0); - attrs.hasModTime = ((flags & SSH_ATTR_MODTIME) != 0); - if(attrs.hasSize) { - attrs.size = readLong(); - } - if(attrs.hasUserGroup) { - attrs.uid = readInt(); - attrs.gid = readInt(); - } - if(attrs.hasPermissions) { - attrs.permissions = readInt(); - } - if(attrs.hasModTime) { - attrs.atime = readInt(); - attrs.mtime = readInt(); - } - return attrs; - } - - public void readFrom(InputStream in) - throws SFTPException - { - int cnt = 0; - len = 5; - try { - while(cnt < len) { - int n; - n = in.read(data, cnt, (len - cnt)); - if(n == -1) { - throw new SFTPDisconnectException(); - } - cnt += n; - if(cnt == 5) { - len = readInt() + 4; - type = readByte(); - } - } - } catch (IOException e) { - throw new SFTPException(e.getMessage()); - } - len -= 5; - } - - public void writeTo(OutputStream out) - throws SFTPException - { - len = getWPos() - 5; - setWPos(0); - writeInt(len + 1); - try { - out.write(data, 0, len + 5); - } catch (IOException e) { - throw new SFTPException(e.getMessage()); - } - } - } - - /* Version is 3 according to draft minus extension in init */ - protected final static int SSH_FILEXFER_VERSION = 2; - - /* Packet types. */ - protected final static int SSH_FXP_INIT = 1; - protected final static int SSH_FXP_VERSION = 2; - protected final static int SSH_FXP_OPEN = 3; - protected final static int SSH_FXP_CLOSE = 4; - protected final static int SSH_FXP_READ = 5; - protected final static int SSH_FXP_WRITE = 6; - protected final static int SSH_FXP_LSTAT = 7; - protected final static int SSH_FXP_FSTAT = 8; - protected final static int SSH_FXP_SETSTAT = 9; - protected final static int SSH_FXP_FSETSTAT = 10; - protected final static int SSH_FXP_OPENDIR = 11; - protected final static int SSH_FXP_READDIR = 12; - protected final static int SSH_FXP_REMOVE = 13; - protected final static int SSH_FXP_MKDIR = 14; - protected final static int SSH_FXP_RMDIR = 15; - protected final static int SSH_FXP_REALPATH = 16; - protected final static int SSH_FXP_STAT = 17; - protected final static int SSH_FXP_RENAME = 18; - - protected final static int SSH_FXP_STATUS = 101; - protected final static int SSH_FXP_HANDLE = 102; - protected final static int SSH_FXP_DATA = 103; - protected final static int SSH_FXP_NAME = 104; - protected final static int SSH_FXP_ATTRS = 105; - protected final static int SSH_FXP_EXTENDED = 200; - protected final static int SSH_FXP_EXTENDED_REPLY = 201; - - /* Status/error codes. */ - public final static int SSH_FX_OK = 0; - public final static int SSH_FX_EOF = 1; - public final static int SSH_FX_NO_SUCH_FILE = 2; - public final static int SSH_FX_PERMISSION_DENIED = 3; - public final static int SSH_FX_FAILURE = 4; - public final static int SSH_FX_BAD_MESSAGE = 5; - public final static int SSH_FX_NO_CONNECTION = 6; - public final static int SSH_FX_CONNECTION_LOST = 7; - public final static int SSH_FX_OP_UNSUPPORTED = 8; - - /* Portable versions of O_RDONLY etc. */ - public final static int SSH_FXF_READ = 0x0001; - public final static int SSH_FXF_WRITE = 0x0002; - public final static int SSH_FXF_APPEND = 0x0004; - public final static int SSH_FXF_CREAT = 0x0008; - public final static int SSH_FXF_TRUNC = 0x0010; - public final static int SSH_FXF_EXCL = 0x0020; - - /* Flags indicating presence of file attributes. */ - protected final static int SSH_ATTR_SIZE = 0x01; - protected final static int SSH_ATTR_UIDGID = 0x02; - protected final static int SSH_ATTR_PERM = 0x04; - protected final static int SSH_ATTR_MODTIME = 0x08; - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2SFTPClient.java b/src/main/java/com/mindbright/ssh2/SSH2SFTPClient.java deleted file mode 100644 index 7d504aa..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2SFTPClient.java +++ /dev/null @@ -1,822 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.IOException; -import java.io.RandomAccessFile; - -import java.util.Hashtable; -import java.util.Enumeration; - -import com.mindbright.util.Queue; - -public final class SSH2SFTPClient extends SSH2SFTP { - - private class ReplyLock { - protected int expectType; - protected SFTPPacket replyPkt; - - protected ReplyLock(int expectType) { - this.expectType = expectType; - this.replyPkt = null; - } - - protected synchronized SFTPPacket expect() throws SFTPException { - while(replyPkt == null) { - try { - this.wait(); - } catch (InterruptedException e) { - } - } - checkType(replyPkt, expectType); - return replyPkt; - } - - protected synchronized void received(SFTPPacket replyPkt) { - this.replyPkt = replyPkt; - this.notify(); - } - - protected synchronized void cancel() { - this.replyPkt = createPacket(SSH_FXP_STATUS); - this.replyPkt.writeInt(SSH_FX_CONNECTION_LOST); - this.notify(); - } - - } - - private class WriteReplyLock extends ReplyLock { - - private FileHandle handle; - private int len; - - protected WriteReplyLock(FileHandle handle, int len) { - super(SSH_FXP_STATUS); - this.handle = handle; - this.len = len; - handle.asyncStart(len); - } - - protected synchronized void received(SFTPPacket replyPkt) { - try { - if(!handle.isOpen()) { - /* Ignore and discard packets after close */ - return; - } - checkType(replyPkt, expectType); - handle.asyncEnd(len); - } catch (SFTPException e) { - handle.asyncException(e); - } - releasePacket(replyPkt); - } - - protected synchronized void cancel() { - handle.asyncException(new SFTPDisconnectException()); - this.notify(); - } - - } - - private class ReadReplyLock extends ReplyLock { - - private FileHandle handle; - private long fileOffset; - private byte[] buf; - private int off; - private int len; - - private RandomAccessFile fileTarget; - private OutputStream strmTarget; - - private ReadReplyLock(FileHandle handle, long fileOffset, int len) { - super(SSH_FXP_DATA); - this.handle = handle; - this.fileOffset = fileOffset; - this.len = len; - handle.asyncStart(len); - } - - protected ReadReplyLock(FileHandle handle, long fileOffset, - OutputStream strmTarget, int len) { - this(handle, fileOffset, len); - this.strmTarget = strmTarget; - } - - protected ReadReplyLock(FileHandle handle, long fileOffset, - RandomAccessFile fileTarget, int len) { - this(handle, fileOffset, len); - this.fileTarget = fileTarget; - } - - protected ReadReplyLock(FileHandle handle, long fileOffset, - byte[] buf, int off, int len) { - this(handle, fileOffset, len); - this.buf = buf; - this.off = off; - } - - protected synchronized void received(SFTPPacket replyPkt) { - try { - int n; - if(!handle.isOpen()) { - /* Ignore and discard packets after close */ - return; - } - checkType(replyPkt, expectType); - if(fileTarget != null) { - n = replyPkt.readInt(); - fileTarget.seek(fileOffset); - fileTarget.write(replyPkt.getData(), replyPkt.getRPos(), n); - } else if(strmTarget != null) { - if(handle.lastOffset != fileOffset) { - handle.asyncException(new SFTPException( - "Out of order packets can't be handled yet!")); - } - n = replyPkt.readInt(); - strmTarget.write(replyPkt.getData(), replyPkt.getRPos(), n); - handle.lastOffset = fileOffset + n; - } else { - n = replyPkt.readString(buf, off); - } - if(n < len) { - resend(replyPkt, n); - } else { - handle.asyncEnd(len); - releasePacket(replyPkt); - } - } catch (IOException e) { - handle.asyncException(new SFTPException(e.getMessage())); - } catch (SFTPEOFException e) { - handle.asyncReadEOF(); - } catch (SFTPException e) { - handle.asyncException(e); - } - } - - private void resend(SFTPPacket pkt, int n) { - int i = getNextId(); - Integer id = new Integer(i); - - fileOffset += n; - len -= n; - off += n; - pkt.reset(SSH_FXP_READ, i); - pkt.writeString(handle.getHandle()); - pkt.writeLong(fileOffset); - pkt.writeInt(len); - replyLocks.put(id, this); - txQueue.putLast(pkt); - } - - protected synchronized void cancel() { - handle.asyncException(new SFTPDisconnectException()); - this.notify(); - } - - } - - private final static int POOL_SIZE = 16; - - private SSH2Connection connection; - private SSH2SessionChannel session; - private Queue txQueue; - - private int id; - private int version; - private boolean isBlocking; - private boolean isOpen; - - private Hashtable replyLocks; - - private SFTPPacket[] pktPool; - private int pktPoolCnt; - - public SSH2SFTPClient(SSH2Connection connection, boolean isBlocking) - throws SFTPException - { - this.connection = connection; - this.id = 0; - this.isBlocking = isBlocking; - - this.restart(); - - // INIT pkt don't have an id but version is in same place - // - SFTPPacket pkt = createPacket(); - pkt.reset(SSH_FXP_INIT, SSH_FILEXFER_VERSION); - pkt.writeTo(session.stdin); - pkt.reset(); - pkt.readFrom(session.stdout); - checkType(pkt, SSH_FXP_VERSION); - version = pkt.readInt(); - releasePacket(pkt); - - if(!isBlocking) { - startNonblocking(); - } - } - - public void terminate() { - isOpen = false; - if(session != null) { - session.close(); - } - cancelAllAsync(); - session = null; - if(pktPool != null) { - // Be nice to the GC - for(int i = 0; i < POOL_SIZE; i++) { - pktPool[i] = null; - } - } - pktPoolCnt = 0; - } - - public void restart() throws SFTPException { - terminate(); - session = connection.newSession(); - if(!session.doSubsystem("sftp")) { - // !!! TODO: fix - throw new SFTPException("sftp subsystem couldn't be started on server"); - } - isOpen = true; - pktPool = new SFTPPacket[POOL_SIZE]; - pktPoolCnt = POOL_SIZE; - for(int i = 0; i < POOL_SIZE; i++) { - pktPool[i] = new SFTPPacket(); - } - } - - public FileHandle open(String name, int flags, FileAttributes attrs) - throws SFTPException - { - SFTPPacket pkt = createPacket(SSH_FXP_OPEN); - pkt.writeString(name); - pkt.writeInt(flags); - pkt.writeAttrs(attrs); - - pkt = transmitExpectReply(pkt, SSH_FXP_HANDLE); - FileHandle handle = new FileHandle(name, pkt.readString(), false); - releasePacket(pkt); - return handle; - } - - public void close(FileHandle handle) throws SFTPException { - SFTPPacket pkt = createPacket(SSH_FXP_CLOSE, handle); - pkt = transmitExpectReply(pkt, SSH_FXP_STATUS); - releasePacket(pkt); - handle.asyncClose(); - } - - public int read(FileHandle handle, long fileOffset, - RandomAccessFile fileTarget, int len) - throws SFTPException, IOException - { - if(!handle.isOpen()) { - throw new SFTPAsyncAbortException(); - } - SFTPPacket pkt = createPacket(SSH_FXP_READ, handle); - pkt.writeLong(fileOffset); - pkt.writeInt(len); - - if(isBlocking) { - try { - pkt = transmitExpectReply(pkt, SSH_FXP_DATA); - len = pkt.readInt(); - fileTarget.seek(fileOffset); - fileTarget.write(pkt.getData(), pkt.getRPos(), len); - return len; - } catch (SFTPEOFException e) { - return 0; - } finally { - if(pkt != null) - releasePacket(pkt); - } - } else { - Integer id = new Integer(pkt.getId()); - ReplyLock reply = new ReadReplyLock(handle, fileOffset, fileTarget, - len); - replyLocks.put(id, reply); - txQueue.putLast(pkt); - return len; - } - } - - public int read(FileHandle handle, long fileOffset, - byte[] buf, int off, int len) - throws SFTPException - { - if(!handle.isOpen()) { - throw new SFTPAsyncAbortException(); - } - SFTPPacket pkt = createPacket(SSH_FXP_READ, handle); - pkt.writeLong(fileOffset); - pkt.writeInt(len); - - if(isBlocking) { - try { - pkt = transmitExpectReply(pkt, SSH_FXP_DATA); - return pkt.readString(buf, off); - } catch (SFTPEOFException e) { - return 0; - } finally { - if(pkt != null) - releasePacket(pkt); - } - } else { - if(!isOpen) { - throw new SFTPDisconnectException(); - } - Integer id = new Integer(pkt.getId()); - ReplyLock reply = new ReadReplyLock(handle, fileOffset, - buf, off, len); - replyLocks.put(id, reply); - txQueue.putLast(pkt); - return -1; - } - } - - public int readFully(FileHandle handle, OutputStream out) - throws SFTPException, IOException - { - if(!handle.isOpen()) { - throw new SFTPAsyncAbortException(); - } - FileAttributes attrs = fstat(handle); - - int len = (int)attrs.size; - int foffs = 0; - int cnt = 0; - - try { - while(foffs < len) { - int n = (32768 < (len - foffs) ? 32768 : - (int)(len - foffs)); - - SFTPPacket pkt = createPacket(SSH_FXP_READ, handle); - pkt.writeLong(foffs); - pkt.writeInt(n); - - if(isBlocking) { - try { - pkt = transmitExpectReply(pkt, SSH_FXP_DATA); - n = pkt.readInt(); - out.write(pkt.getData(), pkt.getRPos(), n); - } finally { - if(pkt != null) - releasePacket(pkt); - } - } else { - Integer id = new Integer(pkt.getId()); - ReplyLock reply = new ReadReplyLock(handle, foffs, out, n); - replyLocks.put(id, reply); - txQueue.putLast(pkt); - } - - foffs += n; - - if(!isBlocking && ++cnt == 24) { - cnt = 0; - handle.asyncWait(12); - } - } - - if(!isBlocking) { - handle.asyncWait(); - } - - } finally { - close(handle); - } - - return (int)attrs.size; - } - - protected void writeInternal(FileHandle handle, SFTPPacket pkt, int len) - throws SFTPException - { - if(isBlocking) { - pkt = transmitExpectReply(pkt, SSH_FXP_STATUS); - releasePacket(pkt); - } else { - if(!isOpen) { - throw new SFTPDisconnectException(); - } - Integer id = new Integer(pkt.getId()); - ReplyLock reply = new WriteReplyLock(handle, len); - replyLocks.put(id, reply); - txQueue.putLast(pkt); - } - } - - public void write(FileHandle handle, long fileOffset, - byte[] buf, int off, int len) - throws SFTPException - { - if(!handle.isOpen()) { - throw new SFTPAsyncAbortException(); - } - SFTPPacket pkt = createPacket(SSH_FXP_WRITE, handle); - pkt.writeLong(fileOffset); - pkt.writeString(buf, off, len); - - writeInternal(handle, pkt, len); - } - - public int writeFully(FileHandle handle, InputStream in) - throws SFTPException, IOException - { - if(!handle.isOpen()) { - throw new SFTPAsyncAbortException(); - } - - int len = 0; - int foffs = 0; - int cnt = 0; - int lPos = 0; - - try { - while(true) { - SFTPPacket pkt = createPacket(SSH_FXP_WRITE, handle); - pkt.writeLong(foffs); - lPos = pkt.getWPos(); - pkt.writeInt(0); - - int n = pkt.getMaxWriteSize(); - n = (n > 32768 ? 32768 : n); - - len = in.read(pkt.getData(), pkt.getWPos(), n); - - if(len > 0) { - pkt.setWPos(lPos); - pkt.writeInt(len); - pkt.setWPos(lPos + 4 + len); - writeInternal(handle, pkt, len); - foffs += len; - if(!isBlocking && ++cnt == 24) { - cnt = 0; - handle.asyncWait(12); - } - - // !!! REMOVE, seems to choke scheduler (in linux anyway...) - // - if((cnt % 6 == 1)) - Thread.yield(); - - } else { - break; - } - } - - if(!isBlocking) { - handle.asyncWait(); - } - - } finally { - close(handle); - } - - return foffs; - } - - public FileAttributes lstat(String name) - throws SFTPException - { - SFTPPacket pkt = createPacket(SSH_FXP_LSTAT); - pkt.writeString(name); - - return statInternal(pkt); - } - - public FileAttributes stat(String name) - throws SFTPException - { - SFTPPacket pkt = createPacket(SSH_FXP_STAT); - pkt.writeString(name); - - return statInternal(pkt); - } - - public FileAttributes fstat(FileHandle handle) - throws SFTPException - { - SFTPPacket pkt = createPacket(SSH_FXP_FSTAT, handle); - - return statInternal(pkt); - } - - private FileAttributes statInternal(SFTPPacket pkt) throws SFTPException { - pkt = transmitExpectReply(pkt, SSH_FXP_ATTRS); - FileAttributes attrs = pkt.readAttrs(); - releasePacket(pkt); - return attrs; - } - - public void setstat(String name, FileAttributes attrs) - throws SFTPException - { - SFTPPacket pkt = createPacket(SSH_FXP_SETSTAT); - pkt.writeString(name); - pkt.writeAttrs(attrs); - - pkt = transmitExpectReply(pkt, SSH_FXP_STATUS); - releasePacket(pkt); - } - - public void fsetstat(FileHandle handle, FileAttributes attrs) - throws SFTPException - { - SFTPPacket pkt = createPacket(SSH_FXP_FSETSTAT, handle); - - pkt.writeAttrs(attrs); - - pkt = transmitExpectReply(pkt, SSH_FXP_STATUS); - releasePacket(pkt); - } - - public FileHandle opendir(String path) - throws SFTPException - { - SFTPPacket pkt = createPacket(SSH_FXP_OPENDIR); - pkt.writeString(path); - - pkt = transmitExpectReply(pkt, SSH_FXP_HANDLE); - FileHandle handle = new FileHandle(path, pkt.readString(), true); - releasePacket(pkt); - return handle; - } - - public FileAttributes[] readdir(FileHandle handle) - throws SFTPException - { - SFTPPacket pkt = createPacket(SSH_FXP_READDIR, handle); - - pkt = transmitExpectReply(pkt, SSH_FXP_NAME); - - int count = pkt.readInt(); - FileAttributes[] list = new FileAttributes[count]; - - for(int i = 0; i < count; i++) { - String name = new String(pkt.readString()); - String lname = new String(pkt.readString()); - list[i] = pkt.readAttrs(); - list[i].name = name; - list[i].lname = lname; - list[i].hasName = true; - } - releasePacket(pkt); - - return list; - } - - public void remove(String name) throws SFTPException { - SFTPPacket pkt = createPacket(SSH_FXP_REMOVE); - pkt.writeString(name); - - pkt = transmitExpectReply(pkt, SSH_FXP_STATUS); - releasePacket(pkt); - } - - public void rename(String oldName, String newName) - throws SFTPException - { - SFTPPacket pkt = createPacket(SSH_FXP_RENAME); - pkt.writeString(oldName); - pkt.writeString(newName); - - pkt = transmitExpectReply(pkt, SSH_FXP_STATUS); - releasePacket(pkt); - } - - public void mkdir(String name, FileAttributes attrs) - throws SFTPException - { - SFTPPacket pkt = createPacket(SSH_FXP_MKDIR); - pkt.writeString(name); - pkt.writeAttrs(attrs); - - pkt = transmitExpectReply(pkt, SSH_FXP_STATUS); - releasePacket(pkt); - } - - public void rmdir(String name) throws SFTPException { - SFTPPacket pkt = createPacket(SSH_FXP_RMDIR); - pkt.writeString(name); - - pkt = transmitExpectReply(pkt, SSH_FXP_STATUS); - releasePacket(pkt); - } - - public FileAttributes realpath(String nameIn) - throws SFTPException - { - SFTPPacket pkt = createPacket(SSH_FXP_REALPATH); - pkt.writeString(nameIn); - - pkt = transmitExpectReply(pkt, SSH_FXP_NAME); - int cnt = pkt.readInt(); // Allways one - String name = new String(pkt.readString()); - String lname = new String(pkt.readString()); - FileAttributes attrs = pkt.readAttrs(); - attrs.name = name; - attrs.lname = lname; - attrs.hasName = true; - releasePacket(pkt); - - return attrs; - } - - private SFTPPacket transmitExpectReply(SFTPPacket pkt, int expectType) - throws SFTPException - { - if(!isOpen) { - throw new SFTPDisconnectException(); - } - if(isBlocking) { - synchronized(this) { - int expectId = pkt.getId(); - pkt.writeTo(session.stdin); - pkt.reset(); - pkt.readFrom(session.stdout); - if(expectId != pkt.readInt()) { - throw new SFTPException("SFTP error, invalid packet id"); - } - checkType(pkt, expectType); - return pkt; - } - } else { - Integer id = new Integer(pkt.getId()); - ReplyLock reply = new ReplyLock(expectType); - replyLocks.put(id, reply); - txQueue.putLast(pkt); - return reply.expect(); - } - } - - private void startNonblocking() { - txQueue = new Queue(); - replyLocks = new Hashtable(); - /* - * NOTE: We could implement custom I/O streams and insert them to handle - * the work in the tx/rx threads of the SSH2StreamChannel though the - * gains are not huge. - */ - Thread transmitter = new Thread(new Runnable() { - public void run() { - sftpTransmitLoop(); - } - }, "SSH2SFTPTX"); - Thread receiver = new Thread(new Runnable() { - public void run() { - sftpReceiveLoop(); - } - }, "SSH2SFTPRX"); - - transmitter.setDaemon(true); - receiver.setDaemon(true); - transmitter.start(); - receiver.start(); - } - - private void sftpTransmitLoop() { - SFTPPacket pkt; - try { - while((pkt = (SFTPPacket)txQueue.getFirst()) != null) { - pkt.writeTo(session.stdin); - releasePacket(pkt); - } - } catch (SFTPException e) { - connection.getLog().error("SSH2SFTPClient", - "sftpTransmitLoop", - "session was probably closed"); - terminate(); - } - } - - private void sftpReceiveLoop() { - SFTPPacket pkt; - Integer id; - ReplyLock reply; - try { - while(true) { - pkt = createPacket(); - - pkt.reset(); - pkt.readFrom(session.stdout); - - id = new Integer(pkt.readInt()); - reply = (ReplyLock)replyLocks.remove(id); - if(reply == null) { - connection.getLog().error("SSH2SFTPClient", - "sftpReceiveLoop", - "received unsent id: " + - id); - connection.getLog().debug2("SSH2SFTPClient", - "sftpReceiveLoop", - "sftp packet: ", - pkt.getData(), - 0, - pkt.getLength() + 5); - throw new SFTPException("Invalid reply"); - } - - reply.received(pkt); - } - } catch (SFTPDisconnectException e) { - connection.getLog().debug("SSH2SFTPClient", - "sftpReceiveLoop", - "session was closed"); - } catch (SFTPException e) { - connection.getLog().error("SSH2SFTPClient", - "sftpReceiveLoop", - "session was probably closed"); - } finally { - terminate(); - } - } - - private SFTPPacket createPacket(int type, FileHandle handle) { - SFTPPacket pkt = createPacket(type); - pkt.writeString(handle.getHandle()); - return pkt; - } - - private SFTPPacket createPacket(int type) { - SFTPPacket pkt = createPacket(); - pkt.reset(type, getNextId()); - return pkt; - } - - private SFTPPacket createPacket() { - SFTPPacket pkt; - synchronized(pktPool) { - if(pktPoolCnt == 0) { - pkt = new SFTPPacket(); - } else { - pkt = pktPool[--pktPoolCnt]; - } - } - return pkt; - } - - private void releasePacket(SFTPPacket pkt) { - synchronized(pktPool) { - if(pktPoolCnt < POOL_SIZE) { - pktPool[pktPoolCnt++] = pkt; - } - } - } - - private void checkType(SFTPPacket pkt, int type) throws SFTPException { - if(pkt.getType() == SSH_FXP_STATUS) { - int error = pkt.readInt(); - if(error == SSH_FX_OK) - return; - if(error == SSH_FX_EOF) - throw new SFTPEOFException(); - if(error == SSH_FX_NO_SUCH_FILE) - throw new SFTPNoSuchFileException(); - if(error == SSH_FX_PERMISSION_DENIED) - throw new SFTPPermissionDeniedException(); - if(error == SSH_FX_CONNECTION_LOST) - throw new SFTPDisconnectException(); - // !!! TODO: provide error - throw new SFTPException("Got error: " + error); - } else if(pkt.getType() != type) { - // !!! TODO: provide fatal error - throw new SFTPException("Got unexpected packet: " + pkt.getType()); - } - } - - private void cancelAllAsync() { - if(replyLocks == null) { - return; - } - Enumeration ids = replyLocks.keys(); - while(ids.hasMoreElements()) { - ReplyLock l = (ReplyLock)replyLocks.remove(ids.nextElement()); - l.cancel(); - } - } - - private synchronized int getNextId() { - return id++; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2SFTPFileBrowser.java b/src/main/java/com/mindbright/ssh2/SSH2SFTPFileBrowser.java deleted file mode 100644 index 760c10a..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2SFTPFileBrowser.java +++ /dev/null @@ -1,154 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import com.isnetworks.ssh.AbstractFileBrowser; -import com.isnetworks.ssh.SSHException; -import com.isnetworks.ssh.FileListItem; -import com.isnetworks.ssh.FileDisplay; - -public class SSH2SFTPFileBrowser extends AbstractFileBrowser { - - private SSH2Connection connection; - private SSH2SFTPClient client; - private String cwd; - - public SSH2SFTPFileBrowser(SSH2Connection connection, - FileDisplay fileDisplay) - { - super(fileDisplay, null); - this.connection = connection; - } - - public void fileDoubleClicked(FileListItem file) throws SSHException { - if(file.isDirectory()) { - changeDirectory(cwd + "/" + file.getName()); - } - } - - public void refresh() throws SSHException { - SSH2SFTP.FileHandle handle = null; - try { - handle = client.opendir(cwd); - SSH2SFTP.FileAttributes[] list = client.readdir(handle); - FileListItem[] files = new FileListItem[list.length]; - int li = 0; - - if(!cwd.equals("/") && !cwd.equals("")) { - files[li++] = new FileListItem("..", "", true, "/"); - } - - for(int i = 0; i < list.length; i++) { - String name = list[i].name; - if(!("..".equals(name)) && !(".".equals(name))) { - files[li++] = new FileListItem(name, cwd, - list[i].isDirectory(), - "/", list[i].size); - } - } - - FileListItem[] tmp = new FileListItem[li]; - System.arraycopy(files, 0, tmp, 0, li); - files = tmp; - - FileListItem.sort(files); - String dir = cwd; - if(!dir.endsWith("/")) { - dir += "/"; - } - mFileDisplay.setFileList(files, dir); - } catch (Exception e) { - throw new SSHException(e.getMessage()); - } finally { - try { client.close(handle); } - catch (Exception e) { /* don't care */ } - } - } - - public void delete(FileListItem[] files) throws SSHException { - String file = null; - try { - for(int i = 0; i < files.length; i++) { - file = files[i].getAbsolutePath(); - SSH2SFTP.FileAttributes attrs = client.stat(file); - if(attrs.isDirectory()) { - client.rmdir(file); - } else { - client.remove(file); - } - } - } catch (SSH2SFTP.SFTPException e) { - throw new SSHException("Unable to delete " + file + - " - may not have permission or directory may not be empty"); - } - } - - public void initialize() throws SSHException { - try { - client = new SSH2SFTPClient(connection, true); - SSH2SFTP.FileAttributes attrs = client.realpath("."); - cwd = attrs.lname; - refresh(); - } catch (SSH2SFTP.SFTPException e) { - throw new SSHException("Could not start sftp session: " + - e.getMessage()); - } - } - - public void makeDirectory(String directoryName) throws SSHException { - try { - if(!directoryName.startsWith("/")) { - directoryName = cwd + "/" + directoryName; - } - client.mkdir(directoryName, new SSH2SFTP.FileAttributes()); - } catch (SSH2SFTP.SFTPException e) { - throw new SSHException(e.getMessage()); - } - } - - public void rename(FileListItem file, String newFileName) - throws SSHException - { - try { - client.rename(file.getAbsolutePath(), file.getParent() + "/" + - newFileName); - } catch (SSH2SFTP.SFTPException e) { - throw new SSHException(e.getMessage()); - } - } - - public void changeDirectory(String newDir) throws SSHException { - try { - if(!newDir.startsWith("/")) { - newDir = cwd + "/" + newDir; - } - SSH2SFTP.FileAttributes attrs = client.realpath(newDir); - SSH2SFTP.FileHandle handle = client.opendir(newDir); - newDir = attrs.lname; - client.close(handle); - } catch (SSH2SFTP.SFTPException e) { - newDir = cwd; - } - cwd = newDir; - } - - public void disconnect() { - if(client != null) { - client.terminate(); - } - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2SFTPTransfer.java b/src/main/java/com/mindbright/ssh2/SSH2SFTPTransfer.java deleted file mode 100644 index 6c57157..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2SFTPTransfer.java +++ /dev/null @@ -1,222 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; - -import com.mindbright.sshcommon.SSHFileTransfer; -import com.mindbright.sshcommon.SSHFileTransferProgress; - -public class SSH2SFTPTransfer implements SSHFileTransfer, - SSH2SFTP.AsyncListener -{ - - private SSHFileTransferProgress progress; - private SSH2SFTPClient client; - private File cwd; - - public SSH2SFTPTransfer(File cwd, SSH2Connection connection) - throws SSH2Exception - { - try { - this.cwd = cwd; - this.client = new SSH2SFTPClient(connection, false); - } catch (SSH2SFTP.SFTPException e) { - throw new SSH2FatalException("Could not start sftp session", e); - } - } - - public void setProgress(SSHFileTransferProgress progress) { - this.progress = progress; - } - - public void copyToRemote(String[] localFiles, String remoteFile, - boolean recursive) - throws IOException - { - if(remoteFile == null || remoteFile.equals("")) - remoteFile = "."; - - for(int i = 0; i < localFiles.length; i++) { - File lf = new File(localFiles[i]); - if(!lf.isAbsolute()) - lf = new File(cwd, localFiles[i]); - if(!lf.isFile() && !lf.isDirectory()) { - throw new IOException("File: " + lf.getName() + - " is not a regular file or directory"); - } - try { - writeFileToRemote(lf, remoteFile, recursive); - } catch (SSH2SFTP.SFTPException e) { - throw new IOException("Error writing file: " + e.getMessage()); - } - } - } - - public void copyToLocal(String localFile, String remoteFiles[], - boolean recursive) - throws IOException - { - if(localFile == null || localFile.equals("")) - localFile = "."; - - File lf = new File(localFile); - if(!lf.isAbsolute()) - lf = new File(cwd, localFile); - - if(lf.exists() && !lf.isFile() && !lf.isDirectory()) { - throw new IOException("File: " + localFile + - " is not a regular file or directory"); - } - - for(int i = 0; i < remoteFiles.length; i++) { - String fName = remoteFiles[i]; - try { - readFileFromRemote(fName, localFile, recursive); - } catch (SSH2SFTP.SFTPException e) { - throw new IOException(e.getMessage()); - } - } - } - - private void writeFileToRemote(File file, String remoteFile, - boolean recursive) - throws IOException, SSH2SFTP.SFTPException - { - String fName = file.getName(); - if(file.isDirectory() && recursive) { - writeDirToRemote(file, remoteFile); - } else if(file.isFile()) { - if(progress != null) - progress.startFile(fName, file.length()); - - FileInputStream fin = new FileInputStream(file); - SSH2SFTP.FileHandle fh = null; - try { - fh = client.open(remoteFile + fName, - SSH2SFTP.SSH_FXF_WRITE | - SSH2SFTP.SSH_FXF_TRUNC | - SSH2SFTP.SSH_FXF_CREAT, - new SSH2SFTP.FileAttributes()); - fh.addAsyncListener(this); - client.writeFully(fh, fin); - } finally { - fin.close(); - } - - if(progress != null) - progress.endFile(); - } else { - throw new IOException("Not ordinary file: " + fName); - } - } - - private void writeDirToRemote(File dir, String remoteDir) - throws IOException, SSH2SFTP.SFTPException - { - if(progress != null) - progress.startDir(dir.getAbsolutePath()); - remoteDir += dir.getName(); - if(!remoteDir.endsWith("/")) { - remoteDir += "/"; - } - try { - client.stat(remoteDir); - } catch (SSH2SFTP.SFTPException e) { - client.mkdir(remoteDir, new SSH2SFTP.FileAttributes()); - } - String[] dirList = dir.list(); - for(int i = 0; i < dirList.length; i++) { - File f = new File(dir, dirList[i]); - writeFileToRemote(f, remoteDir, true); - } - if(progress != null) - progress.endDir(); - } - - private void readFileFromRemote(String fName, String localFile, - boolean recursive) - throws IOException, SSH2SFTP.SFTPException - { - SSH2SFTP.FileAttributes attrs = client.stat(fName); - SSH2SFTP.FileHandle fh = null; - - File targetFile = new File(localFile); - if(targetFile.isDirectory()) { - String f = fName; - int n = fName.lastIndexOf('/'); - if(n != -1) { - f = fName.substring(n + 1); - } - targetFile = new File(targetFile, f); - } - - if(attrs.isDirectory() && recursive) { - if(targetFile.exists()) { - if(!targetFile.isDirectory()) { - throw new IOException("Invalid target " + - targetFile.getName() + - ", must be a directory"); - } - } else { - if(!targetFile.mkdir()) { - throw new IOException("Could not create directory: " + - targetFile.getName()); - } - } - fh = client.opendir(fName); - SSH2SFTP.FileAttributes[] list = client.readdir(fh); - for(int i = 0; i < list.length; i++) { - String name = list[i].name; - if("..".equals(name) || ".".equals(name)) { - continue; - } - readFileFromRemote(fName + "/" + name, - targetFile.getAbsolutePath(), recursive); - } - } else if(attrs.isFile()) { - FileOutputStream fout = new FileOutputStream(targetFile); - try { - fh = client.open(fName, SSH2SFTP.SSH_FXF_READ, - new SSH2SFTP.FileAttributes()); - if(progress != null) - progress.startFile(targetFile.getName(), attrs.size); - fh.addAsyncListener(this); - client.readFully(fh, fout); - if(progress != null) - progress.endFile(); - } finally { - fout.close(); - } - } else { - throw new IOException("Not ordinary file: " + fName); - } - } - - public void abort() { - if(client != null) { - client.terminate(); - } - } - - public void progress(long size) { - progress.progress((int)size); - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2SessionChannel.java b/src/main/java/com/mindbright/ssh2/SSH2SessionChannel.java deleted file mode 100644 index e5ff22d..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2SessionChannel.java +++ /dev/null @@ -1,416 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.IOException; - -import com.mindbright.util.InputStreamPipe; -import com.mindbright.util.OutputStreamPipe; - -/** - * This class implements session channels as defined in the connection protocol - * spec. It can be used to start shells, commands, and subsystems on the server. - * An instance of this class is created with the newSession methods - * found in SSH2Connection. - * - * @see SSH2Channel - * @see SSH2Connection - */ -public final class SSH2SessionChannel extends SSH2StreamChannel { - - private final static int DEFAULT_STDIO_BUFFER_SIZE = 65536; - - private class StdErrDummyStream extends OutputStream { - public void write(int b) { - write(new byte[] { (byte)b }, 0, 1); - } - public void write(byte[] buf, int off, int len) { - connection.getLog().info("StdErrDummyStream", - new String(buf, off, len)); - } - } - - public static final int EXIT_ON_CLOSE = -1; - public static final int EXIT_ON_FAILURE = -2; - - protected boolean started; - protected boolean blocking; - protected boolean exited; - protected Object exitMonitor; - protected Object reqMonitor; - protected boolean exitedOnSignal; - protected int exitStatus; - protected boolean reqStatus; - protected boolean x11Mapping; - - protected InputStream stdout; - protected OutputStream stdin; - protected InputStreamPipe stderr; - protected OutputStream stderrW; - - protected SSH2SessionChannel(SSH2Connection connection) { - super(SSH2Connection.CH_TYPE_SESSION, connection, connection, - new InputStreamPipe(DEFAULT_STDIO_BUFFER_SIZE), - new OutputStreamPipe()); - this.rxInitWinSz = 16384; - this.rxCurrWinSz = 16384; - this.rxMaxPktSz = 8192; - this.started = false; - this.exited = false; - this.blocking = true; - this.reqStatus = true; - this.x11Mapping = false; - this.exitMonitor = new Object(); - this.reqMonitor = new Object(); - - try { - this.stdin = new OutputStreamPipe(); - this.stdout = new InputStreamPipe(DEFAULT_STDIO_BUFFER_SIZE); - this.stderrW = new StdErrDummyStream(); - ((InputStreamPipe)this.stdout).connect((OutputStreamPipe)out); - ((OutputStreamPipe)this.stdin).connect((InputStreamPipe)in); - } catch (IOException e) { - connection.getLog().error("SSH2SessionChannel", "", - "can't happen, bug somewhere!?!"); - } - } - - public boolean doShell() { - if(started || openStatus() != SSH2Channel.STATUS_OPEN) { - return false; - } - SSH2TransportPDU pdu = getRequestPDU(SSH2Connection.CH_REQ_SHELL); - started = sendAndBlockUntilReply(pdu); - return started; - } - - public boolean doSingleCommand(String command) { - if(started || openStatus() != SSH2Channel.STATUS_OPEN) { - return false; - } - SSH2TransportPDU pdu = getRequestPDU(SSH2Connection.CH_REQ_EXEC); - pdu.writeString(command); - started = sendAndBlockUntilReply(pdu); - return started; - } - - public boolean doSubsystem(String subsystem) { - if(started || openStatus() != SSH2Channel.STATUS_OPEN) { - return false; - } - SSH2TransportPDU pdu = getRequestPDU(SSH2Connection.CH_REQ_SUBSYSTEM); - pdu.writeString(subsystem); - started = sendAndBlockUntilReply(pdu); - return started; - } - - public int waitForExit(long timeout) { - synchronized (exitMonitor) { - if(!exited) { - try { exitMonitor.wait(timeout); } - catch (InterruptedException e) { /* don't care */ } - } - // !!! TODO: Handle signals, maybe should throw exception ??? - return exitStatus; - } - } - - public void changeStdOut(OutputStream out) { - this.out = out; - } - - public void changeStdIn(InputStream in) { - this.in = in; - } - - public void changeStdErr(OutputStream stderrW) { - this.stderrW = stderrW; - } - - public void enableStdErr() { - this.stderrW = new OutputStreamPipe(); - this.stderr = new InputStreamPipe(); - try { - this.stderr.connect((OutputStreamPipe)stderrW); - } catch (IOException e) { - connection.getLog().error("SSH2SessionChannel", "enableStdErr", - "can't happen, bug somewhere!?!"); - } - } - - public InputStream getStdOut() { - return stdout; - } - - public OutputStream getStdIn() { - return stdin; - } - - public InputStream getStdErr() { - return stderr; - } - - public void stdinWriteNoLatency(String str) { - byte[] b = str.getBytes(); - stdinWriteNoLatency(b, 0, b.length); - } - - public void stdinWriteNoLatency(byte[] buf, int off, int len) { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_CHANNEL_DATA, - len + 128); - pdu.writeInt(peerChanId); - pdu.writeInt(len); - pdu.writeRaw(buf, off, len); - transmit(pdu); - txCounter += len; - } - - public void stdinWriteNoLatency(int c) { - stdinWriteNoLatency(new byte[] { (byte)c }, 0, 1); - } - - public void setBlocking(boolean value) { - synchronized (reqMonitor) { - this.blocking = value; - } - } - - public boolean requestPTY(String termType, int rows, int cols, - byte[] terminalModes) { - if(openStatus() != SSH2Channel.STATUS_OPEN) { - return false; - } - - SSH2TransportPDU pdu = getRequestPDU(SSH2Connection.CH_REQ_PTY); - pdu.writeString(termType); - pdu.writeInt(cols); - pdu.writeInt(rows); - pdu.writeInt(0); - pdu.writeInt(0); - if(terminalModes == null) - terminalModes = new byte[] { 0 }; - pdu.writeString(terminalModes); - return sendAndBlockUntilReply(pdu); - } - - public boolean requestX11Forward(String localAddr, int localPort, - byte[] cookie, boolean single, int screen) { - connection.getPreferences().setX11LocalAddr(localAddr); - connection.getPreferences().setX11LocalPort(localPort); - connection.getPreferences().setX11Cookie(cookie); - return requestX11Forward(single, screen); - } - - public boolean requestX11Forward(boolean single, int screen) { - if(openStatus() != SSH2Channel.STATUS_OPEN || - x11Mapping) { - if(x11Mapping) - connection.getLog().warning("SSH2SessionChannel", - "requesting x11 forward multiple times"); - return false; - } - - byte[] x11FakeCookie = connection.getX11FakeCookie(); - StringBuffer cookieBuf = new StringBuffer(); - for(int i = 0; i < 16; i++) { - String b = Integer.toHexString(x11FakeCookie[i] & 0xff); - if(b.length() == 1) { - b = "0" + b; - } - cookieBuf.append(b); - } - String cookie = cookieBuf.toString(); - SSH2TransportPDU pdu = getRequestPDU(SSH2Connection.CH_REQ_X11); - - pdu.writeBoolean(single); - pdu.writeString("MIT-MAGIC-COOKIE-1"); - pdu.writeString(cookie); - pdu.writeInt(screen); - - x11Mapping = sendAndBlockUntilReply(pdu); - - if(x11Mapping) { - connection.setX11Mapping(single); - } - - return x11Mapping; - } - - public boolean setEnvironment(String name, String value) { - if(openStatus() != SSH2Channel.STATUS_OPEN) { - return false; - } - - SSH2TransportPDU pdu = getRequestPDU(SSH2Connection.CH_REQ_ENV); - pdu.writeString(name); - pdu.writeString(value); - return sendAndBlockUntilReply(pdu); - } - - public void sendWindowChange(int rows, int cols) { - SSH2TransportPDU pdu = - getNoReplyRequestPDU(SSH2Connection.CH_REQ_WINCH); - pdu.writeInt(cols); - pdu.writeInt(rows); - pdu.writeInt(0); - pdu.writeInt(0); - transmit(pdu); - } - - public void sendSignal(int signal) { - SSH2TransportPDU pdu = - getNoReplyRequestPDU(SSH2Connection.CH_REQ_SIGNAL); - pdu.writeInt(signal); - transmit(pdu); - } - - public void doExit(int status, boolean onSignal) { - synchronized (exitMonitor) { - if(!exited) { - exited = true; - if(x11Mapping) { - x11Mapping = false; - connection.clearX11Mapping(); - } - this.exitedOnSignal = onSignal; - this.exitStatus = status; - exitMonitor.notifyAll(); - } - } - } - - protected void extData(SSH2TransportPDU pdu) { - int type = pdu.readInt(); - if(type != SSH2.EXTENDED_DATA_STDERR) { - connection.getLog().error("SSH2SessionChannel", "extData", - "extended data of unknown type: " + type); - } else { - try { - int len = pdu.readInt(); - stderrW.write(pdu.getData(), pdu.getRPos(), len); - } catch (IOException e) { - connection.getLog().error("SSH2SessionChannel", "extData", - "error writing to stderr: " + - e.getMessage()); - } - } - } - - protected void closeImpl() { - super.closeImpl(); - doExit(EXIT_ON_CLOSE, false); - // - // Just to make sure everybody gets released - // - requestFailure((SSH2TransportPDU)null); - } - - protected boolean openFailureImpl(int reasonCode, String reasonText, - String langTag) { - doExit(EXIT_ON_FAILURE, false); - return false; - } - - protected void requestSuccess(SSH2TransportPDU pdu) { - synchronized (reqMonitor) { - reqStatus = true; - reqMonitor.notify(); - } - } - - protected void requestFailure(SSH2TransportPDU pdu) { - synchronized (reqMonitor) { - reqStatus = false; - reqMonitor.notify(); - } - } - - protected void handleRequestImpl(String type, boolean wantReply, - SSH2TransportPDU pdu) { - - // !!! TODO: Handle exit properly... - - if(type.equals(SSH2Connection.CH_REQ_EXIT_STAT)) { - int status = pdu.readInt(); - doExit(status, false); - - connection.getLog().notice("SSH2SessionChannel", - "session exit with status " + status); - - } else if(type.equals(SSH2Connection.CH_REQ_EXIT_SIG)) { - int sig = pdu.readInt(); - boolean core = pdu.readBoolean(); - String msg = new String(pdu.readString()); - doExit(sig, true); - - // !!! TODO: store msg/core also !!! - - connection.getLog().notice("SSH2SessionChannel", - "session exit with signal " + sig + - ", " + msg + ", core dumped? " + core); - } else { - connection.getLog().error("SSH2SessionChannel", "handleRequestImpl", - "got unknown channel-request: " + type); - if(wantReply) { - SSH2TransportPDU reply = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_CHANNEL_FAILURE); - reply.writeInt(peerChanId); - transmit(reply); - } - } - } - - private boolean sendAndBlockUntilReply(SSH2TransportPDU pdu) { - synchronized (reqMonitor) { - transmit(pdu); - try { - if(blocking) - reqMonitor.wait(); - } catch (InterruptedException e) { - connection.getLog().error("SSH2SessionChannel", - "sendAndBlockUntilReply", - "wait for reply interrupted"); - } - boolean s = reqStatus; - reqStatus = true; - return s; - } - } - - private SSH2TransportPDU getRequestPDU(String type) { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_CHANNEL_REQUEST); - pdu.writeInt(peerChanId); - pdu.writeString(type); - synchronized (reqMonitor) { - pdu.writeBoolean(blocking); - } - return pdu; - } - - private SSH2TransportPDU getNoReplyRequestPDU(String type) { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_CHANNEL_REQUEST); - pdu.writeInt(peerChanId); - pdu.writeString(type); - pdu.writeBoolean(false); - return pdu; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2Signature.java b/src/main/java/com/mindbright/ssh2/SSH2Signature.java deleted file mode 100644 index e59abf7..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2Signature.java +++ /dev/null @@ -1,177 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.util.Hashtable; - -import com.mindbright.jca.security.Signature; -import com.mindbright.jca.security.PublicKey; -import com.mindbright.jca.security.PrivateKey; -import com.mindbright.jca.security.InvalidKeyException; -import com.mindbright.jca.security.SignatureException; - -public abstract class SSH2Signature implements SSH2PKISigner { - - private static Hashtable algorithms; - - static { - algorithms = new Hashtable(); - algorithms.put("ssh-dss", "com.mindbright.ssh2.SSH2DSS"); - algorithms.put("ssh-rsa", "com.mindbright.ssh2.SSH2RSA"); - }; - - protected String algorithm; - protected Signature signature; - protected PrivateKey privateKey; - protected PublicKey publicKey; - protected byte[] pubKeyBlob; - - public static SSH2Signature getInstance(String algorithm) - throws SSH2Exception - { - SSH2Signature impl = getEncodingInstance(algorithm); - impl.init(algorithm); - return impl; - } - - public static SSH2Signature getEncodingInstance(String algorithm) - throws SSH2Exception - { - SSH2Signature impl = null; - String className = (String)algorithms.get(algorithm); - try { - impl = (SSH2Signature)Class.forName(className).newInstance(); - } catch (Exception e) { - // !!! TODO - throw new SSH2FatalException("Public key algorithm '" + algorithm + - "' not supported"); - } - return impl; - } - - private void init(String algorithm) throws SSH2Exception { - this.algorithm = algorithm; - String sigAlg = getSignatureAlgorithm(); - try { - signature = Signature.getInstance(sigAlg); - } catch (Exception e) { - // !!! TODO - throw new SSH2FatalException("Error initializing SSH2Signature: " + - algorithm + "/" + sigAlg + " - " + e); - } - } - - protected SSH2Signature() { - } - - public final String getAlgorithmName() { - return algorithm; - } - - public final byte[] getPublicKeyBlob() throws SSH2SignatureException { - if(pubKeyBlob == null) { - try { - pubKeyBlob = encodePublicKey(publicKey); - } catch (SSH2Exception e) { - throw new SSH2SignatureException(e.getMessage()); - } - } - return pubKeyBlob; - } - - public final PublicKey getPublicKey() throws SSH2SignatureException { - if(publicKey == null) { - try { - publicKey = decodePublicKey(pubKeyBlob); - } catch (SSH2Exception e) { - throw new SSH2SignatureException(e.getMessage()); - } - } - return publicKey; - } - - public final void setPublicKey(PublicKey publicKey) { - this.publicKey = publicKey; - } - - public void setIncompatibility(SSH2Transport transport) { - // Do nothing here, derived class might be interested... - } - - public final void initSign(PrivateKey privateKey) throws SSH2Exception { - this.privateKey = privateKey; - try { - signature.initSign(privateKey); - } catch (InvalidKeyException e) { - throw new SSH2FatalException("SSH2Signature.initSign, invalid key: " - + e.getMessage()); - } - } - - public final void initVerify(PublicKey publicKey) throws SSH2Exception { - initVerify(encodePublicKey(publicKey)); - } - - public final void initVerify(byte[] pubKeyBlob) throws SSH2Exception { - this.pubKeyBlob = pubKeyBlob; - this.publicKey = decodePublicKey(pubKeyBlob); - try { - signature.initVerify(publicKey); - } catch (InvalidKeyException e) { - throw new SSH2FatalException("SSH2Signature.initSign, invalid key: " - + e.getMessage()); - } - } - - public final byte[] sign(byte[] data) throws SSH2SignatureException { - try { - signature.update(data); - byte[] sigRaw = signature.sign(); - return encodeSignature(sigRaw); - } catch (SignatureException e) { - throw new SSH2SignatureException("Error in " + algorithm + - " sign: " + e.getMessage()); - } - } - - public final boolean verify(byte[] sigBlob, byte[] data) - throws SSH2SignatureException - { - try { - byte[] sigRaw = decodeSignature(sigBlob); - signature.update(data); - return signature.verify(sigRaw); - } catch (SignatureException e) { - throw new SSH2SignatureException("Error in " + algorithm + - " verify: " + e.getMessage()); - } - } - - protected abstract String getSignatureAlgorithm(); - - protected abstract byte[] encodePublicKey(PublicKey publicKey) - throws SSH2Exception; - - protected abstract PublicKey decodePublicKey(byte[] pubKeyBlob) - throws SSH2Exception; - - protected abstract byte[] encodeSignature(byte[] sigRaw); - - protected abstract byte[] decodeSignature(byte[] sigBlob) - throws SSH2SignatureException; - - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2SignatureException.java b/src/main/java/com/mindbright/ssh2/SSH2SignatureException.java deleted file mode 100644 index bedffb0..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2SignatureException.java +++ /dev/null @@ -1,25 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public class SSH2SignatureException extends SSH2Exception { - public SSH2SignatureException(String message) { - super(message); - } - public SSH2SignatureException(String message, Throwable rootCause) { - super(message, rootCause); - } -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2SimpleClient.java b/src/main/java/com/mindbright/ssh2/SSH2SimpleClient.java deleted file mode 100644 index 2d354ef..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2SimpleClient.java +++ /dev/null @@ -1,122 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.net.Socket; -import java.util.Properties; - -import com.mindbright.sshcommon.SSHConsoleRemote; - -import com.mindbright.util.SecureRandomAndPad; - -/** - * This class implements the most basic variant of a ssh2 client. It creates the - * transport, userauth, and connection layers (i.e. instances of - * SSH2Transport, SSH2UserAuth, and - * SSH2Connection). The only thing which needs to be provided is a - * connected socket to the server, user authentication data, and preferences for - * the transport layer (provided as ordinary java.util.Properties - * for convenience). The constructor is active in that it does all the required - * work to set up the complete protocol stack, hence it can throw exceptions - * which can occur. - *

- * This simple client can easily be used as the basis for example to build - * tunneling capabilities into any java app. requiring secure connections. For - * doing remote command execution and/or controlling input/output of a command - * or shell the class SSH2ConsoleRemote can be used to have easy - * access to command execution and/or input/output as - * java.io.InputStream and java.io.OutpuStream - * - * @see SSH2Transport - * @see SSH2Connection - * @see SSH2ConsoleRemote - */ -public class SSH2SimpleClient { - - protected SSH2Transport transport; - protected SSH2Connection connection; - protected SSH2UserAuth userAuth; - - /** - * Simple constructor to use when password authentication is sufficient. - * - * @param socket connected socket to ssh2 server - * @param rand source of randomness for padding and keys - * @param username name of user - * @param password password of user - * @param prefs preferences for transport layer - * - * @see SSH2TransportPreferences - */ - public SSH2SimpleClient(Socket socket, SecureRandomAndPad rand, - String username, String password, - Properties prefs) - throws SSH2Exception - { - this(socket, rand, - username, "password", new SSH2AuthPassword(password), - prefs); - } - - /** - * Constructor to use when other authentication than password is needed. - * - * @param socket connected socket to ssh2 server - * @param rand source of randomness for padding and keys - * @param username name of user - * @param authType type of authentication (e.g. publickey) - * @param authModule authentication module (e.g. SSH2AuthPublicKey) - * @param prefs preferences for transport layer - * - * @see SSH2TransportPreferences - */ - public SSH2SimpleClient(Socket socket, SecureRandomAndPad rand, - String username, - String authType, SSH2AuthModule authModule, - Properties prefs) - throws SSH2Exception - { - transport = new SSH2Transport(socket, - new SSH2TransportPreferences(prefs), - rand); - transport.boot(); - - if(!transport.waitForKEXComplete()) { - throw new SSH2FatalException("KEX failed"); - } - - SSH2Authenticator authenticator = new SSH2Authenticator(username); - - authenticator.addModule(authType, authModule); - - userAuth = new SSH2UserAuth(transport, authenticator); - if(!userAuth.authenticateUser("ssh-connection")) { - throw new SSH2FatalException("Permission denied"); - } - - connection = new SSH2Connection(userAuth, transport); - transport.setConnection(connection); - } - - public SSH2Transport getTransport() { - return transport; - } - - public SSH2Connection getConnection() { - return connection; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2SimpleSFTPShell.java b/src/main/java/com/mindbright/ssh2/SSH2SimpleSFTPShell.java deleted file mode 100644 index 868a753..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2SimpleSFTPShell.java +++ /dev/null @@ -1,564 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.awt.Frame; -import java.awt.BorderLayout; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; - -import com.mindbright.terminal.TerminalWin; -import com.mindbright.terminal.TerminalXTerm; -import com.mindbright.terminal.LineReaderTerminal; - -public final class SSH2SimpleSFTPShell implements Runnable { - Frame frame; - TerminalWin terminal; - LineReaderTerminal linereader; - SSH2Connection connection; - SSH2SFTPClient sftp; - - String localDir; - String remoteDir; - - public static final class ProgressBar implements SSH2SFTP.AsyncListener { - LineReaderTerminal linereader; - long totalSize; - long curSize; - long start; - static final String[] prefix = { "", "k", "M", "G", "T" }; - public ProgressBar(LineReaderTerminal linereader) { - this.linereader = linereader; - } - public void start(long totalSize) { - this.totalSize = totalSize; - this.curSize = 0; - start = System.currentTimeMillis(); - } - public void progress(long size) { - long now = System.currentTimeMillis(); - - curSize += size; - int perc = (int)(totalSize > 0 ? - ((100 * curSize) / totalSize) : 100); - int i; - StringBuffer buf = new StringBuffer(); - - buf.append("\r " + perc + "%\t|"); - int len = (int)((double)32 * ((double)perc / 100)); - - for(i = 0; i < len; i++) { - buf.append('*'); - } - for(i = len; i < 32; i++) { - buf.append(' '); - } - long printSize = curSize; - i = 0; - while(printSize >= 100000) { - i++; - printSize >>>= 10; - } - buf.append("| " + printSize + " " + prefix[i] + "bytes"); - - long elapsed = (now - start); - if(elapsed == 0) { - elapsed = 1; - } - - int curSpeed = (int)((double)curSize / ((double)elapsed / 1000)); - - i = 0; - while(curSpeed >= 100000) { - i++; - curSpeed >>>= 10; - } - buf.append(" (" + curSpeed + " " + prefix[i] + "B/sec) "); - - linereader.print(buf.toString()); - } - } - - public SSH2SimpleSFTPShell(SSH2Connection connection, String title) { - this.connection = connection; - this.frame = new Frame(); - this.terminal = new TerminalWin(frame, new TerminalXTerm()); - linereader = new LineReaderTerminal(terminal); - - frame.setLayout(new BorderLayout()); - frame.add(terminal.getPanelWithScrollbar(), - BorderLayout.CENTER); - - frame.setTitle(title); - - frame.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - linereader.breakPromptLine("Exit"); - sftp.terminate(); - } - }); - - frame.pack(); - frame.show(); - - Thread shell = new Thread(this); - - shell.setDaemon(true); - shell.start(); - } - - public void run() { - linereader.println("Starting sftp..."); - - try { - netscape.security.PrivilegeManager.enablePrivilege("UniversalFileAccess"); - } catch (netscape.security.ForbiddenTargetException e) { - // !!! - } - - doHelp(); - - try { - sftp = new SSH2SFTPClient(connection, false); - - File f = new File("."); - localDir = f.getCanonicalPath(); - - SSH2SFTP.FileAttributes attrs = sftp.realpath("."); - remoteDir = attrs.lname; - - linereader.println("local dir:\t" + localDir); - linereader.println("remote dir:\t" + remoteDir); - - boolean keepRunning = true; - while(keepRunning) { - try { - SSH2SFTP.FileHandle handle = null; - String cmdLine = linereader.promptLine("sftp> ", null, - false); - String[] argv; - String cmd; - cmdLine = cmdLine.trim(); - - if(cmdLine.equals("")) { - doHelp(); - continue; - } - - argv = makeArgv(cmdLine); - cmd = argv[0]; - - if(cmd.equals("ls")) { - try { - handle = sftp.opendir(remoteDir); - SSH2SFTP.FileAttributes[] list = sftp.readdir(handle); - for(int i = 0; i < list.length; i++) { - linereader.println(list[i].lname); - } - } finally { - try { sftp.close(handle); } - catch (Exception e) { /* don't care */ } - } - - } else if(cmd.equals("cd")) { - if(argv.length < 2) { - doHelp(); - continue; - } - String newDir = expandRemote(argv[1]); - try { - attrs = sftp.realpath(newDir); - } catch (SSH2SFTP.SFTPException e) { - linereader.println(newDir + - ": No such remote directory."); - continue; - } - newDir = attrs.lname; - try { - handle = sftp.opendir(newDir); - sftp.close(handle); - remoteDir = newDir; - linereader.println("remote: " + remoteDir); - } catch (SSH2SFTP.SFTPException e) { - linereader.println(newDir + ": Not a remote directory."); - } - - } else if(cmd.equals("lls")) { - f = new File(localDir); - String[] list = f.list(); - if(list == null) { - linereader.print(localDir + - " is empty or not accessible"); - continue; - } - - for(int i = 0; i < list.length; i++) { - f = new File(localDir + File.separator + list[i]); - linereader.print((f.isDirectory() ? "d" : "-") + - (f.canRead() ? "r" : "-") + - (f.canWrite() ? "w" : "-") + "\t"); - linereader.print(f.length() + "\t"); - - java.util.Date d = new java.util.Date(f.lastModified()); - java.text.DateFormat df = - java.text.DateFormat.getDateInstance(); - linereader.print(df.format(d) + "\t"); - linereader.println(list[i]); - } - - } else if(cmd.equals("lcd")) { - if(argv.length < 2) { - doHelp(); - continue; - } - String newDir; - newDir = expandLocal(argv[1]); - f = new File(newDir); - if(f.exists() && f.isDirectory() && f.canRead()) { - localDir = f.getCanonicalPath(); - linereader.println("local: " + localDir); - } else { - linereader.println(newDir + ": No such local directory"); - } - - } else if(cmd.equals("get")) { - if(argv.length < 2) { - doHelp(); - continue; - } - - String localFile = argv[1]; // Default to same name - String remoteFile = expandRemote(localFile); - - localFile = localFile.replace('/', File.separatorChar); - - if(argv.length > 2) { - localFile = argv[2]; - } - localFile = expandLocal(localFile); - - handle = sftp.open(remoteFile, - SSH2SFTP.SSH_FXF_READ, - new SSH2SFTP.FileAttributes()); - - attrs = sftp.fstat(handle); - - linereader.println("download from remote '" + - remoteFile + "',"); - linereader.println(" to local '" + - localFile + "', " + attrs.size + - " bytes"); - - java.io.RandomAccessFile file = - new java.io.RandomAccessFile(localFile, "rw"); - - int len = (int)attrs.size; - int foffs = 0; - int cnt = 0; - - ProgressBar bar = new ProgressBar(linereader); - handle.addAsyncListener(bar); - bar.start(len); - - while(foffs < len) { - int n = (32768 < (len - foffs) ? 32768 : - (int)(len - foffs)); - sftp.read(handle, foffs, file, n); - foffs += n; - if(++cnt == 24) { - cnt = 0; - handle.asyncWait(12); - } - if(linereader.ctrlCPressed()) { - handle.asyncClose(); - } - } - handle.asyncWait(); - - linereader.println(""); - - file.close(); - sftp.close(handle); - - } else if(cmd.equals("put")) { - if(argv.length < 2) { - doHelp(); - continue; - } - String remoteFile = argv[1]; // Default to same name - String localFile = expandLocal(remoteFile); - - remoteFile = remoteFile.replace(File.separatorChar, - '/'); - - if(argv.length > 2) { - remoteFile = argv[2]; - } - remoteFile = expandRemote(remoteFile); - - handle = sftp.open(remoteFile, - SSH2SFTP.SSH_FXF_WRITE | - SSH2SFTP.SSH_FXF_TRUNC | - SSH2SFTP.SSH_FXF_CREAT, - new SSH2SFTP.FileAttributes()); - f = new File(localFile); - FileInputStream fin = new FileInputStream(f); - - linereader.println("upload to remote '" + - remoteFile + "',"); - linereader.println(" from local '" + - localFile + "', " + f.length() + - " bytes"); - - ProgressBar bar = new ProgressBar(linereader); - handle.addAsyncListener(bar); - bar.start((int)f.length()); - - sftp.writeFully(handle, fin); - - /* !!! Can't interrupt now !!! - if(linereader.ctrlCPressed()) { - handle.asyncClose(); - } - */ - - linereader.println(""); - fin.close(); - - } else if(cmd.equals("pwd")) { - linereader.println("local dir:\t" + localDir); - linereader.println("remote dir:\t" + remoteDir); - - } else if(cmd.equals("rm")) { - if(argv.length < 2) { - doHelp(); - continue; - } - sftp.remove(expandRemote(argv[1])); - - } else if(cmd.startsWith("ren")) { - if(argv.length < 3) { - doHelp(); - continue; - } - sftp.rename(expandRemote(argv[1]), - expandRemote(argv[2])); - - } else if(cmd.startsWith("lren")) { - if(argv.length < 3) { - doHelp(); - continue; - } - f = new File(expandLocal(argv[1])); - f.renameTo(new File(expandLocal(argv[2]))); - - } else if(cmd.equals("lrm") || cmd.equals("lrmdir")) { - if(argv.length < 2) { - doHelp(); - continue; - } - f = new File(expandLocal(argv[1])); - f.delete(); - - } else if(cmd.equals("rmdir")) { - if(argv.length < 2) { - doHelp(); - continue; - } - sftp.rmdir(expandRemote(argv[1])); - - } else if(cmd.equals("mkdir")) { - if(argv.length < 2) { - doHelp(); - continue; - } - sftp.mkdir(expandRemote(argv[1]), - new SSH2SFTP.FileAttributes()); - - } else if(cmd.equals("lmkdir")) { - if(argv.length < 2) { - doHelp(); - continue; - } - f = new File(expandLocal(argv[1])); - f.mkdir(); - - } else if(cmd.equals("q") || cmd.equals("quit")) { - linereader.println("exiting..."); - keepRunning = false; - - } else { - doHelp(); - } - } catch (SSH2SFTP.SFTPNoSuchFileException e) { - linereader.println("No such file or directory"); - } catch (SSH2SFTP.SFTPPermissionDeniedException e) { - linereader.println("Permission denied"); - } catch (SSH2SFTP.SFTPAsyncAbortException e) { - linereader.println(""); - linereader.println("Async transfer aborted"); - } - } - } catch (SSH2SFTP.SFTPDisconnectException e) { - /* Exit because session was closed */ - } catch (SSH2SFTP.SFTPException e) { - String msg = e.getMessage(); - linereader.println("sftp error: " + ((msg != null && - msg.length() > 0) ? msg : - e.toString())); - } catch (LineReaderTerminal.ExternalMessageException e) { - /* Exit on window close */ - frame.dispose(); - return; - } catch (Exception e) { - System.out.println("Fatal error in SFTP:"); - e.printStackTrace(); - linereader.println("fatal error: " + e); - } - - try { - linereader.promptLine("\n\rPress to exit sftp shell", null, - false); - } catch (LineReaderTerminal.ExternalMessageException e) { - } - - if(sftp != null) { - sftp.terminate(); - } - frame.dispose(); - } - - public String expandRemote(String name) { - if(name.charAt(0) != '/') - name = remoteDir + "/" + name; - return name; - } - - public String expandLocal(String name) { - if(name.length() > 1 && - name.charAt(0) != File.separatorChar && - name.charAt(1) != ':') { - name = localDir + File.separator + name; - } - return name; - } - - public String getNextArg(String args) { - int i = args.indexOf(' '); - if(i > -1) - args = args.substring(0, i); - return args; - } - - public String[] makeArgv(String cmdLine) { - String[] argv = new String[32]; - String[] argvRet; - int n = 0, i; - while(cmdLine != null) { - argv[n++] = getNextArg(cmdLine); - i = cmdLine.indexOf(' '); - if(i > -1) { - cmdLine = cmdLine.substring(i); - cmdLine = cmdLine.trim(); - } else - cmdLine = null; - } - argvRet = new String[n]; - System.arraycopy(argv, 0, argvRet, 0, n); - return argvRet; - } - - public void doHelp() { - linereader.println(""); - linereader.println("The following commands are available:"); - linereader.println(""); - linereader.println("pwd\t\t\t\t\tshow current local/remote directory"); - linereader.println("cd

\t\t\t\tchange current directory (remote)"); - linereader.println("lcd \t\t\t\tchange current directory (local)"); - linereader.println("ls\t\t\t\t\tlist current directory (remote)"); - linereader.println("lls\t\t\t\t\tlist current directory (local)"); - linereader.println("get []\tdownload file from remote host"); - linereader.println("put []\tupload file to remote host"); - linereader.println("ren \t\trename remote file"); - linereader.println("lren \t\trename local file"); - linereader.println("rm \t\t\tremove remote file"); - linereader.println("lrm \t\t\tremove local file"); - linereader.println("mkdir \t\t\tcreate remote directory"); - linereader.println("lmkdir \t\t\tcreate local directory"); - linereader.println("rmdir \t\t\tremove remote directory"); - linereader.println("lrmdir \t\t\tremove local directory"); - linereader.println("quit\t\t\t\t\tquit this sftp session"); - linereader.println(""); - } - - public TerminalWin getTerminal() { - return terminal; - } - - /* - SSH2SFTPClient sftp = new SSH2SFTPClient(connection); - SSH2SFTP.FileHandle handle = sftp.opendir("."); - SSH2SFTP.FileAttributes[] list = sftp.readdir(handle); - - System.out.println("length: " + list.length); - for(i = 0; i < list.length; i++) { - System.out.println(list[i].lname); - } - - SSH2SFTP.FileAttributes attrs = sftp.stat("."); - System.out.println("attrs: " + attrs); - - attrs = sftp.realpath("."); - System.out.println("lname-rp: " + attrs.lname); - System.out.println("attrs-rp: " + attrs); - - handle = sftp.open("/tmp/hostkey", SSH2SFTP.SSH_FXF_READ, - new SSH2SFTP.FileAttributes()); - java.io.FileOutputStream fout = new java.io.FileOutputStream("/tmp/keycopy"); - byte[] buf = new byte[1024]; - long foffs = 0; - int len; - while((len = sftp.read(handle, foffs, buf, 0, 1024)) > 0) { - System.out.println("read: " + len); - fout.write(buf, 0, len); - foffs += len; - } - sftp.close(handle); - fout.close(); - - handle = sftp.open("/tmp/foobar", SSH2SFTP.SSH_FXF_WRITE | - SSH2SFTP.SSH_FXF_CREAT, - new SSH2SFTP.FileAttributes()); - FileInputStream fin = new FileInputStream("/tmp/keycopy"); - buf = new byte[1024]; - foffs = 0; - while((len = fin.read(buf, 0, 1024)) > 0) { - System.out.println("wrote: " + len); - sftp.write(handle, foffs, buf, 0, len); - foffs += len; - } - sftp.close(handle); - fin.close(); - - sftp.terminate(); - - */ - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2SimpleSignature.java b/src/main/java/com/mindbright/ssh2/SSH2SimpleSignature.java deleted file mode 100644 index 2313d75..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2SimpleSignature.java +++ /dev/null @@ -1,98 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public abstract class SSH2SimpleSignature extends SSH2Signature { - - protected String signatureAlgorithm; - protected String ssh2KeyFormat; - - protected boolean draftIncompatibleSignature; - - protected SSH2SimpleSignature(String signatureAlgorithm, - String ssh2KeyFormat) - { - super(); - this.signatureAlgorithm = signatureAlgorithm; - this.ssh2KeyFormat = ssh2KeyFormat; - } - - public static SSH2Signature getVerifyInstance(byte[] pubKeyBlob) - throws SSH2Exception - { - String keyFormat = getKeyFormat(pubKeyBlob); - SSH2Signature signature = SSH2Signature.getInstance(keyFormat); - signature.initVerify(pubKeyBlob); - return signature; - } - - public final String getSignatureAlgorithm() { - return signatureAlgorithm; - } - - public byte[] encodeSignature(byte[] sigRaw) { - if(draftIncompatibleSignature) { - return sigRaw; - } else { - SSH2DataBuffer buf = new SSH2DataBuffer(sigRaw.length + 4 + - ssh2KeyFormat.length() + 4); - buf.writeString(ssh2KeyFormat); - buf.writeString(sigRaw); - return buf.readRestRaw(); - } - } - - public byte[] decodeSignature(byte[] sigBlob) - throws SSH2SignatureException - { - if(draftIncompatibleSignature) { - return sigBlob; - } else { - SSH2DataBuffer buf = new SSH2DataBuffer(sigBlob.length); - buf.writeRaw(sigBlob); - - int len = buf.readInt(); - if(len <= 0 || len > sigBlob.length) { - // This is probably an undetected buggy implemenation - // !!! TODO: might want to report this... - return sigBlob; - } - - buf.setRPos(buf.getRPos() - 4); // undo above readInt - - String type = buf.readJavaString(); - if(!type.equals(ssh2KeyFormat)) { - throw new SSH2SignatureException(ssh2KeyFormat + - ", signature blob type " + - "mismatch, got '" + type); - } - - return buf.readString(); - } - } - - public static String getKeyFormat(byte[] pubKeyBlob) { - SSH2DataBuffer buf = new SSH2DataBuffer(pubKeyBlob.length); - buf.writeRaw(pubKeyBlob); - return buf.readJavaString(); - } - - public void setIncompatibility(SSH2Transport transport) { - draftIncompatibleSignature = transport.incompatibleSignature; - } - -} - diff --git a/src/main/java/com/mindbright/ssh2/SSH2StreamChannel.java b/src/main/java/com/mindbright/ssh2/SSH2StreamChannel.java deleted file mode 100644 index 3560a18..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2StreamChannel.java +++ /dev/null @@ -1,259 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.IOException; - -import com.mindbright.util.Queue; - -public class SSH2StreamChannel extends SSH2Channel { - protected InputStream in; - protected OutputStream out; - - protected Thread transmitter; - protected Thread receiver; - protected Queue rxQueue; - protected long txCounter; - protected long rxCounter; - - private final static boolean QUEUED_RX_CHAN = true; - - protected SSH2StreamChannel(int channelType, SSH2Connection connection, - Object creator, - InputStream in, OutputStream out) { - super(channelType, connection, creator); - this.in = in; - this.out = out; - createStreams(); - } - - public void applyFilter(SSH2StreamFilter filter) { - if(filter != null) { - in = filter.getInputFilter(in); - out = filter.getOutputFilter(out); - } - } - - private void channelTransmitLoop() { - connection.getLog().debug("SSH2StreamChannel", - "starting ch. #" + channelId + - " (" + getType() + ") transmitter"); - Thread.yield(); - try { - SSH2TransportPDU pdu; - int maxSz = 0; - int rcvSz = 0; - while(!eofSent) { - pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_CHANNEL_DATA, - txMaxPktSz + 256); - pdu.writeInt(peerChanId); - maxSz = checkTxWindowSize(rcvSz); - rcvSz = in.read(pdu.data, pdu.wPos + 4, maxSz); - if(rcvSz == -1) { - sendEOF(); - } else { - pdu.writeInt(rcvSz); - pdu.wPos += rcvSz; - txCounter += rcvSz; - transmit(pdu); - } - } - } catch (IOException e) { - if(!eofSent) { - connection.getLog().error("SSH2StreamChannel", - "channelTransmitLoop", - e.toString()); - } - } finally { - try { in.close(); } catch (IOException e) { /* don't care */ }; - sendClose(); - } - connection.getLog().debug("SSH2StreamChannel", - "exiting ch. #" + - channelId + " (" + getType() + - ") transmitter, " + txCounter + - " bytes tx"); - } - - private void channelReceiveLoop() { - connection.getLog().debug("SSH2StreamChannel", - "starting ch. #" + channelId + - " (" + getType() + ") receiver"); - Thread.yield(); - try { - SSH2TransportPDU pdu; - while((pdu = (SSH2TransportPDU)rxQueue.getFirst()) != null) { - rxWrite(pdu); - } - } catch (IOException e) { - connection.getLog().error("SSH2StreamChannel", - "channelReceiveLoop", - e.toString()); - } finally { - rxClosing(); - } - connection.getLog().debug("SSH2StreamChannel", - "exiting ch. #" + - channelId + " (" + getType() + - ") receiver, " + rxCounter + - " bytes rx"); - } - - private final void rxWrite(SSH2TransportPDU pdu) throws IOException { - int len = pdu.readInt(); - int off = pdu.getRPos(); - rxCounter += len; - out.write(pdu.data, off, len); - pdu.release(); - checkRxWindowSize(len); - } - - private final void rxClosing() { - // Signal to transmitter that this is an orderly shutdown - // - eofSent = true; - try { out.close(); } catch (IOException e) { /* don't care */ } - try { in.close(); } catch (IOException e) { /* don't care */ } - outputClosed(); - - // there is a slight chance that the transmitter is waiting for - // window adjust in which case we must interrupt it here so it - // doesn't hang - // - if(txCurrWinSz == 0) { - txCurrWinSz = -1; - transmitter.interrupt(); - } - } - - private final synchronized int checkTxWindowSize(int lastSz) { - txCurrWinSz -= lastSz; - while(txCurrWinSz == 0) { - // Our window is full, wait for ACK from peer - try { - this.wait(); - } catch (InterruptedException e) { - if(!eofSent) { - connection.getLog().error("SSH2StreamChannel", - "checkTxWindowSize", - "window adjust wait interrupted"); - } - } - } - // Try sending remaining window size or max packet size before ACK - // - int dataSz = (txCurrWinSz < txMaxPktSz ? txCurrWinSz : txMaxPktSz); - return dataSz; - } - - private final void checkRxWindowSize(int len) { - rxCurrWinSz -= len; - if(rxCurrWinSz < 0) { - connection.fatalDisconnect(SSH2.DISCONNECT_PROTOCOL_ERROR, - "Peer overflowed window"); - } else if(rxCurrWinSz <= (rxInitWinSz >>> 1)) { - // ACK on >= 50% of window received - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_CHANNEL_WINDOW_ADJUST); - pdu.writeInt(peerChanId); - pdu.writeInt(rxInitWinSz - rxCurrWinSz); - transmit(pdu); - rxCurrWinSz = rxInitWinSz; - } - } - - protected void data(SSH2TransportPDU pdu) { - if(QUEUED_RX_CHAN) { - rxQueue.putLast(pdu); - } else { - try { - rxWrite(pdu); - } catch (IOException e) { - connection.getLog().error("SSH2StreamChannel", - "data", - e.toString()); - rxClosing(); - } - } - } - - protected void openConfirmationImpl(SSH2TransportPDU pdu) { - startStreams(); - } - - protected boolean openFailureImpl(int reasonCode, String reasonText, - String langTag) { - // Just return false since we don't want to keep the channel, - // handle in derived class if needed - return false; - } - - protected synchronized void windowAdjustImpl(int inc) { - txCurrWinSz += inc; - this.notify(); - } - - protected void eofImpl() { - if(QUEUED_RX_CHAN) { - rxQueue.setBlocking(false); - } else { - rxClosing(); - } - } - - protected void closeImpl() { - eofImpl(); - } - - protected void outputClosed() { - // Do nothing, handle in derived class if needed - } - - protected void handleRequestImpl(String type, boolean wantReply, - SSH2TransportPDU pdu) { - // Do nothing, handle in derived class if needed - } - - protected void createStreams() { - if(QUEUED_RX_CHAN) { - receiver = new Thread(new Runnable() { - public void run() { - channelReceiveLoop(); - } - }, "SSH2StreamRX_" + getType() + "_" + channelId); - receiver.setDaemon(false); - rxQueue = new Queue(); - } - transmitter = new Thread(new Runnable() { - public void run() { - channelTransmitLoop(); - } - }, "SSH2StreamTX_" + getType() + "_" + channelId); - transmitter.setDaemon(false); - } - - protected void startStreams() { - transmitter.start(); - if(QUEUED_RX_CHAN) { - receiver.start(); - } - } -} - - diff --git a/src/main/java/com/mindbright/ssh2/SSH2StreamFilter.java b/src/main/java/com/mindbright/ssh2/SSH2StreamFilter.java deleted file mode 100644 index ebbe69d..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2StreamFilter.java +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.InputStream; -import java.io.OutputStream; - -public interface SSH2StreamFilter { - public InputStream getInputFilter(InputStream toBeFiltered); - public OutputStream getOutputFilter(OutputStream toBeFiltered); -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2StreamFilterAdapter.java b/src/main/java/com/mindbright/ssh2/SSH2StreamFilterAdapter.java deleted file mode 100644 index 497ae7e..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2StreamFilterAdapter.java +++ /dev/null @@ -1,29 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.InputStream; -import java.io.OutputStream; - -public class SSH2StreamFilterAdapter implements SSH2StreamFilter { - public InputStream getInputFilter(InputStream toBeFiltered) { - return toBeFiltered; - } - - public OutputStream getOutputFilter(OutputStream toBeFiltered) { - return toBeFiltered; - } -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2StreamFilterFactory.java b/src/main/java/com/mindbright/ssh2/SSH2StreamFilterFactory.java deleted file mode 100644 index 7b1b09b..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2StreamFilterFactory.java +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public interface SSH2StreamFilterFactory { - public SSH2StreamFilter createFilter(SSH2Connection connection, - SSH2StreamChannel channel); - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2StreamSniffer.java b/src/main/java/com/mindbright/ssh2/SSH2StreamSniffer.java deleted file mode 100644 index 8adb6ad..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2StreamSniffer.java +++ /dev/null @@ -1,89 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.FilterInputStream; -import java.io.FilterOutputStream; -import java.io.IOException; - -import com.mindbright.util.HexDump; - -public class SSH2StreamSniffer implements SSH2StreamFilter, - SSH2StreamFilterFactory -{ - protected int id; - - protected class SniffOutput extends FilterOutputStream { - - public SniffOutput(OutputStream toBeFiltered) { - super(toBeFiltered); - } - - public void write(byte b[], int off, int len) throws IOException { - HexDump.print("ch. #" + id + " tx:", true, b, off, len); - out.write(b, off, len); - } - - } - - protected class SniffInput extends FilterInputStream { - - public SniffInput(InputStream toBeFiltered) { - super(toBeFiltered); - } - - public int read(byte b[], int off, int len) throws IOException { - int n = in.read(b, off, len); - if(n >= 0) { - HexDump.print("ch. #" + id + " rx:", true, b, off, n); - } else { - System.out.println("ch. #" + id + " rx: EOF"); - } - return n; - } - - } - - private static SSH2StreamSniffer factoryInstance; - - public SSH2StreamSniffer() { - } - - public static synchronized SSH2StreamSniffer getFilterFactory() { - if(factoryInstance == null) { - factoryInstance = new SSH2StreamSniffer(); - } - return factoryInstance; - } - - public SSH2StreamFilter createFilter(SSH2Connection connection, - SSH2StreamChannel channel) { - SSH2StreamSniffer sniffer = new SSH2StreamSniffer(); - sniffer.id = channel.getId(); - return sniffer; - } - - public InputStream getInputFilter(InputStream toBeFiltered) { - return new SniffInput(toBeFiltered); - } - - public OutputStream getOutputFilter(OutputStream toBeFiltered) { - return new SniffOutput(toBeFiltered); - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2TCPChannel.java b/src/main/java/com/mindbright/ssh2/SSH2TCPChannel.java deleted file mode 100644 index 3d45c87..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2TCPChannel.java +++ /dev/null @@ -1,106 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.IOException; -import java.net.Socket; -import java.net.InetAddress; - -public class SSH2TCPChannel extends SSH2StreamChannel { - - protected Socket endpoint; - protected String originAddr; - protected int originPort; - protected String remoteAddr; - protected int remotePort; - - public SSH2TCPChannel(int channelType, SSH2Connection connection, - Object creator, - Socket endpoint, - String remoteAddr, int remotePort, - String originAddr, int originPort) - throws IOException - { - super(channelType, connection, creator, - endpoint.getInputStream(), endpoint.getOutputStream()); - this.endpoint = endpoint; - this.remoteAddr = remoteAddr; - this.remotePort = remotePort; - this.originAddr = originAddr; - this.originPort = originPort; - } - - protected void outputClosed() { - if(endpoint != null) { - try { endpoint.close(); } catch (IOException e) { /* don't care */ } - } - endpoint = null; - } - - protected boolean openFailureImpl(int reasonCode, String reasonText, - String langTag) { - outputClosed(); - return false; - } - - public InetAddress getAddress() { - return endpoint.getInetAddress(); - } - - public int getPort() { - return endpoint.getPort(); - } - - public String getRemoteAddress() { - return remoteAddr; - } - - public int getRemotePort() { - return remotePort; - } - - public String getOriginAddress() { - return originAddr; - } - - public int getOriginPort() { - return originPort; - } - - public String toString() { - String desc = ""; - switch(channelType) { - case SSH2Connection.CH_TYPE_FWD_TCPIP: - desc = "[remote] " + originAddr + ":" + originPort + " <--> " + - getRemoteAddress() + ":" + getRemotePort() + " <--ssh2--> " + - getAddress().getHostAddress() + ":" + getPort(); - break; - case SSH2Connection.CH_TYPE_DIR_TCPIP: - SSH2Listener l = (SSH2Listener)creator; - desc = "[local] " + originAddr + ":" + originPort + " <--> " + - l.getListenHost() + ":" + l.getListenPort() + " <--ssh2--> " + - getRemoteAddress() + ":" + getRemotePort(); - break; - default: - System.out.println("!!! NOT SUPPORTED IN SSH2TCPChannel.toString !!!"); - break; - } - return desc; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2TerminalAdapter.java b/src/main/java/com/mindbright/ssh2/SSH2TerminalAdapter.java deleted file mode 100644 index d30e010..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2TerminalAdapter.java +++ /dev/null @@ -1,21 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public interface SSH2TerminalAdapter { - public void attach(SSH2SessionChannel session); - public void detach(); -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2TerminalAdapterImpl.java b/src/main/java/com/mindbright/ssh2/SSH2TerminalAdapterImpl.java deleted file mode 100644 index a512803..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2TerminalAdapterImpl.java +++ /dev/null @@ -1,85 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.OutputStream; -import java.io.IOException; - -import com.mindbright.terminal.TerminalWin; -import com.mindbright.terminal.TerminalInputListener; - -public class SSH2TerminalAdapterImpl implements SSH2TerminalAdapter, - TerminalInputListener { - TerminalWin terminal; - SSH2SessionChannel session; - TerminalOutStream stdout; - - final class TerminalOutStream extends OutputStream { - public void write(int b) throws IOException { - terminal.write((char)b); - } - public void write(byte b[], int off, int len) throws IOException { - terminal.write(b, off, len); - } - } - - public SSH2TerminalAdapterImpl(TerminalWin terminal) { - this.terminal = terminal; - this.stdout = new TerminalOutStream(); - } - - public void attach(SSH2SessionChannel session) { - this.session = session; - session.changeStdOut(this.stdout); - terminal.addInputListener(this); - } - - public void detach() { - if(terminal != null) { - terminal.removeInputListener(this); - } - // !!! TODO want to do this ? - // session.changeStdOut( - } - - public void typedChar(char c) { - try { - session.stdin.write((int)c); - } catch (IOException e) { - session.connection.getLog().error("SSH2TerminalAdapterImpl", - "typedChar", - "error writing to stdin: " + - e.getMessage()); - } - } - - public void sendBytes(byte[] b) { - try { - session.stdin.write(b, 0, b.length); - } catch (IOException e) { - session.connection.getLog().error("SSH2TerminalAdapterImpl", - "sendBytes", - "error writing to stdin: " + - e.getMessage()); - } - } - - public void signalWindowChanged(int rows, int cols, - int vpixels, int hpixels) { - session.sendWindowChange(rows, cols); - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2Transport.java b/src/main/java/com/mindbright/ssh2/SSH2Transport.java deleted file mode 100644 index a8674ed..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2Transport.java +++ /dev/null @@ -1,1601 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; -import java.math.BigInteger; - -import java.io.IOException; - -import com.mindbright.jca.security.MessageDigest; -import com.mindbright.jca.security.SecureRandom; -import com.mindbright.jca.security.InvalidKeyException; - -import javax.crypto.Cipher; -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.ShortBufferException; - -import com.mindbright.util.SecureRandomAndPad; -import com.mindbright.util.Queue; -import com.mindbright.util.Log; - -/** - * This class implements the transport layer of the secure shell version 2 - * (ssh2) protocol stack. It handles the initial negotiation of algorithms for - * key exchange, host key type, encryption, message authentication and - * compression. It also handles server authentication (through the provided - * SSH2TransportEventHandler). - *

- * To create a SSH2Transport instance a TCP connection to the ssh2 - * server must first be established using a java.net.Socket. This - * socket is passed to the constructor. The constructor is passive in that it - * doesn't start any communication. To start the protocol engine and begin - * communcation with the server the method boot must be called. In - * this method the version information echange is done and two threads are - * started which handles the protocol engine and all communication with the - * server. - *

- * The operation of the transport layer can be controlled and monitored with - * instances of the classes SSH2TransportPreferences and - * SSH2TransportEventHandler which are provided to the constructor. - *

- * After initial negotiation the chosen key exchange algorithm is handled by a - * subclass of the abstract class SSH2KeyExchanger. When the key - * exchange is complete, keys for encryption and message authentication can be - * derived. The communciation at this point is secured with the selected - * cipher/mac algorithms. The actual encryption, message authentication and - * compression is handled in the class SSH2TransportPDU which is - * the data container implementing the specific formatting defined in the - * protocol. - *

- * Before the upper layers (i.e. the user authentication and connection layers) - * of the protocol can be started the key exchange stage must be completed. This - * must be checked by calling the blocking method - * waitForKEXComplete. When the key exchange is complete a secure - * connection to an authenticated server has been established. The function of - * the transport layer at this point is the multiplexing of protocol data units - * (referred to as PDU or packet) between the server and the upper layers which - * are implemented in the classes SSH2UserAuth and - * SSH2Connection. - * - * @see SSH2TransportPreferences - * @see SSH2TransportEventHandler - * @see SSH2UserAuth - * @see SSH2Connection - */ -public final class SSH2Transport { - - private class KeepAliveThread implements Runnable { - private volatile int interval; - private volatile boolean keepRunning; - - protected KeepAliveThread(int interval) { - this.interval = interval; - this.keepRunning = true; - Thread heartbeat = new Thread(this, "SSH2TransportKeepAlive"); - heartbeat.setDaemon(true); - heartbeat.setPriority(Thread.MIN_PRIORITY); - heartbeat.start(); - } - - protected synchronized void setInterval(int interval) { - if(interval < 1) { - stop(); - } else { - this.interval = interval; - } - } - - public void run() { - while(keepRunning) { - sendIgnore("heartbeat".getBytes()); - try { - Thread.sleep(1000 * interval); - } catch (InterruptedException e) { /* ignore */ } - } - } - - protected void stop() { - keepRunning = false; - } - } - - private final static boolean DEBUG_ALL_TX = false; - private final static boolean DEBUG_ALL_RX = false; - - private boolean weAreAServer; - - private String clientVersion; - private String serverVersion; - - private SSH2TransportPreferences ourPrefs; - private SSH2TransportPreferences peerPrefs; - - private SSH2TransportEventHandler eventHandler; - - private SSH2KeyExchanger keyExchanger; - private SSH2UserAuth userAuth; - private SSH2Connection connection; - - private Log tpLog; - - protected Socket tpSocket; - protected InputStream tpIn; - protected OutputStream tpOut; - - private Thread transmitter; - private Thread receiver; - private Queue txQueue; - - private SecureRandomAndPad tpRand; - - private KeepAliveThread heartbeat; - - private byte[] sessionId; - private volatile boolean keyExchangeInProgress; - private boolean keyExchangeOk; - private Object keyExchangeMonitor; - private SSH2TransportPDU clientKEXINITPkt; - private SSH2TransportPDU serverKEXINITPkt; - - private int rxSeqNum; - private Mac rxMAC; - private Cipher rxCipher; - private SSH2Compressor rxCompressor; - - private int txSeqNum; - private Mac txMAC; - private Cipher txCipher; - private SSH2Compressor txCompressor; - - private Object disconnectMonitor; - private volatile boolean isConnected; - private volatile boolean isTxUp; - private volatile boolean isRxUp; - - // Incompatibility flags (peer's incompatibility of course :-) - // - public boolean incompatibleSignature; - public boolean incompatibleServiceAccept; - public boolean incompatiblePublicKeyAuth; - public boolean incompatibleHMACKeyLength; - public boolean incompatiblePublicKeyUserId; - public boolean incompatibleChannelOpenFail; - public boolean incompatibleRijndael; - public boolean incompatibleCantReKey; - - /** - * This is the basic constructor used when no logging or event handling is - * needed. - * - * @param tpSocket the connection to the ssh2 server - * @param prefs the protocol preferences - * @param rand the source of randomness for keys and padding - */ - public SSH2Transport(Socket tpSocket, - SSH2TransportPreferences prefs, - SecureRandomAndPad rand) { - this(tpSocket, prefs, null, rand); - } - - /** - * This is the constructor used when an event handler is needed but no - * logging. - * - * @param tpSocket the connection to the ssh2 server - * @param prefs the protocol preferences - * @param eventHandler the event handler which receives callbacks - * @param rand the source of randomness for keys and padding - */ - public SSH2Transport(Socket tpSocket, - SSH2TransportPreferences prefs, - SSH2TransportEventHandler eventHandler, - SecureRandomAndPad rand) { - this(tpSocket, prefs, eventHandler, rand, new Log(Log.LEVEL_INFO)); - } - - /** - * This is the constructor used when both an event handler and logging is - * needed. - * - * @param tpSocket the connection to the ssh2 server - * @param prefs the protocol preferences - * @param eventHandler the event handler which receives callbacks - * @param rand the source of randomness for keys and padding - * @param log the log handler which receives all logs - */ - public SSH2Transport(Socket tpSocket, - SSH2TransportPreferences prefs, - SSH2TransportEventHandler eventHandler, - SecureRandomAndPad rand, Log log) { - this.disconnectMonitor = new Object(); - this.keyExchangeMonitor = new Object(); - this.isConnected = false; - this.isTxUp = false; - this.isRxUp = false; - this.ourPrefs = prefs; - this.eventHandler = (eventHandler != null ? eventHandler : - new SSH2TransportEventAdapter()); - this.tpSocket = tpSocket; - this.tpRand = rand; - this.tpLog = log; - try { - tpIn = tpSocket.getInputStream(); - tpOut = tpSocket.getOutputStream(); - } catch (IOException e) { - // !!! TODO: pathological, fixit!!! - } - } - - /** - * Starts the protocol engine and begins communication with the server. It - * completes the version negotiation and starts two threads which handles - * the protocol engine and all communication with the server. The key - * exchange is started here. - * - * @exception SSH2Exception if a fatal error occurs such as an I/O error or - * a protocol mismatch. - */ - public void boot() throws SSH2Exception { - synchronized(disconnectMonitor) { - if(isConnected) { - throw new SSH2FatalException("Already booted"); - } - isConnected = true; - } - try { - negotiateVersion(); - } catch (IOException e) { - throw new SSH2FatalException("I/O error in version negotiation", e); - } - - transmitter = new Thread(new Runnable() { - public void run() { - transportTransmitLoop(); - } - }, "SSH2TransportTX"); - txQueue = new Queue(); - transmitter.start(); - - // Note we start the receiver AFTER we do startKeyExchange() to avoid - // race with startKeyExchange() in receiver - // - startKeyExchange(); - - receiver = new Thread(new Runnable() { - public void run() { - transportReceiveLoop(); - } - }, "SSH2TransportRX"); - receiver.start(); - } - - /** - * Gets the session identifier calculated at key exchange as defined in the - * protool spec. - * - * @return the session identifier as a byte array. - */ - public byte[] getSessionId() { - byte[] id = sessionId; - if(!incompatiblePublicKeyUserId) { - SSH2DataBuffer buf = - new SSH2DataBuffer(sessionId.length + 4); - buf.writeString(sessionId); - id = buf.readRestRaw(); - } - return id; - } - - /** - * Gets the PDU containing the key exchange initialization (KEXINIT) sent by - * the client. - * - * @return the PDU containing the KEXINIT packet - */ - public SSH2TransportPDU getClientKEXINITPDU() { - return clientKEXINITPkt; - } - - /** - * Gets the PDU containing the key exchange initialization (KEXINIT) sent by - * the server. - * - * @return the PDU containing the KEXINIT packet. - */ - public SSH2TransportPDU getServerKEXINITPDU() { - return serverKEXINITPkt; - } - - /** - * Gets the client's version string - * - * @return the client's version string - */ - public String getClientVersion() { - return clientVersion; - } - - /** - * Gets the server's version string. - * - * @return the server's version string. - */ - public String getServerVersion() { - return serverVersion; - } - - /** - * Gets the preferences we want. - * - * @return our preferences. - */ - public SSH2TransportPreferences getOurPreferences() { - return ourPrefs; - } - - /** - * Gets the preferences peer want. - * - * @return peer's preferences. - */ - public SSH2TransportPreferences getPeerPreferences() { - return peerPrefs; - } - - /** - * Sets the event handler to use. - * - * @param eventHandler the event handler to use. - */ - public void setEventHandler(SSH2TransportEventHandler eventHandler) { - if(eventHandler != null) { - this.eventHandler = eventHandler; - } - } - - /** - * Gets the event handler currently in use. - * - * @return the event handler currently in use. - */ - public SSH2TransportEventHandler getEventHandler() { - return eventHandler; - } - - /** - * Gets the log handler currently in use. - * - * @return the log handler currently in use. - */ - public Log getLog() { - return tpLog; - } - - /** - * Sets the log handler to use. - * - * @param the log handler to use - */ - public void setLog(Log log) { - tpLog = log; - } - - /** - * Checks whether we are a server or a client. - * - * @return a boolean indicating if we are a server or not. - */ - public boolean isServer() { - return weAreAServer; - } - - /** - * Gets the SecureRandom currently in use. - * - * @return the SecureRandom in use. - */ - public SecureRandom getSecureRandom() { - return tpRand; - } - - /** - * Gets the SSH2Compressor currently in use for the - * receiver. - * - * @return the SSH2Compressor in use, - * null if none. - */ - public SSH2Compressor getRxCompressor() { - return rxCompressor; - } - - /** - * Gets the SSH2Compressor currently in use for the - * transmitter. - * - * @return the SSH2Compressor in use, - * null if none. - */ - public SSH2Compressor getTxCompressor() { - return txCompressor; - } - - /** - * Sets the SSH2UserAuth to use for the user authenticaton - * stage. The user authentication service is started from the class - * SSH2UserAuth through the method requestService. - * - * @param userAuth the userAuth layer - */ - public void setUserAuth(SSH2UserAuth userAuth) { - this.userAuth = userAuth; - } - - /** - * Requests the given service (currently the only service defined is the - * "ssh-userauth" service which starts the user authentication). - * - * @param service the name of the service to request - */ - public void requestService(String service) { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_SERVICE_REQUEST); - pdu.writeString(service); - transmit(pdu); - } - - /** - * Sets the SSH2Connection to use for the connection layer. All - * actions after this stage are made through the connection layer. - * - * @param connection the connection layer - */ - public void setConnection(SSH2Connection connection) { - this.connection = connection; - } - - /** - * Starts a key exchange with the preferences set in the constructor. If a - * key exchange is allready in progress this call have no effect. - * - * @exception SSH2Exception if a fatal error occurs. - */ - public void startKeyExchange() throws SSH2Exception { - this.startKeyExchange(ourPrefs); - } - - /** - * Starts a key exchange with the given preferences (i.e. change to new - * preferences and negotiate these with the peer). If a key exchange is - * allready in progress this call have no effect. - * - * @param newPrefs the new preferences to use - * - * @exception SSH2Exception if a fatal error occurs - */ - public void startKeyExchange(SSH2TransportPreferences newPrefs) - throws SSH2Exception - { - synchronized(keyExchangeMonitor) { - if(!keyExchangeInProgress) { - if(incompatibleCantReKey && (peerPrefs != null)) { - throw new SSH2FatalException("Error, peer '" + - (weAreAServer ? clientVersion : - serverVersion) + - "' doesn't support re-keying"); - } - - ourPrefs = newPrefs; - keyExchangeInProgress = true; - - if(incompatibleRijndael) { - removeRijndael(); - } - - txQueue.disable(); - txQueue.waitUntilBlocked(); - - sendKEXINIT(); - } - } - } - - /** - * Waits (blocks) for key exchange to complete (if not in progress returns - * immediately). - * - * @return a boolean indicating if key exchange was successful or not. - */ - public boolean waitForKEXComplete() { - synchronized(keyExchangeMonitor) { - if(keyExchangeInProgress) { - try { - keyExchangeMonitor.wait(); - } catch (InterruptedException e) { - /* don't care, someone interrupted us on purpose */ - } - } - return keyExchangeOk; - } - } - - /** - * Checks if key exchange is currently in progress. - * - * @return a boolean indicating if key exchange is in progress or not. - */ - public boolean keyExchangeInProgress() { - return keyExchangeInProgress; - } - - /** - * Checks if currently connected to a server. - * - * @return a boolean indicating if we are connected or not. - */ - public boolean isConnected() { - return isConnected; - } - - /** - * Sends an IGNORE packet (as defined in the protocol spec.) with the given - * data as payload. - * - * @param data a byte array containing the payload - */ - public void sendIgnore(byte[] data) { - sendIgnore(data, 0, data.length); - } - - /** - * Sends an IGNORE packet (as defined in the protocol spec.) with the given - * data as payload. - * - * @param data a byte array containing the payload - * @param off offset in data where payload starts - * @param len length of payload - */ - public void sendIgnore(byte[] data, int off, int len) { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_IGNORE); - pdu.writeString(data, off, len); - transmit(pdu); - } - - /** - * Sends a DEBUG packet (as defined in the protocol spec.) with the given - * message. - * - * @param alwaysDisp boolean indicating whether this message must always be - * displayed or not. - * @param message the debug message to send - * @param language the language tag to use - */ - public void sendDebug(boolean alwaysDisp, String message, String language) { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_DEBUG); - pdu.writeBoolean(alwaysDisp); - pdu.writeString(message); - pdu.writeString(language); - transmit(pdu); - } - - /** - * Enables keep-alive function which sends IGNORE packets on the given time - * interval to prevent the connection from beeing timed out (e.g. because of - * TCP connection subject to idle-timeouts in a firewall). - * - * @param intervalSeconds interval time in seconds - */ - public void enableKeepAlive(int intervalSeconds) { - if(heartbeat != null) { - heartbeat.setInterval(intervalSeconds); - } else if(intervalSeconds > 0) { - heartbeat = new KeepAliveThread(intervalSeconds); - } - } - - /** - * Disables keep-alive function. - */ - public void disableKeepAlive() { - if(heartbeat != null) { - heartbeat.stop(); - } - heartbeat = null; - } - - private void kexComplete(boolean noError) { - synchronized(keyExchangeMonitor) { - keyExchangeInProgress = false; - keyExchangeOk = noError; - keyExchangeMonitor.notifyAll(); - if(noError) { - eventHandler.kexComplete(this); - } - } - } - - private void authTerminate() { - if(userAuth != null) { - userAuth.terminate(); - } - } - - /** - * Transmits the given PDU if we are connected. The PDU is put in a queue - * which is processed by the internal threads hence this call is can only - * block in extreme cases since all internal queues are subject to flow - * control to prevent memory from beeing exhausted. - * - * @param pdu PDU to send - */ - public void transmit(SSH2TransportPDU pdu) { - if(isConnected) { - txQueue.putLast(pdu); - } - } - - /** - * Transmits the given PDU without checking if we are connected. This - * version of transmit writes the PDU directly to the - * OutputStream to the peer, hence it can only be used when - * the transmitter is not running. - * - * @param pdu PDU to send - * - * @exception SSH2Exception if an I/O exception or other fatal error occurs - */ - public synchronized void transmitInternal(SSH2TransportPDU pdu) - throws SSH2Exception - { - if(DEBUG_ALL_TX) tpLog.debug2("SSH2Transport", - "transmitInternal", - "sending message of type: " + - SSH2.msgTypeString(pdu.pktType), - pdu.getData(), - pdu.getPayloadOffset(), - pdu.getPayloadLength()); - try { - pdu.writeTo(tpOut, - txSeqNum++, txMAC, txCipher, txCompressor, tpRand); - } catch (ShortBufferException e) { - throw new SSH2FatalException("Internal error/bug: " + - e.getMessage()); - } catch (IOException e) { - throw new SSH2FatalException("Couldn't write packet of type " + - SSH2.msgTypeString(pdu.pktType), e); - } - } - - /** - * Disconnects from peer using the DISCONNECT packet type with the given - * reason and description. See the class SSH2 for reason codes. - * - * @param reason the reason code - * @param description the textual description for the cause of disconnect - * - * @see SSH2 - */ - public void fatalDisconnect(int reason, String description) { - disconnectInternal(reason, description, - /* !!! TODO: languageTag, from ourPrefs? */ "", - false); - } - - /** - * Disconnects from peer using the DISCONNECT packet type with the - * reason code DISCONNECT_BY_APPLICATION and the given description. - * - * @param description the textual description for the cause of disconnect - */ - public void normalDisconnect(String description) { - disconnectInternal(SSH2.DISCONNECT_BY_APPLICATION, description, - /* !!! TODO: languageTag, from ourPrefs? */ "", - false); - } - - private void disconnectInternal(int reason, String description, - String languageTag, boolean fromPeer) { - synchronized(disconnectMonitor) { - if(!isConnected) { - return; - } - isConnected = false; - } - - if(!fromPeer && isTxUp) { - // - // !!! Pathological condition: tx may be exiting, will cause bug - // - txQueue.disable(); - txQueue.waitUntilBlocked(); - - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_DISCONNECT); - pdu.writeInt(reason); - pdu.writeString(description); - pdu.writeString(""); // !!! TODO: Handle the language - - try { - transmitInternal(pdu); - } catch (SSH2Exception e) { - tpLog.message(Log.LEVEL_ERROR, "SSH2Transport", - "disconnectInternal", - "error writing disconnect msg: " + e); - } - } - - disableKeepAlive(); - - shutdownRx(); - shutdownTx(); - - if(connection != null) { - connection.terminate(); - } - - if(fromPeer) { - eventHandler.peerDisconnect(this, reason, description, languageTag); - } else if(reason == SSH2.DISCONNECT_BY_APPLICATION) { - eventHandler.normalDisconnect(this, description, languageTag); - } else { - eventHandler.fatalDisconnect(this, reason, description, languageTag); - } - - tpLog.warning("SSH2Transport", "disconnect: " + description); - } - - private void negotiateVersion() throws IOException, SSH2Exception { - String idString; - String ourVersion = SSH2.getVersionId(ourPrefs.getPackageVersion()); - - if(weAreAServer) { - serverVersion = ourVersion; - idString = serverVersion + "\r\n"; - tpOut.write(idString.getBytes()); - tpOut.flush(); - clientVersion = idString; - tpLog.info("SSH2Transport", "peer's version is '" + - clientVersion + "'"); - } else { - clientVersion = ourVersion; - idString = clientVersion + "\r\n"; - tpOut.write(idString.getBytes()); - tpOut.flush(); - while(!(idString = readIdString()).startsWith("SSH-")) { - eventHandler.gotConnectInfoText(this, idString); - } - serverVersion = idString; - tpLog.info("SSH2Transport", "peer's version is '" + - serverVersion + "'"); - } - - checkPeerVersion(clientVersion, serverVersion); - } - - private void checkPeerVersion(String clientVersion, String serverVersion) - throws SSH2Exception - { - String cliPackage = extractPackageVersion(clientVersion); - String srvPackage = extractPackageVersion(serverVersion); - int cliMajor = extractMajor(clientVersion); - int cliMinor = extractMinor(clientVersion); - int srvMajor = extractMajor(serverVersion); - int srvMinor = extractMinor(serverVersion); - - if(weAreAServer) { - eventHandler.gotPeerVersion(this, clientVersion, - cliMajor, cliMinor, cliPackage); - } else { - eventHandler.gotPeerVersion(this, serverVersion, - srvMajor, srvMinor, srvPackage); - } - - if(cliMajor != srvMajor && !(srvMajor == 1 && srvMinor == 99)) { - String msg; - if(weAreAServer) { - msg = "Can't serve a client with version " + clientVersion; - } else { - msg = "Can't connect to a server with version " + serverVersion; - } - throw new SSH2FatalException(msg); - } - - String peerPackage = (weAreAServer ? cliPackage : srvPackage); - - if(peerPackage.startsWith("2.0.7 ") || - peerPackage.startsWith("2.0.8 ") || - peerPackage.startsWith("2.0.9 ")) { - throw new SSH2FatalException("Peer's version is too old: " + peerPackage); - } - - incompatibleServiceAccept = peerPackage.startsWith("2.0.11 ") || - peerPackage.startsWith("2.0.12 ") || - peerPackage.startsWith("2.0.13 "); - - incompatiblePublicKeyAuth = incompatibleServiceAccept; - - incompatibleChannelOpenFail = incompatibleServiceAccept; - - incompatibleSignature = peerPackage.startsWith("2.1.0 SSH") || - (peerPackage.startsWith("2.1.0") && - peerPackage.indexOf("F-SECURE") != -1) || - incompatibleServiceAccept; - - incompatibleHMACKeyLength = incompatibleSignature || - peerPackage.startsWith("2.2.0 SSH") || - peerPackage.startsWith("2.3.0 SSH") || - ((peerPackage.startsWith("2.2.0") || - peerPackage.startsWith("2.3.0")) && - peerPackage.indexOf("F-SECURE") != -1); - - incompatiblePublicKeyUserId = incompatibleSignature || - peerPackage.startsWith("OpenSSH_2.0") || - peerPackage.startsWith("OpenSSH_2.1") || - peerPackage.startsWith("OpenSSH_2.2"); - - incompatibleRijndael = peerPackage.startsWith("OpenSSH_2.5.1p1") || - peerPackage.startsWith("OpenSSH_2.5.0") || - peerPackage.startsWith("OpenSSH_2.3"); - - incompatibleCantReKey = incompatiblePublicKeyUserId || - peerPackage.startsWith("OpenSSH_2.3") || - peerPackage.startsWith("OpenSSH_2.5.1") || - peerPackage.startsWith("OpenSSH_2.5.2"); - - if(incompatibleServiceAccept) { - tpLog.notice("SSH2Transport", - "enabling draft incompatible SERVICE_ACCEPT"); - tpLog.notice("SSH2Transport", - "enabling draft incompatible publickey method"); - tpLog.notice("SSH2Transport", - "enabling draft incompatible CHANNEL_OPEN_FAILURE"); - } - if(incompatibleSignature) { - tpLog.notice("SSH2Transport", - "enabling draft incompatible signature format"); - } - if(incompatibleHMACKeyLength) { - tpLog.notice("SSH2Transport", - "enabling rfc incompatible hmac key length"); - } - if(incompatiblePublicKeyUserId) { - tpLog.notice("SSH2Transport", - "enabling draft incompatible session id for signature"); - } - if(incompatibleRijndael) { - tpLog.notice("SSH2Transport", - "disabling aes/rijndael cipher, peer has buggy implementation"); - } - if(incompatibleCantReKey) { - tpLog.notice("SSH2Transport", - "disabling key re-exchange, not implemented in peer"); - } - } - - /** - * Extracts the major version from a version string (as defined in the - * protocol spec.) - * - * @param the full version string - * - * @return the major version number - * - * @exception SSH2Exception if there is a format error - */ - public static int extractMajor(String versionStr) throws SSH2Exception { - try { - int r = versionStr.indexOf('.', 4); - return Integer.parseInt(versionStr.substring(4, r)); - } catch (NumberFormatException e) { - throw new SSH2FatalException("Corrupt version string: " + - versionStr); - } - } - - /** - * Extracts the minor version from a version string (as defined in the - * protocol spec.) - * - * @param the full version string - * - * @return the minor version number - * - * @exception SSH2Exception if there is a format error - */ - public static int extractMinor(String versionStr) throws SSH2Exception { - try { - int l = versionStr.indexOf('.', 4) + 1; - int r = versionStr.indexOf('-', l); - return Integer.parseInt(versionStr.substring(l, r)); - } catch (NumberFormatException e) { - throw new SSH2FatalException("Corrupt version string: " + - versionStr); - } - } - - /** - * Extracts the package version (defined as softwareversion and comments in - * the protocol spec.) from a version string. - * - * @param the full version string - * - * @return the package version (i.e. software version and comments) - * - * @exception SSH2Exception if there is a format error - */ - public static String extractPackageVersion(String versionStr) - throws SSH2Exception - { - try { - int i = versionStr.indexOf('-', 4) + 1; - return versionStr.substring(i); - } catch (Exception e) { - throw new SSH2FatalException("Corrupt version string: " + - versionStr); - } - } - - private String readIdString() throws IOException, SSH2Exception { - byte[] buf = new byte[256]; - int len = 0; - int c; - - while(true) { - c = tpIn.read(); - if(c == -1) { - throw new SSH2EOFException("Server closed connection before sending identifaction"); - } - if(c == '\r') - continue; - if(c != '\n') { - buf[len++] = (byte)c; - } else { - return new String(buf, 0, len); - } - } - } - - private void sendKEXINIT() throws SSH2Exception { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_KEXINIT); - byte[] cookie = new byte[16]; - tpRand.nextBytes(cookie); - pdu.writeRaw(cookie); - ourPrefs.writeTo(pdu); - pdu.writeBoolean(false); - pdu.writeInt(0); - - if(weAreAServer) { - serverKEXINITPkt = pdu.makeCopy(); - } else { - clientKEXINITPkt = pdu.makeCopy(); - } - - transmitInternal(pdu); - eventHandler.kexStart(this); - } - - private void processKEXINIT(SSH2TransportPDU pdu) throws SSH2Exception { - startKeyExchange(); - - if(weAreAServer) { - clientKEXINITPkt = pdu; - } else { - serverKEXINITPkt = pdu; - } - - pdu.readRaw(16); // Cookie, we don't need it - peerPrefs = new SSH2TransportPreferences(); - peerPrefs.readFrom(pdu); - boolean firstKEXFollows = pdu.readBoolean(); - pdu.readInt(); // Reserved int, we don't need it - - tpLog.info("SSH2Transport", "peer kex algorithms: " + - peerPrefs.listPreference(SSH2TransportPreferences.KEX_ALGORITHMS)); - tpLog.info("SSH2Transport", "peer host key algorithms: " + - peerPrefs.listPreference(SSH2TransportPreferences.HOST_KEY_ALG)); - tpLog.info("SSH2Transport", "peer enc. alg. cli2srv: " + - peerPrefs.listPreference(SSH2TransportPreferences.CIPHERS_C2S)); - tpLog.info("SSH2Transport", "peer enc. alg. srv2cli: " + - peerPrefs.listPreference(SSH2TransportPreferences.CIPHERS_S2C)); - tpLog.info("SSH2Transport", "peer mac alg. cli2srv: " + - peerPrefs.listPreference(SSH2TransportPreferences.MACS_C2S)); - tpLog.info("SSH2Transport", "peer mac alg. srv2cli: " + - peerPrefs.listPreference(SSH2TransportPreferences.MACS_S2C)); - tpLog.info("SSH2Transport", "peer comp. alg. cli2srv: " + - peerPrefs.listPreference(SSH2TransportPreferences.COMP_C2S)); - tpLog.info("SSH2Transport", "peer comp. alg. srv2cli: " + - peerPrefs.listPreference(SSH2TransportPreferences.COMP_S2C)); - tpLog.info("SSH2Transport", "our kex algorithms: " + - ourPrefs.listPreference(SSH2TransportPreferences.KEX_ALGORITHMS)); - tpLog.info("SSH2Transport", "our host key algorithms: " + - ourPrefs.listPreference(SSH2TransportPreferences.HOST_KEY_ALG)); - tpLog.info("SSH2Transport", "our enc. alg. cli2srv: " + - ourPrefs.listPreference(SSH2TransportPreferences.CIPHERS_C2S)); - tpLog.info("SSH2Transport", "our enc. alg. srv2cli: " + - ourPrefs.listPreference(SSH2TransportPreferences.CIPHERS_S2C)); - tpLog.info("SSH2Transport", "our mac alg. cli2srv: " + - ourPrefs.listPreference(SSH2TransportPreferences.MACS_C2S)); - tpLog.info("SSH2Transport", "our mac alg. srv2cli: " + - ourPrefs.listPreference(SSH2TransportPreferences.MACS_S2C)); - tpLog.info("SSH2Transport", "our comp. alg. cli2srv: " + - ourPrefs.listPreference(SSH2TransportPreferences.COMP_C2S)); - tpLog.info("SSH2Transport", "our comp. alg. srv2cli: " + - ourPrefs.listPreference(SSH2TransportPreferences.COMP_S2C)); - - keyExchanger = ourPrefs.selectKEXAlgorithm(peerPrefs, weAreAServer); - - tpLog.notice("SSH2Transport", "KEX algorithm chosen: " + - ourPrefs.getKEXAlgorithm()); - tpLog.info("SSH2Transport", "same KEX guessed? " + - ourPrefs.sameKEXGuess()); - tpLog.info("SSH2Transport", "first KEX follows? " + firstKEXFollows); - - if(!ourPrefs.canAgree(peerPrefs, weAreAServer)) { - throw new SSH2FatalException( - "Can't agree on transport preferences with peer"); - } - - if(firstKEXFollows && !ourPrefs.sameKEXGuess()) { - // Discard next packet which is the incorrectly guessed KEX packet - // - try { - receiveInternal(); - } catch (IOException e) { - throw new SSH2FatalException("I/O error when reading guessed " + - "packet", e); - } catch (ShortBufferException e) { - throw new SSH2FatalException("Internal error/bug: " + - e.getMessage()); - } - tpLog.notice("SSH2Transport", "first KEX packet discarded, " + - "wrong initial guess"); - } - - eventHandler.kexAgreed(this, ourPrefs, peerPrefs); - - keyExchanger.init(this); - } - - private void removeRijndael() { - boolean removedAES = false; - String l1, l2; - l1 = ourPrefs.listPreference(SSH2TransportPreferences.CIPHERS_C2S); - l2 = ourPrefs.listPreference(SSH2TransportPreferences.CIPHERS_S2C); - - int l1l = l1.length(); - int l2l = l2.length(); - - l1 = SSH2ListUtil.removeAllPrefixFromList(l1, "aes"); - l1 = SSH2ListUtil.removeAllPrefixFromList(l1, "rijndael"); - l2 = SSH2ListUtil.removeAllPrefixFromList(l2, "aes"); - l2 = SSH2ListUtil.removeAllPrefixFromList(l2, "rijndael"); - - if(l1.length() != l1l) { - ourPrefs.setPreference(SSH2TransportPreferences.CIPHERS_C2S, - l1); - removedAES = true; - } - if(l2.length() != l2l) { - ourPrefs.setPreference(SSH2TransportPreferences.CIPHERS_S2C, - l2); - removedAES = true; - } - if(removedAES) { - tpLog.warning("SSH2Transport", - "removed AES cipher from our preferences" + - " due to bug in peer's implementation"); - } - } - - /** - * Sends the NEWKEYS paket type and changes the transmitter keys according - * to the current prefs (as negotiated before). Typically used from a - * subclass to SSH2KeyExchanger. - * - * @exception SSH2Exception if an error occurs while sending the packet. - */ - public void sendNewKeys() throws SSH2Exception { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_NEWKEYS); - transmitInternal(pdu); - changeTransmitterKeys(); - txQueue.enable(); - } - - /** - * Authenticates the server through its host key. Typically used from a - * subclass to SSH2KeyExchanger. - * - * @param serverHostKey byte array containing server's host key (e.g. a - * public key blob or a certificate). - * @param serverSigH byte array containing server's signature of the - * exchange hash which should be verified. - * @param the exchange hash - * - * @exception SSH2Exception if an error occurs - */ - public void authenticateHost(byte[] serverHostKey, byte[] serverSigH, - byte[] exchangeHash_H) - throws SSH2Exception - { - tpLog.debug2("SSH2Transport", "authenticateHost", - "Server's public host key: ", serverHostKey); - tpLog.debug2("SSH2Transport", "authenticateHost", - "Signature over H: ", serverSigH); - tpLog.debug2("SSH2Transport", "authenticateHost", - "Exchange hash H", exchangeHash_H); - - boolean verified = false; - SSH2Signature signature = - SSH2Signature.getInstance(ourPrefs.getHostKeyAlgorithm()); - - signature.initVerify(serverHostKey); - signature.setIncompatibility(this); - - verified = signature.verify(serverSigH, exchangeHash_H); - - if(verified) { - tpLog.notice("SSH2Transport", "server's signature verified"); - } else { - String msg = "server's signature didn't verify"; - tpLog.error("SSH2Transport", "authenticateHost", msg); - fatalDisconnect(SSH2.DISCONNECT_HOST_KEY_NOT_VERIFIABLE, msg); - throw new SSH2FatalException(msg); - } - - if(!eventHandler.kexAuthenticateHost(this, signature)) { - throw new SSH2SignatureException("Host authentication failed"); - } - } - - 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()); - - // Note, we don't use transmitInternal since we don't want to - // loop over the exception handler here - // - pdu.writeTo(tpOut, txSeqNum++, - txMAC, txCipher, txCompressor, tpRand); - } - } 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); - } finally { - shutdownTx(); - kexComplete(false); - authTerminate(); - } - tpLog.debug("SSH2Transport", "transportTransmitLoop", - "stopping"); - } - - private void transportReceiveLoop() { - isRxUp = true; - tpLog.debug("SSH2Transport", "transportReceiveLoop", - "starting"); - try { - while(isRxUp) { - SSH2TransportPDU pdu = receiveInternal(); - - switch(pdu.pktType) { - case SSH2.MSG_DISCONNECT: { - int reason = pdu.readInt(); - String description = pdu.readJavaString(); - String languageTag = pdu.readJavaString(); - // !!! TODO, disconnect ourselves (not trying to send disc...) - eventHandler.peerDisconnect(this, reason, description, - languageTag); - 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"); - changeReceiverKeys(); - 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: - connection.processGlobalMessage(pdu); - break; - case SSH2.MSG_CHANNEL_OPEN: - connection.processGlobalMessage(pdu); - pdu = null; - break; - - case SSH2.MSG_CHANNEL_DATA: - case SSH2.MSG_CHANNEL_EXTENDED_DATA: - connection.processChannelMessage(pdu); - pdu = null; - break; - - 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); - 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(); - } - } - } catch (ShortBufferException e) { - String msg = "Internal error/bug: " + e.getMessage(); - tpLog.error("SSH2Transport", "transportReceiveLoop", msg); - disconnectInternal(SSH2.DISCONNECT_CONNECTION_LOST, msg, - /* !!! TODO: languageTag, from ourPrefs? */ "", - false); - } catch (SSH2MacCheckException e) { - String msg = e.getMessage(); - tpLog.error("SSH2Transport", "transportReceiveLoop", msg); - disconnectInternal(SSH2.DISCONNECT_MAC_ERROR, msg, - /* !!! TODO: languageTag, from ourPrefs? */ "", - false); - } catch (SSH2CompressionException e) { - String msg = e.getMessage(); - tpLog.error("SSH2Transport", "transportReceiveLoop", msg); - disconnectInternal(SSH2.DISCONNECT_COMPRESSION_ERROR, msg, - /* !!! TODO: languageTag, from ourPrefs? */ "", - false); - } catch (SSH2SignatureException e) { - String msg = e.getMessage(); - tpLog.error("SSH2Transport", "transportReceiveLoop", msg); - 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() + ")"; - } - tpLog.error("SSH2Transport", "transportReceiveLoop", msg); - disconnectInternal(SSH2.DISCONNECT_PROTOCOL_ERROR, msg, - /* !!! TODO: languageTag, from ourPrefs? */ "", - false); - } - } catch (IOException e) { - if(isRxUp) { - String msg = "I/O error: " + e.getMessage(); - tpLog.error("SSH2Transport", "transportReceiveLoop", msg); - disconnectInternal(SSH2.DISCONNECT_CONNECTION_LOST, msg, - /* !!! TODO: languageTag, from ourPrefs? */ "", - false); - } - } finally { - shutdownRx(); - kexComplete(false); - authTerminate(); - } - tpLog.debug("SSH2Transport", "transportReceiveLoop", - "stopping"); - } - - /** - * Receives a PDU directly from the InputStream 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++, rxMAC, rxCipher, rxCompressor); - - 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 changeTransmitterKeys() throws SSH2Exception { - try { - String cipherName = ourPrefs.getTransmitterCipher(); - String macName = ourPrefs.getTransmitterMac(); - String compName = ourPrefs.getTransmitterCompression(); - tpLog.info("SSH2Transport", "new transmitter context (" + - cipherName + "," + macName + "," + compName + ")"); - txCipher = - Cipher.getInstance(ourPrefs.ssh2ToJCECipher(cipherName)); - txMAC = Mac.getInstance(ourPrefs.ssh2ToJCEMac(macName)); - initKeys(txCipher, ourPrefs.getCipherKeyLen(cipherName), - txMAC, - (incompatibleHMACKeyLength ? 16 : - ourPrefs.getMacKeyLen(macName)), - true); - txCompressor = - SSH2Compressor.getInstance(compName, - SSH2Compressor.COMPRESS_MODE, - ourPrefs.getCompressionLevel()); - } catch (Exception e) { - txCipher = null; - txMAC = null; - throw new SSH2FatalException("Error in changeTransmitterKeys", e); - } - } - - private synchronized void changeReceiverKeys() throws SSH2Exception { - try { - String cipherName = ourPrefs.getReceiverCipher(); - String macName = ourPrefs.getReceiverMac(); - String compName = ourPrefs.getReceiverCompression(); - tpLog.info("SSH2Transport", "new receiver context (" + - cipherName + "," + macName + "," + compName + ")"); - rxCipher = - Cipher.getInstance(ourPrefs.ssh2ToJCECipher(cipherName)); - rxMAC = Mac.getInstance(ourPrefs.ssh2ToJCEMac(macName)); - initKeys(rxCipher, ourPrefs.getCipherKeyLen(cipherName), - rxMAC, - (incompatibleHMACKeyLength ? 16 : - ourPrefs.getMacKeyLen(macName)), - false); - rxCompressor = - SSH2Compressor.getInstance(compName, - SSH2Compressor.UNCOMPRESS_MODE); - } catch (Exception e) { - rxCipher = null; - rxMAC = null; - throw new SSH2FatalException("Error in changeReceiverKeys", e); - } - - kexComplete(true); - } - - private void initKeys(Cipher cipher, int ckLen, Mac mac, int mkLen, - boolean transmit) - throws SSH2Exception - { - byte[] iv, cKey, mKey; - char[] ids; - if(weAreAServer ^ transmit) { - ids = new char[] { 'A', 'C', 'E' }; - } else { - ids = new char[] { 'B', 'D', 'F' }; - } - - iv = deriveKey(ids[0], cipher.getBlockSize()); - cKey = deriveKey(ids[1], ckLen); - mKey = deriveKey(ids[2], mkLen); - - try { - if(cipher != null) { - cipher.init(transmit ? Cipher.ENCRYPT_MODE : - Cipher.DECRYPT_MODE, - new SecretKeySpec(cKey, cipher.getAlgorithm()), - new IvParameterSpec(iv)); - } - if(mac != null) { - mac.init(new SecretKeySpec(mKey, mac.getAlgorithm())); - } - } catch (InvalidKeyException e) { - throw new SSH2FatalException("Invalid key generated in initKeys"); - } - } - - 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; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2TransportEventAdapter.java b/src/main/java/com/mindbright/ssh2/SSH2TransportEventAdapter.java deleted file mode 100644 index d40637f..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2TransportEventAdapter.java +++ /dev/null @@ -1,68 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.IOException; - -/** - * This class is an adapter for the interface - * SSH2TransportEventHandler. - * - * @see SSH2TransportEventHandler - */ -public class SSH2TransportEventAdapter implements SSH2TransportEventHandler { - public void gotConnectInfoText(SSH2Transport tp, String text) { - } - public void gotPeerVersion(SSH2Transport tp, String versionString, - int major, int minor, String packageVersion) { - } - - public void kexStart(SSH2Transport tp) { - } - public void kexAgreed(SSH2Transport tp, - SSH2TransportPreferences ourPrefs, - SSH2TransportPreferences peerPrefs) { - } - public boolean kexAuthenticateHost(SSH2Transport tp, - SSH2Signature serverHostKey) - { - return true; - } - public void kexComplete(SSH2Transport tp) { - } - - public void msgDebug(SSH2Transport tp, boolean alwaysDisplay, String message, - String languageTag) { - } - public void msgIgnore(SSH2Transport tp, byte[] data) { - } - public void msgUnimplemented(SSH2Transport tp, int rejectedSeqNum) { - } - - public void peerSentUnknownMessage(SSH2Transport tp, int pktType) { - } - - public void normalDisconnect(SSH2Transport tp, String description, - String languageTag) { - } - public void fatalDisconnect(SSH2Transport tp, int reason, - String description, String languageTag) { - } - public void peerDisconnect(SSH2Transport tp, int reason, - String description, String languageTag) { - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2TransportEventHandler.java b/src/main/java/com/mindbright/ssh2/SSH2TransportEventHandler.java deleted file mode 100644 index 9dce9c1..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2TransportEventHandler.java +++ /dev/null @@ -1,173 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.IOException; - -/** - * This interface is an event callback interface used to monitor the transport - * layer of an ssh2 connection. It is used with the class - * SSH2Transport to get info on the progress and status of the ssh2 - * connection. It is also used to authenticate the host running the ssh2 server - * (e.g. through comparing its public key to a known key or verifying its - * certificate). - * - * @see SSH2Transport - * @see SSH2TransportEventAdapter - */ -public interface SSH2TransportEventHandler { - - /** - * Called when an info text is received in the version negotiation stage (as - * defined in the transport protocol spec.). - * - * @param tp the transport layer - * @param text the info text received - */ - public void gotConnectInfoText(SSH2Transport tp, String text); - - /** - * Called in the version negotiation stage when the peer version is received - * (as defined in the transport protocol spec.). - * - * @param tp the transport layer - * @param versionString the version string of peer - * @param major the major protocol version of peer - * @param minor the minor protocol version of peer - * @param packageVersion the package version of peer - */ - public void gotPeerVersion(SSH2Transport tp, String versionString, - int major, int minor, String packageVersion); - - /** - * Called when key exchange starts (i.e. when KEXINIT message is sent to - * peer). - * - * @param tp the transport layer - */ - public void kexStart(SSH2Transport tp); - - /** - * Called when key exchange have agreed on algorithms (i.e. when KEXINIT - * message has been received and processed). - * - * @param tp the transport layer - * @param ourPrefs our preferences - * @param peerPrefs peer's preferences - */ - public void kexAgreed(SSH2Transport tp, - SSH2TransportPreferences ourPrefs, - SSH2TransportPreferences peerPrefs); - - /** - * Called to authenticate server's host key. - * - * @param tp the transport layer - * @param serverHostKey server's host key - * - * @return a boolean indicating if the server could be authenticated or not. - */ - public boolean kexAuthenticateHost(SSH2Transport tp, - SSH2Signature serverHostKey); - - /** - * Called when key exchange has been successfully completed (i.e. new - * keys and algorithms are now active). - * - * @param tp the transport layer - */ - public void kexComplete(SSH2Transport tp); - - /** - * Called when a DEBUG message is received. - * - * @param tp the transport layer - * @param alwaysDisplay boolean flag indicating whether this message should - * always be displayed or not. - * @param message debug message contained in the packet - * @param languageTag language tag - */ - public void msgDebug(SSH2Transport tp, boolean alwaysDisplay, - String message, String languageTag); - - /** - * Called when an IGNORE message is received. - * - * @param tp the transport layer - * @param data byte array of data contained in packet - */ - public void msgIgnore(SSH2Transport tp, byte[] data); - - /** - * Called when an UNIMPLEMENTED message is received. - * - * @param tp the transport layer - * @param rejectedSeqNum sequence number of packet which peer didn't - * understnad - */ - public void msgUnimplemented(SSH2Transport tp, int rejectedSeqNum); - - /** - * Called when an unimplemented message is received, and an UNIMPLEMENTED - * message is sent to peer. - * - * @param tp the transport layer - * @param type type of message which we didn't understand - */ - public void peerSentUnknownMessage(SSH2Transport tp, int pktType); - - /** - * Called when transport layer is disconnected gracefully by our side of - * connection. - * - * @param tp the transport layer - * @param description textual description for reason of disconnect - * @param languageTag language tag - */ - public void normalDisconnect(SSH2Transport tp, String description, - String languageTag); - - - /** - * Called when transport layer is disconnected for the given fatal reason by - * our side of the connection. See the class SSH2 for reason - * codes. - * - * @param tp the transport layer - * @param reason the reason code - * @param description textual description for reason of disconnect - * @param languageTag language tag - * - * @see SSH2 - */ - public void fatalDisconnect(SSH2Transport tp, int reason, - String description, String languageTag); - - /** - * Called when peer disconnects the transport layer for some given - * reason. See the class SSH2 for reason codes. - * - * @param tp the transport layer - * @param reason the reason code - * @param description textual description for reason of disconnect - * @param languageTag language tag - * - * @see SSH2 - */ - public void peerDisconnect(SSH2Transport tp, int reason, - String description, String languageTag); - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2TransportPDU.java b/src/main/java/com/mindbright/ssh2/SSH2TransportPDU.java deleted file mode 100644 index 55d3446..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2TransportPDU.java +++ /dev/null @@ -1,267 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.IOException; - -import javax.crypto.Cipher; -import javax.crypto.Mac; -import javax.crypto.ShortBufferException; - -import com.mindbright.util.SecureRandomAndPad; - -public class SSH2TransportPDU extends SSH2DataBuffer { - public final static int PACKET_DEFAULT_SIZE = 8192 + 256; - public final static int PACKET_MIN_SIZE = 16; - public final static int PACKET_MAX_SIZE = 35000; - - // !!! public static SSH2TransportPDU factoryInstance = new SSH2TransportPDU(); - public static SSH2TransportPDU factoryInstance = new SSH2TransportPDUPool(); - - byte[] macTmpBuf; - - int pktSize; - int padSize; - int pktType; - - protected SSH2TransportPDU() { - /* Factory instance constructor */ - } - - protected SSH2TransportPDU(int pktType, int bufSize) { - super(bufSize); - this.pktType = pktType; - this.pktSize = 0; - this.padSize = 0; - this.macTmpBuf = new byte[128]; - } - - protected SSH2TransportPDU createInPDU(int bufSize) { - return new SSH2TransportPDU(0, bufSize); - } - - protected SSH2TransportPDU createOutPDU(int pktType, int bufSize) { - return new SSH2TransportPDU(pktType, bufSize); - } - - public final static void setFactoryInstance(SSH2TransportPDU factory) { - factoryInstance = factory; - } - - public final static SSH2TransportPDU createIncomingPacket(int bufSize) { - return factoryInstance.createInPDU(bufSize); - } - - public final static SSH2TransportPDU createIncomingPacket() { - return createIncomingPacket(PACKET_DEFAULT_SIZE); - } - - public final static SSH2TransportPDU createOutgoingPacket(int pktType, - int bufSize) { - SSH2TransportPDU pdu = factoryInstance.createOutPDU(pktType, bufSize); - pdu.writeInt(0); // dummy sequence number - pdu.writeInt(0); // dummy length - pdu.writeByte(0); // dummy pad-length - pdu.writeByte(pktType); - return pdu; - } - - public final static SSH2TransportPDU createOutgoingPacket(int pktType) { - return createOutgoingPacket(pktType, PACKET_DEFAULT_SIZE); - } - - public void release() { - } - - public SSH2TransportPDU makeCopy() { - SSH2TransportPDU copy = factoryInstance.createOutPDU(this.pktType, - this.data.length); - System.arraycopy(this.data, 0, copy.data, 0, this.data.length); - copy.pktSize = this.pktSize; - copy.padSize = this.padSize; - copy.rPos = this.rPos; - copy.wPos = this.wPos; - - return copy; - } - - public int getType() { - return pktType; - } - - public int getPayloadLength() { - int plSz; - if(pktSize == 0) { - plSz = wPos - getPayloadOffset(); - } else { - plSz = pktSize - padSize - 1; - } - return plSz; - } - - public int getPayloadOffset() { - return 4 + 4 + 1; // Skip sequence, length and padsize - } - - protected void readFrom(InputStream in, int seqNum, - Mac mac, Cipher cipher, SSH2Compressor compressor) - throws IOException, SSH2Exception, ShortBufferException - { - writeInt(seqNum); // Not received, used for MAC calculation - rPos = 4; // Skip it also (i.e. we don't want to read it) - int bs = 8; - int macSize = 0; - if(cipher != null) { - bs = cipher.getBlockSize(); - bs = (bs > 8 ? bs : 8); - readNextNFrom(in, bs); - cipher.doFinal(data, 4, bs, data, 4); // Skip seqNum - } else { - readNextNFrom(in, 8); - } - bs -= 4; // The part of body pre-read above (i.e. subtract length-field) - pktSize = readInt(); - - if(mac != null) { - macSize = mac.getMacLength(); - } - - int totPktSz = (pktSize + 4 + macSize); - if(totPktSz > PACKET_MAX_SIZE || totPktSz < PACKET_MIN_SIZE) { - throw new SSH2CorruptPacketException("Invalid packet size: " + - pktSize); - } - - readNextNFrom(in, pktSize - bs); // Allready read bs bytes of body - - if(cipher != null) { - cipher.doFinal(data, 8 + bs, pktSize - bs, data, 8 + bs); - } - - if(mac != null) { - readNextNFrom(in, macSize); - checkMac(seqNum, mac, macSize); - } - - padSize = readByte(); - - if(compressor != null) { - // Update pktSize so getPayloadLength() calculates right value - pktSize = compressor.uncompress(this, pktSize - padSize - 1); - pktSize += padSize + 1; - } - - pktType = readByte(); - } - - protected void checkMac(int seqNum, Mac mac, int macSize) - throws SSH2MacCheckException, ShortBufferException - { - mac.update(data, 0, 8 + pktSize); - mac.doFinal(macTmpBuf, 0); - int dOff = 8 + pktSize; - for(int i = 0; i < macSize; i++) { - if(macTmpBuf[i] != data[dOff++]) { - throw new SSH2MacCheckException("MAC check failed"); - } - } - } - - private final void readNextNFrom(InputStream in, int n) - throws IOException, SSH2EOFException - { - if((data.length - wPos) < n) { - byte[] tmp = data; - int newSz = data.length * 2; - if(newSz - wPos < n) { - newSz = wPos + n + (wPos >>> 1); - } - data = new byte[newSz]; - System.arraycopy(tmp, 0, data, 0, tmp.length); - } - n += wPos; - while(wPos < n) { - int s = in.read(data, wPos, n - wPos); - if(s == -1) - throw new SSH2EOFException("Server closed connection"); - wPos += s; - } - } - - protected void writeTo(OutputStream out, int seqNum, - Mac mac, Cipher cipher, SSH2Compressor compressor, - SecureRandomAndPad rand) - throws IOException, ShortBufferException, SSH2CompressionException - { - int macSize = 0; - int bs = 8; - - if(compressor != null) { - compressor.compress(this); - } - - if(cipher != null) { - bs = cipher.getBlockSize(); - bs = (bs > 8 ? bs : 8); - } - - // Subtract dummy sequence number since it is not sent - // - padSize = bs - ((wPos - 4) % bs); - if(padSize < 4) - padSize += bs; - - // sequence + length fields not counted in packet-length - // - pktSize = wPos + padSize - 8; - rand.nextPadBytes(data, wPos, padSize); - - wPos = 0; - writeInt(seqNum); // Not transmitted, used for MAC calculation - writeInt(pktSize); - writeByte(padSize); - int totPktSz = pktSize + 4; // packet size including length field - - if(mac != null) { - // The MAC is calculated on full packet including sequence number - // - int macOffset = 4 + totPktSz; - mac.update(data, 0, macOffset); - mac.doFinal(data, macOffset); - macSize = mac.getMacLength(); - } - - if(cipher != null) { - cipher.doFinal(data, 4, totPktSz, data, 4); - } - - out.write(data, 4, totPktSz + macSize); - out.flush(); // !!! REMOVE(?) - release(); - } - - public String toString() { - return "pdu: buf-sz = " + data.length + - ", rPos = " + rPos + - ", wPos = " + wPos + - ", pktSize = " + pktSize + - ", padSize = " + padSize + - ", pktType = " + pktType; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2TransportPDUPool.java b/src/main/java/com/mindbright/ssh2/SSH2TransportPDUPool.java deleted file mode 100644 index f03632c..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2TransportPDUPool.java +++ /dev/null @@ -1,107 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public class SSH2TransportPDUPool extends SSH2TransportPDU { - - final static int POOL_SIZE = 32; - - protected class InPDU extends SSH2TransportPDU { - protected InPDU(int pktType, int bufSize) { - super(pktType, bufSize); - } - public void release() { - this.reset(); - this.pktSize = 0; - releaseIn(this); - } - } - - protected class OutPDU extends SSH2TransportPDU { - protected OutPDU(int pktType, int bufSize) { - super(pktType, bufSize); - } - public void release() { - this.reset(); - this.pktSize = 0; - releaseOut(this); - } - } - - int inCnt; - int outCnt; - - SSH2TransportPDU[] inPool; - SSH2TransportPDU[] outPool; - - protected SSH2TransportPDUPool() { - inPool = new SSH2TransportPDU[POOL_SIZE]; - outPool = new SSH2TransportPDU[POOL_SIZE]; - inCnt = POOL_SIZE; - outCnt = POOL_SIZE; - for(int i = 0; i < POOL_SIZE; i++) { - inPool[i] = new InPDU(0, PACKET_DEFAULT_SIZE); - outPool[i] = new OutPDU(0, PACKET_DEFAULT_SIZE * 2); - } - } - - protected SSH2TransportPDU createInPDU(int bufSize) { - synchronized(inPool) { - if(inCnt == 0) { - return new InPDU(0, PACKET_DEFAULT_SIZE); - } else { - return inPool[--inCnt]; - } - } - } - - protected SSH2TransportPDU createOutPDU(int pktType, int bufSize) { - if(bufSize > (PACKET_DEFAULT_SIZE * 2)) { - return new SSH2TransportPDU(pktType, bufSize); - } - SSH2TransportPDU pdu = null; - synchronized(outPool) { - if(outCnt == 0) { - return new OutPDU(pktType, (PACKET_DEFAULT_SIZE * 2)); - } else { - pdu = outPool[--outCnt]; - } - } - pdu.pktType = pktType; - return pdu; - } - - protected void releaseIn(InPDU pdu) { - synchronized(inPool) { - if(inCnt < POOL_SIZE) { - inPool[inCnt++] = pdu; - } else { - /* stat */ - } - } - } - - protected void releaseOut(OutPDU pdu) { - synchronized(outPool) { - if(outCnt < POOL_SIZE) { - outPool[outCnt++] = pdu; - } else { - /* stat */ - } - } - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2TransportPreferences.java b/src/main/java/com/mindbright/ssh2/SSH2TransportPreferences.java deleted file mode 100644 index 38e706e..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2TransportPreferences.java +++ /dev/null @@ -1,450 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.util.Properties; - -/** - * This class is a container for all protocol preferences and the packet version - * used in the class SSH2Transport. It can be created using a - * hard-coded list of preferences or it can be created from a - * java.util.Properties instance. All preferences for algorithms - * are comma separated lists in order of preference (as defined in the trasport - * protocol spec.). - *

- * This class contains the negotiation logic to select preferences from lists of - * client and server preferences. It also contains the functionality to select a - * key exchange algorithm given the available algorithms and host key - * types. These functions are used from the SSH2Transport class. - *

- * The preferences that can be set are the following: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Property nameDescription
kex-algorithmsKey exchange algorithms
server-host-key-algorithmsHost key algorithms
enc-algorithms-cli2srvEncryption algorithms client to server
enc-algorithms-srv2cliEncryption algorithms server to client
mac-algorithms-cli2srvMac algorithms client to server
mac-algorithms-srv2cliMac algorithms server to client
comp-algorithms-cli2srvCompression algorithms client to server
comp-algorithms-srv2cliCompression algorithms server to client
languages-cli2srvLanguage tags client to server
languages-srv2cliLanguage tags server to client
compressionOutgoing compression level 0-9 (default 6)
package-versionPackage version for protocol version string
- *

- * The available algorithms are the following - * (provided their classes are included): - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
TypeAlgorithms
Key exchangediffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1
Host keyssh-dss,ssh-rsa
Ciphers3des-cbc,blowfish-cbc,aes128-cbc,aes192-cbc,aes256-cbc,twofish128-cbc, - * twofish192-cbc,twofish256-cbc,cast128-cbc,idea-cbc,arcfour
Macshmac-sha1,hmac-md5,hmac-ripemd160,hmac-sha1-96,hmac-md5-96,hmac-ripemd160-96
- * - * @see SSH2Transport - */ -public class SSH2TransportPreferences { - - public static final int KEX_ALGORITHMS = 0; - public static final int HOST_KEY_ALG = 1; - public static final int CIPHERS_C2S = 2; - public static final int CIPHERS_S2C = 3; - public static final int MACS_C2S = 4; - public static final int MACS_S2C = 5; - public static final int COMP_C2S = 6; - public static final int COMP_S2C = 7; - public static final int LANG_C2S = 8; - public static final int LANG_S2C = 9; - - public static final int CIPHER = CIPHERS_C2S; - public static final int MAC = MACS_C2S; - public static final int COMPRESSION = COMP_C2S; - public static final int LANGUAGE = LANG_C2S; - - final static String[][] ciphers = { - { "3des-cbc", "3DES/CBC" }, - { "3des-ecb", "3DES/ECB" }, - { "3des-cfb", "3DES/CFB" }, - { "3des-ofb", "3DES/OFB" }, - { "blowfish-cbc", "Blowfish/CBC" }, - { "blowfish-ecb", "Blowfish/ECB" }, - { "blowfish-cfb", "Blowfish/CFB" }, - { "blowfish-ofb", "Blowfish/OFB" }, - { "aes128-cbc", "AES/CBC" }, - { "aes192-cbc", "AES/CBC" }, - { "aes256-cbc", "AES/CBC" }, - { "rijndael128-cbc", "Rijndael/CBC" }, - { "rijndael192-cbc", "Rijndael/CBC" }, - { "rijndael256-cbc", "Rijndael/CBC" }, - { "twofish128-cbc", "Twofish/CBC" }, - { "twofish192-cbc", "Twofish/CBC" }, - { "twofish256-cbc", "Twofish/CBC" }, - { "twofish-cbc", "Twofish/CBC" }, - { "twofish-ecb", "Twofish/ECB" }, - { "twofish-cfb", "Twofish/CFB" }, - { "twofish-ofb", "Twofish/OFB" }, - { "cast128-cbc", "CAST128/CBC" }, - { "cast128-ecb", "CAST128/ECB" }, - { "cast128-cfb", "CAST128/CFB" }, - { "cast128-ofb", "CAST128/OFB" }, - { "idea-cbc", "IDEA/CBC" }, - { "idea-ecb", "IDEA/ECB" }, - { "idea-cfb", "IDEA/CFB" }, - { "idea-ofb", "IDEA/OFB" }, - { "arcfour", "RC4/OFB" } - }; - - final static String[][] macs = { - { "hmac-sha1", "HmacSHA1" }, - { "hmac-md5", "HmacMD5" }, - { "hmac-ripemd160", "HmacRIPEMD160" }, - { "hmac-sha1-96", "HmacSHA1-96" }, - { "hmac-md5-96", "HmacMD5-96" }, - { "hmac-ripemd160-96", "HmacRIPEMD160-96" }, - { "hmac-ripemd160@openssh.com", "HmacRIPEMD160" } - }; - - final static String[] fields = { - "kex-algorithms", - "server-host-key-algorithms", - "enc-algorithms-cli2srv", - "enc-algorithms-srv2cli", - "mac-algorithms-cli2srv", - "mac-algorithms-srv2cli", - "comp-algorithms-cli2srv", - "comp-algorithms-srv2cli", - "languages-cli2srv", - "languages-srv2cli" - }; - - String[] preferences; - - String pkgVersion; - - String kexAlgorithm; - String hostKeyAlgorithm; - String rxCipherName; - String rxMacName; - String rxCompName; - String rxLang; - String txCipherName; - String txMacName; - String txCompName; - String txLang; - - int compressionLevel; - - boolean sameKEXGuess; - boolean haveAgreed; - - public SSH2TransportPreferences() { - preferences = new String[10]; - } - - public SSH2TransportPreferences(String[] preferences) { - this.preferences = preferences; - } - - public SSH2TransportPreferences(Properties props) { - this(); - int i; - for(i = 0; i < 10; i++) { - String v = props.getProperty(fields[i]); - preferences[i] = v; - } - pkgVersion = props.getProperty("package-version"); - try { - compressionLevel = - Integer.parseInt(props.getProperty("compression")); - } catch (Exception e) { - compressionLevel = 6; - } - } - - public void setPackageVersion(String pkgVersion) { - this.pkgVersion = pkgVersion; - } - - public String getPackageVersion() { - return pkgVersion; - } - - public void readFrom(SSH2TransportPDU pdu) { - for(int i = 0; i < 10; i++) { - preferences[i] = new String(pdu.readString()); - } - } - - public void writeTo(SSH2TransportPDU pdu) { - for(int i = 0; i < 10; i++) { - pdu.writeString(preferences[i]); - } - } - - public boolean sameKEXGuess() { - return sameKEXGuess; - } - - public boolean canAgree(SSH2TransportPreferences peerPrefs, - boolean weAreAServer) { - rxCipherName = chooseReceiverPref(CIPHER, peerPrefs, weAreAServer); - rxMacName = chooseReceiverPref(MAC, peerPrefs, weAreAServer); - rxCompName = chooseReceiverPref(COMPRESSION, peerPrefs, weAreAServer); - rxLang = chooseReceiverPref(LANGUAGE, peerPrefs, weAreAServer); - - txCipherName = chooseTransmitterPref(CIPHER, peerPrefs, weAreAServer); - txMacName = chooseTransmitterPref(MAC, peerPrefs, weAreAServer); - txCompName = chooseTransmitterPref(COMPRESSION, peerPrefs, weAreAServer); - txLang = chooseTransmitterPref(LANGUAGE, peerPrefs, weAreAServer); - - if(rxCipherName == null || - rxMacName == null || - rxCompName == null || - txCipherName == null || - txMacName == null || - txCompName == null) { - haveAgreed = false; - sameKEXGuess = false; - } else { - haveAgreed = true; - } - - return haveAgreed; - } - - public String getKEXAlgorithm() { - return kexAlgorithm; - } - - public String getHostKeyAlgorithm() { - return hostKeyAlgorithm; - } - - public String getReceiverCipher() { - return rxCipherName; - } - - public String getReceiverMac() { - return rxMacName; - } - - public String getReceiverCompression() { - return rxCompName; - } - - public int getCompressionLevel() { - return compressionLevel; - } - - public String getTransmitterCipher() { - return txCipherName; - } - - public String getTransmitterMac() { - return txMacName; - } - - public String getTransmitterCompression() { - return txCompName; - } - - public String listPreference(int type) { - return preferences[type]; - } - - public void setPreference(int type, String list) { - preferences[type] = list; - } - - public boolean isSupported(int type, String item) { - String list = listPreference(type); - return SSH2ListUtil.isInList(list, item); - } - - public SSH2KeyExchanger - selectKEXAlgorithm(SSH2TransportPreferences peerPrefs, - boolean weAreAServer) - throws SSH2KEXFailedException - { - SSH2KeyExchanger kexImpl = null; - String cliKEXList, srvKEXList, cliHKAList, srvHKAList; - - if(weAreAServer) { - cliKEXList = peerPrefs.listPreference(KEX_ALGORITHMS); - srvKEXList = listPreference(KEX_ALGORITHMS); - cliHKAList = peerPrefs.listPreference(HOST_KEY_ALG); - srvHKAList = listPreference(HOST_KEY_ALG); - } else { - cliKEXList = listPreference(KEX_ALGORITHMS); - srvKEXList = peerPrefs.listPreference(KEX_ALGORITHMS); - cliHKAList = listPreference(HOST_KEY_ALG); - srvHKAList = peerPrefs.listPreference(HOST_KEY_ALG); - } - - kexAlgorithm = SSH2ListUtil.getFirstInList(cliKEXList); - - while(kexAlgorithm != null) { - kexImpl = SSH2KeyExchanger.getInstance(kexAlgorithm); - hostKeyAlgorithm = chooseHostKeyAlgorithm(cliHKAList, srvHKAList, - kexImpl.getHostKeyAlgorithms()); - if(hostKeyAlgorithm != null) { - break; - } - cliKEXList = SSH2ListUtil.removeFirstFromList(cliKEXList, - kexAlgorithm); - kexAlgorithm = SSH2ListUtil.getFirstInList(cliKEXList); - } - - if(kexAlgorithm == null) { - throw new SSH2KEXFailedException("Client kex algorithms empty"); - } - - sameKEXGuess = - kexAlgorithm.equals(SSH2ListUtil.getFirstInList(srvKEXList)) && - hostKeyAlgorithm.equals(SSH2ListUtil.getFirstInList(srvHKAList)); - - return kexImpl; - } - - public String chooseHostKeyAlgorithm(String cliHKAList, String srvHKAList, - String kexHKAList) { - String alg = SSH2ListUtil.chooseFromList(cliHKAList, kexHKAList); - while(alg != null && !SSH2ListUtil.isInList(srvHKAList, alg)) { - cliHKAList = SSH2ListUtil.removeFirstFromList(cliHKAList, alg); - alg = SSH2ListUtil.chooseFromList(cliHKAList, kexHKAList); - } - return alg; - } - - public String chooseTransmitterPref(int type, - SSH2TransportPreferences peerPrefs, - boolean weAreAServer) { - String clientList, serverList; - if(weAreAServer) { - clientList = peerPrefs.listPreference(type + 1); - serverList = listPreference(type + 1); - } else { - clientList = listPreference(type); - serverList = peerPrefs.listPreference(type); - } - return SSH2ListUtil.chooseFromList(clientList, serverList); - } - - public String chooseReceiverPref(int type, - SSH2TransportPreferences peerPrefs, - boolean weAreAServer) { - String clientList, serverList; - if(weAreAServer) { - clientList = peerPrefs.listPreference(type); - serverList = listPreference(type); - } else { - clientList = listPreference(type + 1); - serverList = peerPrefs.listPreference(type + 1); - } - return SSH2ListUtil.chooseFromList(clientList, serverList); - } - - public static String ssh2ToJCECipher(String prefCipher) { - for(int i = 0; i < ciphers.length; i++) { - if(ciphers[i][0].equals(prefCipher)) - return ciphers[i][1]; - } - return null; - } - - public static String ssh2ToJCEMac(String prefMac) { - for(int i = 0; i < macs.length; i++) { - if(macs[i][0].startsWith(prefMac)) - return macs[i][1]; - } - return null; - } - - public static int getCipherKeyLen(String cipherName) { - int len = 128; - if(cipherName != null) { - cipherName = cipherName.toLowerCase(); - if(cipherName.indexOf("128") != -1) { - len = 128; - } else if(cipherName.indexOf("192") != -1) { - len = 192; - } else if(cipherName.indexOf("256") != -1) { - len = 256; - } else if(cipherName.startsWith("twofish") || - cipherName.startsWith("rijndael") || - cipherName.startsWith("aes")) { - len = 256; - } else if(cipherName.startsWith("3des")) { - len = 192; - } - } - return len / 8; - } - - public static int getMacKeyLen(String macName) { - int len = 16; - if(macName != null && ((macName.indexOf("SHA") != -1) || - (macName.indexOf("sha") != -1) || - (macName.indexOf("ripemd160") != -1))) { - len = 20; - } - return len; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2UserAuth.java b/src/main/java/com/mindbright/ssh2/SSH2UserAuth.java deleted file mode 100644 index 5472e18..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2UserAuth.java +++ /dev/null @@ -1,319 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.util.Hashtable; - -import com.mindbright.util.Queue; - -/** - * This class implements the user authentication layer of the secure shell - * version 2 (ssh2) protocol stack. It operates on a connected - * SSH2Transport and uses a SSH2Authenticator which - * contains the user's name and a list of one or more authentication methods - * (each coupled to a SSH2AuthModule instance) to try to - * authenticate the user. - *

- * To create a SSH2UserAuth instance a connected - * SSH2Transport and a SSH2Authenticator must be - * created first to be passed to the constructor. The constructor is passive in - * that it doesn't start any communication. To start the authentication process - * the method authenticateUser must be called. This method blocks - * (the authentication process is run in the calling thread) until either the - * user is authenticated or authentication fails. - *

- * While the authentication process runs events are reported through callbacks - * to the SSH2Authenticator. Each SSH2AuthModule - * instance (one active at a time) handles the actual processing and formatting - * of the packets specific to the authentication method it represents. - * - * @see SSH2Transport - * @see SSH2Authenticator - * @see SSH2AuthModule - */ -public final class SSH2UserAuth { - private SSH2Transport transport; - private SSH2Authenticator authenticator; - private SSH2AuthModule authModule; - - private volatile boolean isAuthenticated; - - String currentMethod; - - String service; - String user; - String ourMethods; - - Queue procQueue; - - /** - * This is the constructor. It uses the transport layer. It takes a - * SSH2Authenticator which contains the user to authenticate - * and provides a list of the authentication methods to try. It is also used - * to report authentication events. - * - * @param transport the transport layer - * @param authenticator the authenticator containing authentication info for - * the user it represents. - */ - public SSH2UserAuth(SSH2Transport transport, - SSH2Authenticator authenticator) { - this.transport = transport; - this.authenticator = authenticator; - this.isAuthenticated = false; - this.procQueue = new Queue(); - } - - /** - * Gets our transport layer. - * - * @return the transport layer - */ - public SSH2Transport getTransport() { - return transport; - } - - /** - * Gets our authenticator. - * - * @return the authenticator in use - */ - public SSH2Authenticator getAuthenticator() { - return authenticator; - } - - /** - * Authenticates the user represented by the authenticator to run the given - * service (currently "ssh-connection" is the only defined service). The - * authentication process is run in the callers thread hence the call blocks - * until either the user is authenticated or the authentication fails. - * - * @return a boolean indicating whether authentication succeeded or not - */ - public boolean authenticateUser(String service) { - this.service = service; - this.user = authenticator.getUsername(); - this.currentMethod = null; - - transport.setUserAuth(this); - transport.requestService("ssh-userauth"); - - String peerMethods = null; - boolean retry = false; - boolean partial = false; - int lastType = -1; - - authLoop: - while(!isAuthenticated) { - SSH2TransportPDU pdu = null; - - if(!retry) { - pdu = (SSH2TransportPDU)procQueue.getFirst(); - if(pdu == null) { - authenticator.authError(); - break authLoop; - } - lastType = pdu.getType(); - } - - try { - switch(lastType) { - case SSH2.MSG_USERAUTH_FAILURE: - if(!retry) { - peerMethods = new String(pdu.readString()); - partial = pdu.readBoolean(); - authenticator.peerMethods(peerMethods); - } - retry = false; - - transport.getLog().notice("SSH2UserAuth", - "failure continuation: " + - peerMethods + - " (partial: " + partial + ")"); - - if(currentMethod != null) { - ourMethods = - SSH2ListUtil.removeFirstFromList(ourMethods, - currentMethod); - authenticator.authFailure(currentMethod, partial); - } else { - ourMethods = authenticator.getMethods(); - } - - transport.getLog().notice("SSH2UserAuth", - "our remaining methods: " + - (ourMethods.length() > 0 ? - ourMethods : "")); - - currentMethod = SSH2ListUtil.chooseFromList(ourMethods, - peerMethods); - - if(currentMethod != null) { - transport.getLog().notice("SSH2UserAuth", - "trying method: " + - currentMethod); - authModule = authenticator.getModule(currentMethod); - SSH2TransportPDU modPDU = - authModule.startAuthentication(this); - transport.transmit(modPDU); - } else { - authenticator.noMoreMethods(); - transport.getLog().notice("SSH2UserAuth", - "no more authentication methods, giving up"); - break authLoop; - } - break; - - case SSH2.MSG_USERAUTH_SUCCESS: - transport.getLog().notice("SSH2UserAuth", - "successful authentication with " + - currentMethod); - isAuthenticated = true; - authenticator.authSuccess(currentMethod); - break; - - case SSH2.MSG_USERAUTH_BANNER: - String msg = new String(pdu.readString()); - transport.getLog().warning("SSH2UserAuth", "banner: " + - msg); - authenticator.displayBanner(msg); - break; - - case SSH2.MSG_SERVICE_ACCEPT: - if(transport.incompatibleServiceAccept) { - transport.getLog().notice("SSH2UserAuth", - "server accepted " + - service + - " (draft incompatible)"); - } else { - transport.getLog().notice("SSH2UserAuth", - "server accepted: " + - new String(pdu.readString())); - } - doNoneAuth(); - break; - - 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: - if(authModule != null) { - SSH2TransportPDU modPDU = - authModule.processMethodMessage(this, pdu); - if(modPDU != null) - transport.transmit(modPDU); - } else { - transport.fatalDisconnect(SSH2.DISCONNECT_PROTOCOL_ERROR, - "Received userauth method " + - "packet when no method selected"); - break authLoop; - } - break; - } - } catch (SSH2UserCancelException e) { - String msg = e.getMessage(); - authenticator.moduleCancel(currentMethod, msg); - transport.fatalDisconnect( - SSH2.DISCONNECT_AUTH_CANCELLED_BY_USER, - "User cancel: " + msg); - transport.getLog(). - notice("SSH2UserAuth", - "user canceled authentication: " - + msg); - break authLoop; - } catch (SSH2Exception e) { - transport.getLog().error("SSH2UserAuth", - "authenticateUser", - "error in module '" + - currentMethod + "': " + - e.getMessage()); - authenticator.moduleFailure(currentMethod, e); - partial = false; - retry = true; - lastType = SSH2.MSG_USERAUTH_FAILURE; - } - if(pdu != null) { - pdu.release(); - } - } - - return isAuthenticated; - } - - /** - * Creates a packet of type USERAUTH_REQUEST (as defined in the userauth - * protocol spec.). This is a convenience method which creates the whole - * packet given the method name (i.e. fills in username and service). It is - * typically used by SSH2AuthModule implementors to create the - * packet to return from the method startAuthentication. - * - * @param method the name of the authentication method - * - * @return the complete USERAUTH_REQUEST packet - */ - public SSH2TransportPDU createUserAuthRequest(String method) { - SSH2TransportPDU pdu = - SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_USERAUTH_REQUEST); - pdu.writeString(user); - pdu.writeString(service); - pdu.writeString(method); - return pdu; - } - - /** - * Terminates the authentication process. - */ - public void terminate() { - procQueue.setBlocking(false); - } - - /** - * Checks if the user represented by the SSH2Authenticator we - * process has been authenticated yet. - * - * @return a boolean indicating if the user is authenticated or not - */ - public boolean isAuthenticated() { - return isAuthenticated; - } - - private void doNoneAuth() { - SSH2TransportPDU pdu = createUserAuthRequest("none"); - transport.transmit(pdu); - } - - void processMessage(SSH2TransportPDU pdu) { - procQueue.putLast(pdu); - } - -} - diff --git a/src/main/java/com/mindbright/ssh2/SSH2UserCancelException.java b/src/main/java/com/mindbright/ssh2/SSH2UserCancelException.java deleted file mode 100644 index ea5d820..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2UserCancelException.java +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -public class SSH2UserCancelException extends SSH2Exception { - - public SSH2UserCancelException(String message) { - super(message, null); - } - -} diff --git a/src/main/java/com/mindbright/ssh2/SSH2X11Filter.java b/src/main/java/com/mindbright/ssh2/SSH2X11Filter.java deleted file mode 100644 index 521891c..0000000 --- a/src/main/java/com/mindbright/ssh2/SSH2X11Filter.java +++ /dev/null @@ -1,187 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.ssh2; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.FilterInputStream; -import java.io.FilterOutputStream; -import java.io.IOException; - -public class SSH2X11Filter implements SSH2StreamFilter, SSH2StreamFilterFactory -{ - - protected final static String X11AUTH_PROTO = "MIT-MAGIC-COOKIE-1"; - - class X11Output extends FilterOutputStream { - - byte[] buf; - int idx; - int wantedLen; - int protoLen; - int cookieLen; - boolean readAuth; - - public X11Output(OutputStream toBeFiltered) { - super(toBeFiltered); - this.buf = new byte[1024]; - this.readAuth = false; - this.idx = 0; - this.wantedLen = 12; // header len - } - - public void write(byte b[], int off, int len) throws IOException { - if(!readAuth) { - int n; - - // Read header of authentication packet - // - if(idx < 12) { - n = readMore(b, off, len); - len -= n; - off += n; - if(wantedLen == 0) { - if(buf[0] == 0x42) { - protoLen = - ((buf[6] & 0xff) << 8) | (buf[7] & 0xff); - cookieLen = - ((buf[8] & 0xff) << 8) | (buf[9] & 0xff); - } else if(buf[0] == 0x6c) { - protoLen = - ((buf[7] & 0xff) << 8) | (buf[6] & 0xff); - cookieLen = - ((buf[9] & 0xff) << 8) | (buf[8] & 0xff); - } else { - throw new IOException("Corrupt X11 authentication"); - } - wantedLen = (protoLen + 0x03) & ~0x03; - wantedLen += (cookieLen + 0x03) & ~0x03; - if(wantedLen + idx > buf.length) { - throw new IOException("Corrupt X11 authentication"); - } - if(wantedLen == 0) { - throw - new IOException("No X11 authentication cookie"); - } - } - } - - // Read payload of authentication packet - // - if(len > 0) { - n = readMore(b, off, len); - len -= n; - off += n; - if(wantedLen == 0) { - byte[] fakeCookie = connection.getX11FakeCookie(); - String protoStr = new String(buf, 12, protoLen); - byte[] recCookie = new byte[fakeCookie.length]; - - protoLen = ((protoLen + 0x03) & ~0x03); - - System.arraycopy(buf, 12 + protoLen, - recCookie, 0, fakeCookie.length); - if(!X11AUTH_PROTO.equals(protoStr) || - !compareCookies(fakeCookie, recCookie, - fakeCookie.length)) { - throw new IOException("X11 authentication failed"); - } - byte[] realCookie = connection.getX11RealCookie(); - if(realCookie.length != cookieLen) { - throw new IOException("X11 wrong cookie length"); - } - System.arraycopy(realCookie, 0, buf, 12 + protoLen, - realCookie.length); - readAuth = true; - out.write(buf, 0, idx); - buf = null; - } - } - - if(!readAuth || len == 0) { - return; - } - } - - out.write(b, off, len); - } - - private boolean compareCookies(byte[] src, byte[] dst, int len) { - int i = 0; - for(; i < len; i++) { - if(src[i] != dst[i]) { - break; - } - } - return i == len; - } - - private int readMore(byte[] b, int off, int len) { - if(len > wantedLen) { - System.arraycopy(b, off, buf, idx, wantedLen); - idx += wantedLen; - len = wantedLen; - wantedLen = 0; - } else { - System.arraycopy(b, off, buf, idx, len); - idx += len; - wantedLen -= len; - } - return len; - } - - } - - private static SSH2X11Filter factoryInstance; - - public SSH2X11Filter() { - // - // Factory instance constructor - // - } - - public static synchronized SSH2X11Filter getFilterFactory() { - if(factoryInstance == null) { - factoryInstance = new SSH2X11Filter(); - } - return factoryInstance; - } - - protected SSH2Connection connection; - protected SSH2StreamChannel channel; - protected X11Output x11Out; - - protected SSH2X11Filter(SSH2Connection connection, - SSH2StreamChannel channel) { - this.connection = connection; - this.channel = channel; - } - - public SSH2StreamFilter createFilter(SSH2Connection connection, - SSH2StreamChannel channel) { - return new SSH2X11Filter(connection, channel); - } - - public InputStream getInputFilter(InputStream toBeFiltered) { - return toBeFiltered; - } - - public OutputStream getOutputFilter(OutputStream toBeFiltered) { - this.x11Out = new X11Output(toBeFiltered); - return this.x11Out; - } - -} diff --git a/src/main/java/com/mindbright/ssh2/package.html b/src/main/java/com/mindbright/ssh2/package.html deleted file mode 100644 index 3de29c4..0000000 --- a/src/main/java/com/mindbright/ssh2/package.html +++ /dev/null @@ -1,18 +0,0 @@ - - - -Implements the secure shell version 2 protocol suite. In here is all classes -implementing the different parts of the full ssh2 protocol stack including -filetransfer. The classes SSH2Transport, SSH2UserAuth, -and SSH2Connection are central to the whole implementation, this is -where you want to start looking for how things works. There are two classes -available which makes a good quick start, these are -SSH2SimpleClient and SSH2ConsoleRemote. They provide -the basic functionality for connecting to an ssh2 server and run single commands -and/or an interactive shell. Together with an understanding of the class -SSH2Connection one can utilize all basic functions of the full API. - - - - - diff --git a/src/main/java/com/mindbright/sshcommon/SSHConsoleRemote.java b/src/main/java/com/mindbright/sshcommon/SSHConsoleRemote.java deleted file mode 100644 index 8b7f415..0000000 --- a/src/main/java/com/mindbright/sshcommon/SSHConsoleRemote.java +++ /dev/null @@ -1,28 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.sshcommon; - -import java.io.InputStream; -import java.io.OutputStream; - -public interface SSHConsoleRemote { - public boolean command(String command); - public boolean connect(); - public void close(); - public void changeStdOut(OutputStream out); - public OutputStream getStdIn(); - public InputStream getStdOut(); -} diff --git a/src/main/java/com/mindbright/sshcommon/SSHFileTransfer.java b/src/main/java/com/mindbright/sshcommon/SSHFileTransfer.java deleted file mode 100644 index 44a02e1..0000000 --- a/src/main/java/com/mindbright/sshcommon/SSHFileTransfer.java +++ /dev/null @@ -1,29 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.sshcommon; - -import java.io.IOException; - -public interface SSHFileTransfer { - public void setProgress(SSHFileTransferProgress progress); - public void copyToRemote(String[] localFiles, String remoteFile, - boolean recursive) - throws IOException; - public void copyToLocal(String localFile, String remoteFiles[], - boolean recursive) - throws IOException; - public void abort(); -} diff --git a/src/main/java/com/mindbright/sshcommon/SSHFileTransferProgress.java b/src/main/java/com/mindbright/sshcommon/SSHFileTransferProgress.java deleted file mode 100644 index aa7e3d2..0000000 --- a/src/main/java/com/mindbright/sshcommon/SSHFileTransferProgress.java +++ /dev/null @@ -1,25 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.sshcommon; - -import com.mindbright.util.Progress; - -public interface SSHFileTransferProgress extends Progress { - public void startFile(String file, long size); - public void startDir(String file); - public void endFile(); - public void endDir(); -} diff --git a/src/main/java/com/mindbright/sshcommon/SSHSCP1.java b/src/main/java/com/mindbright/sshcommon/SSHSCP1.java deleted file mode 100644 index eae0e96..0000000 --- a/src/main/java/com/mindbright/sshcommon/SSHSCP1.java +++ /dev/null @@ -1,377 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.sshcommon; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.EOFException; - -public final class SSHSCP1 implements SSHFileTransfer { - - public final static int DEFAULT_COPY_BUFFER_SZ = 16384; - - private SSHConsoleRemote remote; - private OutputStream out; - private InputStream in; - private File cwd; - private boolean verbose; - private SSHFileTransferProgress progress; - private byte[] copyBuf; - - public SSHSCP1(File cwd, SSHConsoleRemote remote, boolean verbose) { - this.remote = remote; - this.cwd = cwd; - this.in = in; - this.out = out; - this.verbose = verbose; - this.copyBuf = new byte[DEFAULT_COPY_BUFFER_SZ]; - } - - public void setProgress(SSHFileTransferProgress progress) { - this.progress = progress; - } - - public void abort() { - remote.close(); - } - - public void copyToRemote(String localFile, String remoteFile, - boolean recursive) - throws IOException - { - File lf = new File(localFile); - - if(!lf.isAbsolute()) - lf = new File(cwd, localFile); - - if(!lf.exists()) { - throw new IOException("File: " + localFile + " does not exist"); - } - if(!lf.isFile() && !lf.isDirectory()) { - throw new IOException("File: " + localFile + - " is not a regular file or directory"); - } - if(lf.isDirectory() && !recursive) { - throw new IOException("File: " + localFile + - " is a directory, use recursive mode"); - } - if(remoteFile == null || remoteFile.equals("")) - remoteFile = "."; - remoteConnect("scp " + (lf.isDirectory() ? "-d " : "") + "-t " + - (recursive ? "-r " : "") + (verbose ? "-v " : "") + - remoteFile); - readResponse("After starting remote scp"); - writeFileToRemote(lf, recursive); - remote.close(); - } - - public void copyToRemote(String[] localFiles, String remoteFile, - boolean recursive) - throws IOException - { - if(remoteFile == null || remoteFile.equals("")) - remoteFile = "."; - if(localFiles.length == 1) { - copyToRemote(localFiles[0], remoteFile, recursive); - } else { - remoteConnect("scp " + "-d -t " + (recursive ? "-r " : "") + - (verbose ? "-v " : "") + remoteFile); - readResponse("After starting remote scp"); - for(int i = 0; i < localFiles.length; i++) { - File lf = new File(localFiles[i]); - if(!lf.isAbsolute()) - lf = new File(cwd, localFiles[i]); - if(!lf.isFile() && !lf.isDirectory()) { - throw new IOException("File: " + lf.getName() + - " is not a regular file or directory"); - } - writeFileToRemote(lf, recursive); - } - remote.close(); - } - } - - public void copyToLocal(String localFile, String remoteFiles[], - boolean recursive) - throws IOException - { - StringBuffer buf = new StringBuffer(); - for(int i = 0; i < remoteFiles.length; i++) { - buf.append("\""); - buf.append(remoteFiles[i]); - buf.append("\" "); - } - String remoteFile = buf.toString(); - remoteFile = remoteFile.trim(); - copyToLocal(localFile, remoteFile, recursive); - } - - public void copyToLocal(String localFile, String remoteFile, - boolean recursive) - throws IOException - { - if(localFile == null || localFile.equals("")) - localFile = "."; - - File lf = new File(localFile); - if(!lf.isAbsolute()) - lf = new File(cwd, localFile); - - if(lf.exists() && !lf.isFile() && !lf.isDirectory()) { - throw new IOException("File: " + localFile + - " is not a regular file or directory"); - } - remoteConnect("scp " + "-f " + (recursive ? "-r " : "") + - (verbose ? "-v " : "") + remoteFile); - readFromRemote(lf); - remote.close(); - } - - private boolean writeDirToRemote(File dir, boolean recursive) - throws IOException - { - if(!recursive) { - writeError("File " + dir.getName() + - " is a directory, use recursive mode"); - return false; - } - writeString("D0755 0 " + dir.getName() + "\n"); - if(progress != null) - progress.startDir(dir.getAbsolutePath()); - readResponse("After sedning dirdata"); - String[] dirList = dir.list(); - for(int i = 0; i < dirList.length; i++) { - File f = new File(dir, dirList[i]); - writeFileToRemote(f, recursive); - } - writeString("E\n"); - if(progress != null) - progress.endDir(); - return true; - } - - private void writeFileToRemote(File file, boolean recursive) - throws IOException - { - if(file.isDirectory()) { - if(!writeDirToRemote(file, recursive)) - return; - } else if(file.isFile()) { - writeString("C0644 " + file.length() + " " + file.getName() + "\n"); - if(progress != null) - progress.startFile(file.getName(), file.length()); - readResponse("After sending filedata"); - FileInputStream fi = new FileInputStream(file); - writeFully(fi, file.length()); - writeByte(0); - if(progress != null) - progress.endFile(); - } else { - throw new IOException("Not ordinary file: " + file.getName()); - } - readResponse("After writing file"); - } - - private void readFromRemote(File file) throws IOException { - String cmd; - String[] cmdParts = new String[3]; - writeByte(0); - while(true) { - try { - cmd = readString(); - } catch (EOFException e) { - return; - } - char cmdChar = cmd.charAt(0); - switch(cmdChar) { - case 'E': - writeByte(0); - return; - case 'T': - throw new IOException("SSHSCP1: (T)ime not supported: " + cmd); - case 'C': - case 'D': - String targetName = file.getAbsolutePath(); - parseCommand(cmd, cmdParts); - if(file.isDirectory()) { - targetName += File.separator + cmdParts[2]; - } - File targetFile = new File(targetName); - if(cmdChar == 'D') { - if(targetFile.exists()) { - if(!targetFile.isDirectory()) { - String msg = "Invalid target " + - targetFile.getName() + ", must be a directory"; - writeError(msg); - throw new IOException(msg); - } - } else { - if(!targetFile.mkdir()) { - String msg = "Could not create directory: " + - targetFile.getName(); - writeError(msg); - throw new IOException(msg); - } - } - if(progress != null) - progress.startDir(targetFile.getAbsolutePath()); - readFromRemote(targetFile); - if(progress != null) - progress.endDir(); - continue; - } - FileOutputStream fo = new FileOutputStream(targetFile); - writeByte(0); - long len = Long.parseLong(cmdParts[1]); - if(progress != null) - progress.startFile(targetFile.getName(), len); - readFully(fo, len); - readResponse("After reading file"); - if(progress != null) - progress.endFile(); - writeByte(0); - break; - default: - writeError("Unexpected cmd: " + cmd); - throw new IOException("Unexpected cmd: " + cmd); - } - } - } - - private void parseCommand(String cmd, String[] cmdParts) throws IOException - { - int l, r; - l = cmd.indexOf(' '); - r = cmd.indexOf(' ', l + 1); - if(l == -1 || r == -1) { - writeError("Syntax error in cmd"); - throw new IOException("Syntax error in cmd"); - } - cmdParts[0] = cmd.substring(1, l); - cmdParts[1] = cmd.substring(l + 1, r); - cmdParts[2] = cmd.substring(r + 1); - } - - private void readResponse(String where) throws IOException { - int r = readByte(); - if(r == 0) { - // All is well, no error - return; - } - if(r == -1) { - throw new EOFException("SSHSCP1: premature EOF"); - } - String errMsg = readString(); - if(r == (byte)'\02') - throw new IOException(errMsg); - throw new IOException("SSHSCP.readResponse, error: " + errMsg); - } - - private void writeError(String reason) throws IOException { - writeByte(1); - writeString(reason); - } - - private int readByte() throws IOException { - return in.read(); - } - - private String readString() throws IOException { - int ch, i = 0; - while(((ch = readByte()) != ((int)'\n')) && ch >= 0) { - copyBuf[i++] = (byte)ch; - } - if(ch == -1) { - throw new EOFException("SSHSCP1: premature EOF"); - } - if(copyBuf[0] == (byte)'\n') - throw new IOException("Unexpected "); - if(copyBuf[0] == (byte)'\02' || copyBuf[0] == (byte)'\01') { - String errMsg = new String(copyBuf, 1, i - 1); - if(copyBuf[0] == (byte)'\02') - throw new IOException(errMsg); - throw new IOException("SSHSCP.readString, error: " + errMsg); - } - return new String(copyBuf, 0, i); - } - - private void readFully(FileOutputStream file, long size) - throws IOException - { - long cnt = 0, n; - try { - while(cnt < size) { - n = (long)in.read(copyBuf, 0, (int) - ((size - cnt) < DEFAULT_COPY_BUFFER_SZ ? - (size - cnt) : DEFAULT_COPY_BUFFER_SZ)); - if(n == -1) { - throw new EOFException("SSHSCP1: premature EOF"); - } - cnt += n; - file.write(copyBuf, 0, (int)n); - if(progress != null) - progress.progress((int)n); - } - } finally { - file.close(); - } - } - - private void writeByte(int b) throws IOException { - out.write(b); - } - - private void writeString(String str) throws IOException { - byte[] buf = str.getBytes(); - out.write(buf); - } - - private void writeFully(FileInputStream file, long size) - throws IOException - { - long cnt = 0, n; - try { - while(cnt < size) { - n = (int)file.read(copyBuf, 0, (int) - ((size - cnt) < DEFAULT_COPY_BUFFER_SZ ? - (size - cnt) : DEFAULT_COPY_BUFFER_SZ)); - if(n == -1) { - throw new EOFException("SSHSCP1: premature EOF"); - } - cnt += n; - out.write(copyBuf, 0, (int)n); - if(progress != null) - progress.progress((int)n); - } - } finally { - file.close(); - } - } - - private void remoteConnect(String command) throws IOException { - if(!remote.command(command)) { - throw new IOException("SSHSCP.remoteConnect, failed to run: " + - command); - } - this.in = remote.getStdOut(); - this.out = remote.getStdIn(); - } - -} diff --git a/src/main/java/com/mindbright/sshcommon/SSHSCPStdoutProgress.java b/src/main/java/com/mindbright/sshcommon/SSHSCPStdoutProgress.java deleted file mode 100644 index 1bb5a5a..0000000 --- a/src/main/java/com/mindbright/sshcommon/SSHSCPStdoutProgress.java +++ /dev/null @@ -1,32 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.sshcommon; - -public class SSHSCPStdoutProgress implements SSHFileTransferProgress { - public void startFile(String file, long size) { - System.out.print("Transfering " + file + " (" + size + " bytes)..."); - } - public void startDir(String file) { - System.out.println("Entering directory " + file); - } - public void endFile() { - System.out.println("done"); - } - public void endDir() { - } - public void progress(int size) { - } -} diff --git a/src/main/java/com/mindbright/terminal/GlobalClipboard.java b/src/main/java/com/mindbright/terminal/GlobalClipboard.java deleted file mode 100644 index 9851c79..0000000 --- a/src/main/java/com/mindbright/terminal/GlobalClipboard.java +++ /dev/null @@ -1,149 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.terminal; - -import java.util.Vector; -import java.util.Enumeration; - -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.Transferable; -import java.awt.datatransfer.StringSelection; - -public class GlobalClipboard implements TerminalClipboardHandler { - - // Singleton instance of GlobalClipboard - // - private static GlobalClipboard globalClipboard = null; - - private Toolkit toolkit; - private Vector menuHandlers; - private boolean selectionAvailable; - private Clipboard jvmClipboard; - - private GlobalClipboard() { - this.toolkit = Toolkit.getDefaultToolkit(); - this.selectionAvailable = false; - this.menuHandlers = new Vector(); - } - - public static synchronized GlobalClipboard getClipboardHandler() { - return getClipboardHandler(null); - } - - public static synchronized GlobalClipboard - getClipboardHandler(TerminalMenuHandler menuHandler) - { - if(globalClipboard == null) { - globalClipboard = new GlobalClipboard(); - } - globalClipboard.addMenuHandler(menuHandler); - return globalClipboard; - } - - public void addMenuHandler(TerminalMenuHandler menuHandler) { - if(menuHandler != null && !menuHandlers.contains(menuHandler)) { - this.menuHandlers.addElement(menuHandler); - } - } - - public void removeMenuHandler(TerminalMenuHandler menuHandler) { - if(menuHandlers.contains(menuHandler)) { - menuHandlers.removeElement(menuHandler); - } - } - - public void setSelection(String selection) { - Clipboard cb = getClipboard(); - if(cb == null) - return; - if(selection == null) - selection = ""; - StringSelection sl = new StringSelection(selection); - cb.setContents(sl, sl); - selectionAvailable(true); - } - - public String getSelection() { - Clipboard cb = getClipboard(); - String sl = null; - - if(cb == null) { - return sl; - } - - Transferable t = cb.getContents(this); - - if(t != null) { - try { - sl = (String) t.getTransferData(DataFlavor.stringFlavor); - } catch (Exception e) { - try { - toolkit.beep(); - } catch (Throwable ee) { - // Could not beep, we are probably an unpriviliged applet - } - } - } else { - try { - toolkit.beep(); - } catch (Throwable e) { - // Could not beep, we are probably an unpriviliged applet - } - } - - return sl; - } - - public void clearSelection() { - selectionAvailable(false); - } - - private void selectionAvailable(boolean val) { - selectionAvailable = val; - Enumeration e = menuHandlers.elements(); - while(e.hasMoreElements()) { - ((TerminalMenuHandler) - e.nextElement()).updateSelection(selectionAvailable); - } - } - - private synchronized Clipboard getClipboard() { - // !!! OUCH - try { - netscape.security.PrivilegeManager.enablePrivilege("UniversalSystemClipboardAccess"); - } catch (netscape.security.ForbiddenTargetException e) { - // !!! - } - Clipboard cb; - if(jvmClipboard == null) { - try { - cb = toolkit.getSystemClipboard(); - } catch (Throwable e) { - // - // If we can't access the system clipboard we use our own - // "global" one. - // - cb = jvmClipboard = new Clipboard("MindTerm-local-clipboard"); - } - } else { - cb = jvmClipboard; - } - return cb; - } - -} diff --git a/src/main/java/com/mindbright/terminal/LineReaderTerminal.java b/src/main/java/com/mindbright/terminal/LineReaderTerminal.java deleted file mode 100644 index 83c8759..0000000 --- a/src/main/java/com/mindbright/terminal/LineReaderTerminal.java +++ /dev/null @@ -1,191 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.terminal; - -public final class LineReaderTerminal implements TerminalInputListener { - - TerminalWin terminal; - StringBuffer readLineStr; - boolean echoStar; - boolean isReadingLine; - - volatile boolean ctrlCPressed; - volatile boolean ctrlDPressed; - - ExternalMessageException extMsg; - - static public class ExternalMessageException extends Exception { - public ExternalMessageException(String msg) { - super(msg); - } - } - - public LineReaderTerminal(TerminalWin terminal) { - this.terminal = terminal; - terminal.addInputListener(this); - } - - public void print(String str) { - if(terminal != null) { - terminal.write(str); - } else { - System.out.print(str); - } - } - - public void println(String str) { - if(terminal != null) { - terminal.write(str + "\n\r"); - } else { - System.out.println(str); - } - } - - public void breakPromptLine(String msg) { - if(isReadingLine) { - synchronized(this) { - extMsg = new ExternalMessageException(msg); - this.notify(); - } - } - } - - public String readLine(String defaultVal) { - synchronized(this) { - if(defaultVal != null) { - readLineStr = new StringBuffer(defaultVal); - terminal.write(defaultVal); - } else { - readLineStr = new StringBuffer(); - } - isReadingLine = true; - try { - this.wait(); - } catch (InterruptedException e) { - /* don't care */ - } - isReadingLine = false; - } - return readLineStr.toString(); - } - - public String promptLine(String prompt, String defaultVal, boolean echoStar) - throws ExternalMessageException - { - String line = null; - if(terminal != null) { - terminal.setAttribute(Terminal.ATTR_BOLD, true); - terminal.write(prompt); - terminal.setAttribute(Terminal.ATTR_BOLD, false); - this.echoStar = echoStar; - line = readLine(defaultVal); - this.echoStar = false; - } /* - else { - BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); - System.out.print(prompt); - line = br.readLine(); - } - */ - if(extMsg != null) { - ExternalMessageException msg = extMsg; - extMsg = null; - throw msg; - } - return line; - } - - public boolean ctrlCPressed() { - boolean pressed = ctrlCPressed; - ctrlCPressed = false; - return pressed; - } - - // TerminalInputListener interface - // - public synchronized void typedChar(char c) { - if(isReadingLine) { - if(c == (char)127 || c == (char)0x08) { - if(readLineStr.length() > 0) { - boolean ctrlChar = false; - if(readLineStr.charAt(readLineStr.length() - 1) < ' ') { - ctrlChar = true; - } - readLineStr.setLength(readLineStr.length() - 1); - terminal.write((char)8); - if(ctrlChar) terminal.write((char)8); - terminal.write(' '); - if(ctrlChar) terminal.write(' '); - terminal.write((char)8); - if(ctrlChar) terminal.write((char)8); - } else - terminal.doBell(); - } else if(c == '\r') { - this.notify(); - terminal.write("\n\r"); - } else { - ctrlCPressed = false; - ctrlDPressed = false; - readLineStr.append(c); - if(echoStar) - terminal.write('*'); - else - terminal.write(c); - } - } else { - if(c == (char)0x03) { - ctrlCPressed = true; - } else if(c == (char)0x04) { - ctrlDPressed = true; - } - } - } - - public void sendBytes(byte[] b) { - for(int i = 0; i < b.length; i++) - typedChar((char)b[i]); - } - - public void signalWindowChanged(int rows, int cols, int vpixels, int hpixels) { - } - - /* DEBUG/TEST - public static void main(String[] argv) { - java.awt.Frame frame = new java.awt.Frame(); - TerminalWin terminal = new TerminalWin(frame, new TerminalXTerm()); - LineReaderTerminal linereader = new LineReaderTerminal(terminal); - - frame.setLayout(new java.awt.BorderLayout()); - frame.add(terminal.getPanelWithScrollbar(), - java.awt.BorderLayout.CENTER); - - frame.pack(); - frame.show(); - - linereader.println("Now entering lines..."); - String line; - try { - while(true) { - line = linereader.promptLine("prompt> ", "", false); - System.out.println("line: " + line); - } - } catch (Exception e) { - System.out.println("Error: " + e); - } - } - */ - -} diff --git a/src/main/java/com/mindbright/terminal/Terminal.java b/src/main/java/com/mindbright/terminal/Terminal.java deleted file mode 100644 index d7d8479..0000000 --- a/src/main/java/com/mindbright/terminal/Terminal.java +++ /dev/null @@ -1,137 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.terminal; - -import java.io.IOException; -import java.util.Properties; -import java.util.NoSuchElementException; - -public interface Terminal { - - public final static int ATTR_BOLD = 0x0001; - public final static int ATTR_LOWINTENSITY = 0x0002; - public final static int ATTR_UNDERLINE = 0x0004; - public final static int ATTR_BLINKING = 0x0008; - public final static int ATTR_INVERSE = 0x0010; - public final static int ATTR_INVISIBLE = 0x0020; - public final static int ATTR_FGCOLOR = 0x0040; - public final static int ATTR_BGCOLOR = 0x0080; - - final static int OPT_REV_VIDEO = 0; - final static int OPT_AUTO_WRAP = 1; - final static int OPT_REV_WRAP = 2; - final static int OPT_INSERTMODE = 3; - final static int OPT_AUTO_LF = 4; - final static int OPT_SCROLL_SK = 5; - final static int OPT_SCROLL_SI = 6; - final static int OPT_VIS_CURSOR = 7; - final static int OPT_LOCAL_ECHO = 8; - final static int OPT_VIS_BELL = 9; - final static int OPT_MAP_CTRLSP = 10; - final static int OPT_DECCOLM = 11; - final static int OPT_DEC132COLS = 12; - final static int OPT_LOCAL_PGKEYS = 13; - final static int OPT_COPY_CRNL = 14; - final static int OPT_ASCII_LDC = 15; - final static int OPT_COPY_SEL = 16; - - final static int OPT_LAST_OPT = 17; - final static int OPT_LAST_MENU = 13; - - public String terminalType(); - public int rows(); - public int cols(); - public int vpixels(); - public int hpixels(); - - public void write(char c); - public void write(char[] c, int off, int len); - public void write(String str); - public void writeLineDrawChar(char c); - - public void addInputListener(TerminalInputListener listener); - public void addOutputListener(TerminalOutputListener listener); - public void removeOutputListener(TerminalOutputListener listener); - - public void sendBytes(byte[] b); - - public void doBell(); - public void doBS(); - public void doTab(); - public void doTabs(int n); - public void doBackTabs(int n); - public void setTab(int col); - public void clearTab(int col); - public void resetTabs(); - public void clearAllTabs(); - public void doCR(); - public void doLF(); - - public void resetInterpreter(); - public void resetWindow(); - public void setWindow(int top, int bottom); - public void setWindow(int top, int right, int bottom, int left); - public int getWindowTop(); - public int getWindowBottom(); - public int getWindowLeft(); - public int getWindowRight(); - - public int getCursorV(); - public int getCursorH(); - - public void cursorSetPos(int v, int h, boolean relative); - public void cursorUp(int n); - public void cursorDown(int n); - public void cursorForward(int n); - public void cursorBackward(int n); - public void cursorIndex(int n); - public void cursorIndexRev(int n); - - public void cursorSave(); - public void cursorRestore(); - - public void scrollUp(int n); - public void scrollDown(int n); - - public void clearBelow(); - public void clearAbove(); - public void clearScreen(); - public void clearRight(); - public void clearLeft(); - public void clearLine(); - - public void eraseChars(int n); - public void insertChars(int n); - public void insertLines(int n); - public void deleteChars(int n); - public void deleteLines(int n); - - public void setOption(int opt, boolean val); - public boolean getOption(int opt); - - public void setAttribute(int attr, boolean val); - public boolean getAttribute(int attr); - public void setForegroundColor(int c); - public void setBackgroundColor(int c); - public void clearAllAttributes(); - - public void setProperties(Properties newProps, boolean merge) throws IllegalArgumentException, - NoSuchElementException; - public Properties getProperties(); - public void resetToDefaults(); - public boolean getPropsChanged(); - public void setPropsChanged(boolean value); -} diff --git a/src/main/java/com/mindbright/terminal/TerminalCapture.java b/src/main/java/com/mindbright/terminal/TerminalCapture.java deleted file mode 100644 index 18dedc7..0000000 --- a/src/main/java/com/mindbright/terminal/TerminalCapture.java +++ /dev/null @@ -1,61 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.terminal; - -import java.io.OutputStream; -import java.io.IOException; - -public final class TerminalCapture implements TerminalOutputListener { - - private OutputStream captureTarget; - private Terminal terminal; - - public TerminalCapture(OutputStream captureTarget) { - this.captureTarget = captureTarget; - } - - public void startCapture(Terminal terminal) { - this.terminal = terminal; - terminal.addOutputListener(this); - } - - public void endCapture() { - terminal.removeOutputListener(this); - } - - public OutputStream getTarget() { - return captureTarget; - } - - public void write(char c) { - write(new byte[] { (byte)c }, 0, 1); - } - - public void write(char[] c, int off, int len) { - String str = new String(c, off, len); - byte[] bytes = str.getBytes(); - write(bytes, 0, bytes.length); - } - - public void write(byte[] c, int off, int len) { - try { - captureTarget.write(c, off, len); - } catch (IOException e) { - // !!! TODO report this to someone... - } - } - -} diff --git a/src/main/java/com/mindbright/terminal/TerminalClipboardHandler.java b/src/main/java/com/mindbright/terminal/TerminalClipboardHandler.java deleted file mode 100644 index 7832aac..0000000 --- a/src/main/java/com/mindbright/terminal/TerminalClipboardHandler.java +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.terminal; - -public interface TerminalClipboardHandler { - public void setSelection(String selection); - public String getSelection(); - public void clearSelection(); -} diff --git a/src/main/java/com/mindbright/terminal/TerminalDefProps.java b/src/main/java/com/mindbright/terminal/TerminalDefProps.java deleted file mode 100644 index 58af9e0..0000000 --- a/src/main/java/com/mindbright/terminal/TerminalDefProps.java +++ /dev/null @@ -1,180 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.terminal; - -import java.util.Hashtable; -import java.util.Properties; -import java.util.Enumeration; -import java.awt.Toolkit; - -// !!! OUCH KLUDGE - -public abstract class TerminalDefProps { - - // !!! OUCH (we don't want to drag in TerminalXTerm... - // - public final static String[] terminalTypes = { - "xterm", "linux", "scoansi", "att6386", "sun", "aixterm", - "vt220", "vt100", "ansi", "vt52", - - "xterm-color", "linux-lat", "", "at386", "", "", "vt320", "vt102" - }; - public static String listAvailableTerminalTypes() { - int i; - String list = " "; - for(i = 0; i < terminalTypes.length; i++) - list += terminalTypes[i] + " "; - return list; - } - - static public final int PROP_NAME = 0; - static public final int PROP_VALUE = 1; - static public Properties defaultProperties = new Properties(); - static public Hashtable oldPropNames = new Hashtable(); - static public final String[][] defaultPropDesc = { - // Options - { "rev-video", "false" }, - { "autowrap", "true" }, - { "rev-autowrap", "false" }, - { "insert-mode", "false" }, - { "auto-linefeed", "false" }, - { "repos-input", "true" }, - { "repos-output", "true" }, - { "visible-cursor", "true" }, - { "local-echo", "false" }, - { "visual-bell", "false" }, - { "map-ctrl-space", "true" }, - { "80x132-toggle", "false" }, - { "80x132-enable", "true" }, - - { "local-pgkeys", "false" }, - { "copy-crnl", "false" }, - { "ascii-line", "false" }, - { "copy-select", "true" }, - - // Settings - { "font-name", defaultFont() }, - { "font-size", "12" }, - { "geometry", "80x24" }, - { "term-type", terminalTypes[0] }, - { "save-lines", "512" }, - { "scrollbar", "right" }, - { "bg-color", "white" }, - { "fg-color", "black" }, - { "cursor-color", "i_blue" }, - { "resize-gravity", "bottom" }, - { "backspace-send", "DEL" }, - { "delete-send", "DEL" }, - { "select-delim", "\" \"" }, - { "paste-button", "middle" }, - }; - static { - for(int i = 0; i < defaultPropDesc.length; i++) - defaultProperties.put(defaultPropDesc[i][PROP_NAME], defaultPropDesc[i][PROP_VALUE]); - - oldPropNames.put("rv", "rev-video"); - oldPropNames.put("aw", "autowrap"); - oldPropNames.put("rw", "rev-autowrap"); - oldPropNames.put("im", "insert-mode"); - oldPropNames.put("al", "auto-linefeed"); - oldPropNames.put("sk", "repos-input"); - oldPropNames.put("si", "repos-output"); - oldPropNames.put("vi", "visible-cursor"); - oldPropNames.put("le", "local-echo"); - oldPropNames.put("vb", "visual-bell"); - oldPropNames.put("ct", "map-ctrl-space"); - oldPropNames.put("dc", "80x132-toggle"); - oldPropNames.put("da", "80x132-enable"); - oldPropNames.put("lp", "local-pgkeys"); - oldPropNames.put("sc", "copy-crnl"); - oldPropNames.put("ad", "ascii-line"); - oldPropNames.put("cs", "copy-select"); - oldPropNames.put("fn", "font-name"); - oldPropNames.put("fs", "font-size"); - oldPropNames.put("gm", "geometry"); - oldPropNames.put("te", "term-type"); - oldPropNames.put("sl", "save-lines"); - oldPropNames.put("sb", "scrollbar"); - oldPropNames.put("bg", "bg-color"); - oldPropNames.put("fg", "fg-color"); - oldPropNames.put("cc", "cursor-color"); - oldPropNames.put("rg", "resize-gravity"); - oldPropNames.put("bs", "backspace-send"); - oldPropNames.put("de", "delete-send"); - oldPropNames.put("sd", "select-delim"); - oldPropNames.put("pb", "paste-button"); - } - - public static String backwardCompatProp(String key) { - String newName = (String)oldPropNames.get(key); - if(newName != null) { - key = newName; - } - return key; - } - - public static void setAsDefault(Properties props) { - Enumeration enum = props.keys(); - while(enum.hasMoreElements()) { - String name = (String)enum.nextElement(); - String value = props.getProperty(name); - name = backwardCompatProp(name); - defaultProperties.put(name, value); - } - } - - public static String[] systemFonts; - public static String fontList() { - if(systemFonts == null) - systemFonts = Toolkit.getDefaultToolkit().getFontList(); - String list = ""; - for(int i = 0; i < systemFonts.length; i++) { - list += systemFonts[i]; - if(i < systemFonts.length - 1) - list += ", "; - } - return list; - } - - public static String defaultFont() { - if(fontExists("monospaced")) - return "Monospaced"; - if(fontExists("courier")) - return "Courier"; - if(fontExists("dialoginput")) - return "DialogInput"; - return systemFonts[0]; - } - - public static boolean fontExists(String font) { - int i; - if(systemFonts == null) - systemFonts = Toolkit.getDefaultToolkit().getFontList(); - for(i = 0; i < systemFonts.length; i++) { - if(systemFonts[i].equalsIgnoreCase(font)) - break; - } - if(i == systemFonts.length) - return false; - return true; - } - - public static boolean isProperty(String key) { - key = backwardCompatProp(key); - return defaultProperties.containsKey(key); - } -} - diff --git a/src/main/java/com/mindbright/terminal/TerminalDumb.java b/src/main/java/com/mindbright/terminal/TerminalDumb.java deleted file mode 100644 index 5cc9b85..0000000 --- a/src/main/java/com/mindbright/terminal/TerminalDumb.java +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.terminal; - -public final class TerminalDumb extends TerminalInterpreter { - - public String terminalType() { - return "DUMB"; - } - - public int interpretChar(char c) { - switch(c) { - case 7: // BELL - term.doBell(); - break; - case 8: // BS/CTRLH - term.doBS(); - break; - case '\t': - term.doTab(); - break; - case '\r': - term.doLF(); - break; - case '\n': - term.doCR(); - break; - default: - return (int)c; - } - return IGNORE; - } - -} diff --git a/src/main/java/com/mindbright/terminal/TerminalInputAdapter.java b/src/main/java/com/mindbright/terminal/TerminalInputAdapter.java deleted file mode 100644 index af0232c..0000000 --- a/src/main/java/com/mindbright/terminal/TerminalInputAdapter.java +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.terminal; - -public class TerminalInputAdapter implements TerminalInputListener { - - public void typedChar(char c) { - } - - public void sendBytes(byte[] b) { - } - - public void signalWindowChanged(int rows, int cols, - int vpixels, int hpixels) { - } - -} diff --git a/src/main/java/com/mindbright/terminal/TerminalInputListener.java b/src/main/java/com/mindbright/terminal/TerminalInputListener.java deleted file mode 100644 index e8b4dbf..0000000 --- a/src/main/java/com/mindbright/terminal/TerminalInputListener.java +++ /dev/null @@ -1,23 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.terminal; - -public interface TerminalInputListener { - public void typedChar(char c); - public void sendBytes(byte[] b); - public void signalWindowChanged(int rows, int cols, - int vpixels, int hpixels); -} diff --git a/src/main/java/com/mindbright/terminal/TerminalInterpreter.java b/src/main/java/com/mindbright/terminal/TerminalInterpreter.java deleted file mode 100644 index 242da01..0000000 --- a/src/main/java/com/mindbright/terminal/TerminalInterpreter.java +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.terminal; - -public abstract class TerminalInterpreter { - - protected Terminal term; - - public final static int IGNORE = -1; - - abstract public String terminalType(); - abstract public int interpretChar(char c); - - public void vtReset() { - } - - public void keyHandler(int virtualKey, int gMode) { - } - - public void mouseHandler(int x, int y, boolean press, int modifiers) { - } - - public final void setTerminal(Terminal term) { - this.term = term; - } - -} diff --git a/src/main/java/com/mindbright/terminal/TerminalMenuHandler.java b/src/main/java/com/mindbright/terminal/TerminalMenuHandler.java deleted file mode 100644 index da38e1d..0000000 --- a/src/main/java/com/mindbright/terminal/TerminalMenuHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.terminal; - -public class TerminalMenuHandler { - public void setTerminalWin(TerminalWin term) { - } - public void setTerminalMenuListener(TerminalMenuListener listener) { - } - public void updateSelection(boolean selectionAvailable) { - } - public void update() { - } - public void setEnabledOpt(int opt, boolean val) { - } - public void setStateOpt(int opt, boolean val) { - } -} diff --git a/src/main/java/com/mindbright/terminal/TerminalMenuHandlerFull.java b/src/main/java/com/mindbright/terminal/TerminalMenuHandlerFull.java deleted file mode 100644 index b3511a1..0000000 --- a/src/main/java/com/mindbright/terminal/TerminalMenuHandlerFull.java +++ /dev/null @@ -1,1042 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.terminal; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; - -import java.awt.*; -import java.awt.event.*; - -import com.mindbright.gui.AWTConvenience; - -public final class TerminalMenuHandlerFull extends TerminalMenuHandler - implements ActionListener, ItemListener -{ - protected final static int ACT_SETTINGS = 0; - protected final static int ACT_COLORS = 1; - protected final static int ACT_MISC = 2; - protected final static int ACT_FIND_CANCEL = 3; - protected final static int ACT_FIND = 4; - - private class Actions implements ActionListener, ItemListener { - private int action; - - public Actions(int action) { - this.action = action; - } - - public void actionPerformed(ActionEvent e) { - switch(action) { - case ACT_SETTINGS: - try { - term.setProperty("te", te[choiceTE.getSelectedIndex()]); - term.setProperty("fn", fn[choiceFN.getSelectedIndex()]); - term.setProperty("fs", textFS.getText()); - term.setProperty("sb", sb[choiceSB.getSelectedIndex()]); - term.setProperty("sl", textSL.getText()); - term.setProperty("gm", textCols.getText() + "x" + textRows.getText()); - - settingsDialog.setVisible(false); - } catch (Exception ee) { - lblAlert.setText(ee.getMessage()); - } - break; - case ACT_COLORS: - try { - term.setProperty("fg", getSelectedColor(choiceFG, textFG)); - term.setProperty("bg", getSelectedColor(choiceBG, textBG)); - term.setProperty("cc", getSelectedColor(choiceCC, textCC)); - colorsDialog.setVisible(false); - } catch (Exception ee) { - lblAlertC.setText(ee.getMessage()); - } - break; - case ACT_MISC: - try { - term.setProperty("pb", pb[choicePB.getSelectedIndex()]); - term.setProperty("rg", rg[choiceRG.getSelectedIndex()]); - term.setProperty("sd", textSD.getText()); - if(cbBS.getState()) - term.setProperty("bs", "DEL"); - else - term.setProperty("bs", "BS"); - if(cbDEL.getState()) - term.setProperty("de", "BS"); - else - term.setProperty("de", "DEL"); - - term.setProperty("lp", String.valueOf(cbLocPG.getState())); - term.setProperty("sc", String.valueOf(cbCpWinCR.getState())); - term.setProperty("cs", String.valueOf(cbCpOnSel.getState())); - term.setProperty("ad", String.valueOf(cbAsciiLD.getState())); - - settingsDialog2.setVisible(false); - } catch (Exception ee) { - // !!! REMOVE - // Can't happen... - ee.printStackTrace(); - System.out.println("Fatal error in dialog: " + ee); - } - break; - case ACT_FIND_CANCEL: - findDialog.setVisible(false); - if(findLen > 0) { - term.clearSelection(curFindRow, curFindCol, curFindRow, curFindCol + findLen - 1); - } - curFindRow = 0; - curFindCol = 0; - findLen = 0; - break; - case ACT_FIND: - String txt = findText.getText(); - if(txt != null && txt.length() > 0) { - doFind(); - } - break; - } - } - - public void itemStateChanged(ItemEvent e) { - updateColors(); - } - - } - - TerminalWin term; - Menu fileMenu; - Menu editMenu; - Menu optionsMenu; - String titleName; - - Object[][] menuItems; - - TerminalMenuListener listener; - - final static String[] settingsMenu = { "Terminal Settings", - "Emulation", "Resize gravity", "Font", - "Savelines", "Scrollbar", "Colors", - "Backspace" - }; - - final static int MENU_FILE = 0; - final static int MENU_EDIT = 1; - final static int MENU_OPTIONS = 2; - - final static int M_FILE_CAPTURE = 1; - final static int M_FILE_SEND = 2; - final static int M_FILE_CLOSE = 4; - - final static int M_EDIT_COPY = 1; - final static int M_EDIT_PASTE = 2; - final static int M_EDIT_CPPASTE = 3; - final static int M_EDIT_SELALL = 4; - final static int M_EDIT_FIND = 5; - final static int M_EDIT_CLS = 7; - final static int M_EDIT_CLEARSB = 8; - final static int M_EDIT_VTRESET = 9; - - final static String[][] menuTexts = { - { "File", - "_Capture To File...", "Send ASCII File...", null, "Close" - }, - { "Edit", - "Copy Ctrl+Ins", "Paste Shift+Ins", "Copy & Paste", "Select All", - "Find...", null, - "Clear Screen", "Clear Scrollback", "VT Reset" - }, - { "VT Options", - "_Reverse Video", "_Auto Wraparound", "_Reverse Wraparound", - "_Insert mode", "_Auto Linefeed", - "_Scroll to Bottom On Key Press", - "_Scroll to Bottom On Tty Output", - "_Visible Cursor", "_Local Echo", - "_Visual Bell", "_Map + To ^@ ()", - "_Toggle 80/132 Columns", "_Enable 80/132 Switching", - } - }; - - final static int NO_SHORTCUT = -1; - final static int[][] menuShortCuts = { - { NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT, KeyEvent.VK_E }, - - { NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT, KeyEvent.VK_A, - KeyEvent.VK_F, NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT }, - - { NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT, - NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT, - NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT, - NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT, NO_SHORTCUT }, - }; - - // !!! OUCH - public TerminalMenuHandlerFull() { - this("MindTerm"); - } - - public TerminalMenuHandlerFull(String titleName) { - this.titleName = titleName; - } - - public void setTerminalWin(TerminalWin term) { - this.term = term; - } - - public void setTerminalMenuListener(TerminalMenuListener listener) { - this.listener = listener; - } - - public void updateSelection(boolean selectionAvailable) { - ((MenuItem)menuItems[MENU_EDIT][M_EDIT_COPY]).setEnabled( - selectionAvailable); - ((MenuItem)menuItems[MENU_EDIT][M_EDIT_CPPASTE]).setEnabled( - selectionAvailable); - } - - public void update() { - if(listener != null) { - listener.update(); - } - } - - - Dialog settingsDialog; - Choice choiceTE, choiceFN, choiceSB; - TextField textFS, textRows, textCols, textInitPos; - Label lblAlert; - final static String[] sb = { "left", "right", "none" }; - final static String[] te = TerminalXTerm.getTerminalTypes(); - final static String[] fn = Toolkit.getDefaultToolkit().getFontList(); - public final void termSettingsDialog() { - if(settingsDialog == null) { - settingsDialog = new Dialog(term.ownerFrame, settingsMenu[0], true); - - ItemListener ilC; - Label lbl; - GridBagLayout grid = new GridBagLayout(); - GridBagConstraints gridc = new GridBagConstraints(); - settingsDialog.setLayout(grid); - - gridc.insets = new Insets(4, 4, 4, 4); - gridc.fill = GridBagConstraints.NONE; - gridc.anchor = GridBagConstraints.WEST; - - gridc.gridy = 0; - gridc.gridwidth = 6; - lbl = new Label("Terminal type:"); - grid.setConstraints(lbl, gridc); - settingsDialog.add(lbl); - choiceTE = AWTConvenience.newChoice(te); - grid.setConstraints(choiceTE, gridc); - settingsDialog.add(choiceTE); - - gridc.gridy = 1; - gridc.gridwidth = 4; - lbl = new Label("Columns:"); - grid.setConstraints(lbl, gridc); - settingsDialog.add(lbl); - - gridc.gridwidth = 2; - textCols = new TextField("", 3); - grid.setConstraints(textCols, gridc); - settingsDialog.add(textCols); - - lbl = new Label("Rows:"); - grid.setConstraints(lbl, gridc); - settingsDialog.add(lbl); - - textRows = new TextField("", 3); - grid.setConstraints(textRows, gridc); - settingsDialog.add(textRows); - - gridc.gridy = 2; - gridc.gridwidth = 2; - lbl = new Label("Font:"); - grid.setConstraints(lbl, gridc); - settingsDialog.add(lbl); - - gridc.gridwidth = 6; - choiceFN = AWTConvenience.newChoice(fn); - grid.setConstraints(choiceFN, gridc); - settingsDialog.add(choiceFN); - - gridc.gridwidth = 2; - textFS = new TextField("", 3); - grid.setConstraints(textFS, gridc); - settingsDialog.add(textFS); - - gridc.gridy = 3; - gridc.gridwidth = 6; - lbl = new Label("Scrollback buffer:"); - grid.setConstraints(lbl, gridc); - settingsDialog.add(lbl); - textSL = new TextField("", 4); - grid.setConstraints(textSL, gridc); - settingsDialog.add(textSL); - - gridc.gridy = 4; - lbl = new Label("Scrollbar position:"); - grid.setConstraints(lbl, gridc); - settingsDialog.add(lbl); - choiceSB = AWTConvenience.newChoice(sb); - grid.setConstraints(choiceSB, gridc); - settingsDialog.add(choiceSB); - - lblAlert = new Label("", Label.CENTER); - gridc.insets = new Insets(0, 0, 0, 0); - gridc.gridy = 5; - gridc.fill = GridBagConstraints.HORIZONTAL; - gridc.gridwidth = GridBagConstraints.REMAINDER; - gridc.anchor = GridBagConstraints.CENTER; - grid.setConstraints(lblAlert, gridc); - settingsDialog.add(lblAlert); - - Panel bp = new Panel(new FlowLayout()); - - Button b; - bp.add(b = new Button("OK")); - b.addActionListener(new Actions(ACT_SETTINGS)); - bp.add(b = new Button("Cancel")); - b.addActionListener(new AWTConvenience.CloseAction(settingsDialog)); - - gridc.gridy = 6; - grid.setConstraints(bp, gridc); - settingsDialog.add(bp); - - settingsDialog.addWindowListener(new AWTConvenience.CloseAdapter(b)); - - AWTConvenience.setBackgroundOfChildren(settingsDialog); - - settingsDialog.setResizable(true); - settingsDialog.pack(); - } - - choiceTE.select(term.getProperty("te")); - choiceFN.select(term.getProperty("fn")); - textFS.setText(term.getProperty("fs")); - textCols.setText(String.valueOf(term.cols())); - textRows.setText(String.valueOf(term.rows())); - choiceSB.select(term.getProperty("sb")); - textSL.setText(term.getProperty("sl")); - - lblAlert.setText(""); - AWTConvenience.placeDialog(settingsDialog); - - choiceTE.requestFocus(); - settingsDialog.setVisible(true); - } - - TextField textFG, textBG, textCC; - Choice choiceFG, choiceBG, choiceCC; - Dialog colorsDialog; - Label lblAlertC; - public final void termColorsDialog() { - if(colorsDialog == null) { - colorsDialog = new Dialog(term.ownerFrame, "Terminal Colors", true); - - ItemListener ilC; - Label lbl; - GridBagLayout grid = new GridBagLayout(); - GridBagConstraints gridc = new GridBagConstraints(); - colorsDialog.setLayout(grid); - - gridc.insets = new Insets(4, 4, 4, 4); - gridc.fill = GridBagConstraints.NONE; - gridc.anchor = GridBagConstraints.WEST; - - gridc.gridy = 0; - gridc.gridwidth = 10; - lbl = new Label("Foreground color:"); - grid.setConstraints(lbl, gridc); - colorsDialog.add(lbl); - - gridc.gridy = 1; - gridc.gridwidth = 6; - choiceFG = new Choice(); - grid.setConstraints(choiceFG, gridc); - colorsDialog.add(choiceFG); - choiceFG.addItemListener(ilC = new Actions(-1)); - - textFG = new TextField("", 10); - grid.setConstraints(textFG, gridc); - colorsDialog.add(textFG); - - gridc.gridy = 2; - lbl = new Label("Background color:"); - grid.setConstraints(lbl, gridc); - colorsDialog.add(lbl); - - gridc.gridy = 3; - choiceBG = new Choice(); - grid.setConstraints(choiceBG, gridc); - colorsDialog.add(choiceBG); - choiceBG.addItemListener(ilC); - - textBG = new TextField("", 10); - grid.setConstraints(textBG, gridc); - colorsDialog.add(textBG); - - gridc.gridy = 4; - lbl = new Label("Cursor color:"); - grid.setConstraints(lbl, gridc); - colorsDialog.add(lbl); - - gridc.gridy = 5; - choiceCC = new Choice(); - grid.setConstraints(choiceCC, gridc); - colorsDialog.add(choiceCC); - choiceCC.addItemListener(ilC); - - textCC = new TextField("", 10); - grid.setConstraints(textCC, gridc); - colorsDialog.add(textCC); - - lblAlertC = new Label("", Label.CENTER); - gridc.insets = new Insets(0, 0, 0, 0); - gridc.gridy = 6; - gridc.fill = GridBagConstraints.HORIZONTAL; - gridc.gridwidth = GridBagConstraints.REMAINDER; - gridc.anchor = GridBagConstraints.CENTER; - grid.setConstraints(lblAlertC, gridc); - colorsDialog.add(lblAlertC); - - Panel bp = new Panel(new FlowLayout()); - - Button b; - bp.add(b = new Button("OK")); - b.addActionListener(new Actions(ACT_COLORS)); - bp.add(b = new Button("Cancel")); - b.addActionListener(new AWTConvenience.CloseAction(colorsDialog)); - - gridc.gridy = 7; - grid.setConstraints(bp, gridc); - colorsDialog.add(bp); - - fillChoices(); - - colorsDialog.addWindowListener(new AWTConvenience.CloseAdapter(b)); - - AWTConvenience.setBackgroundOfChildren(colorsDialog); - - colorsDialog.setResizable(true); - colorsDialog.pack(); - } - - initColorSelect(choiceFG, textFG, term.getProperty("fg")); - initColorSelect(choiceBG, textBG, term.getProperty("bg")); - initColorSelect(choiceCC, textCC, term.getProperty("cc")); - - updateColors(); - - lblAlertC.setText(""); - AWTConvenience.placeDialog(colorsDialog); - - choiceFG.requestFocus(); - colorsDialog.setVisible(true); - } - - void initColorSelect(Choice c, TextField t, String colStr) { - if(Character.isDigit(colStr.charAt(0))) { - c.select("custom rgb"); - t.setText(colStr); - } else { - t.setText(""); - t.setEnabled(false); - c.select(colStr); - } - } - - void checkColorSelect(Choice c, TextField t) { - int cs = c.getSelectedIndex(); - - if(cs == 0) { - boolean en = t.isEnabled(); - if(!en) { - t.setEditable(true); - t.setEnabled(true); - t.setBackground(SystemColor.text); - t.requestFocus(); - } - } else { - t.setText(""); - t.setEditable(false); - t.setEnabled(false); - // on the Mac, Choices can't get keyboard focus - // so we may need to move focus away from the TextField - t.setBackground(term.termColors[cs - 1]); - } - } - - void updateColors() { - checkColorSelect(choiceFG, textFG); - checkColorSelect(choiceBG, textBG); - checkColorSelect(choiceCC, textCC); - } - - String getSelectedColor(Choice c, TextField t) { - String colStr; - if(c.getSelectedIndex() == 0) - colStr = t.getText(); - else - colStr = c.getSelectedItem(); - return colStr; - } - - void fillChoices() { - int i; - choiceBG.add("custom rgb"); - choiceFG.add("custom rgb"); - choiceCC.add("custom rgb"); - for(i = 0; i < term.termColorNames.length; i++) { - choiceBG.add(term.termColorNames[i]); - choiceFG.add(term.termColorNames[i]); - choiceCC.add(term.termColorNames[i]); - } - } - - Dialog settingsDialog2; - Choice choiceRG, choicePB; - Checkbox cbDEL, cbBS, cbCpOnSel, cbCpWinCR, cbAsciiLD, cbLocPG; - TextField textSL, textSD; - final static String[] rg = { "bottom", "top" }; - final static String[] pb = { "middle", "right", "shift+left" }; - public final void termSettingsDialog2() { - if(settingsDialog2 == null) { - int i; - settingsDialog2 = new Dialog(term.ownerFrame, "Terminal Misc. Settings", true); - - Label lbl; - GridBagLayout grid = new GridBagLayout(); - GridBagConstraints gridc = new GridBagConstraints(); - settingsDialog2.setLayout(grid); - - gridc.insets = new Insets(4, 4, 0, 0); - gridc.fill = GridBagConstraints.NONE; - gridc.anchor = GridBagConstraints.WEST; - gridc.gridwidth = 4; - - gridc.gridy = 0; - gridc.gridwidth = 4; - lbl = new Label("Paste button:"); - grid.setConstraints(lbl, gridc); - settingsDialog2.add(lbl); - choicePB = AWTConvenience.newChoice(pb); - grid.setConstraints(choicePB, gridc); - settingsDialog2.add(choicePB); - - gridc.gridy = 1; - lbl = new Label("Select delim.:"); - grid.setConstraints(lbl, gridc); - settingsDialog2.add(lbl); - textSD = new TextField("", 4); - grid.setConstraints(textSD, gridc); - settingsDialog2.add(textSD); - - gridc.gridy = 2; - gridc.gridwidth = 8; - gridc.insets = new Insets(4, 16, 0, 0); - cbCpWinCR = new Checkbox("Copy line ends"); - grid.setConstraints(cbCpWinCR, gridc); - settingsDialog2.add(cbCpWinCR); - - gridc.gridy = 3; - cbCpOnSel = new Checkbox("Copy on select"); - grid.setConstraints(cbCpOnSel, gridc); - settingsDialog2.add(cbCpOnSel); - - gridc.gridy = 4; - gridc.gridwidth = 4; - gridc.insets = new Insets(4, 4, 0, 0); - lbl = new Label("Resize gravity:"); - grid.setConstraints(lbl, gridc); - settingsDialog2.add(lbl); - choiceRG = AWTConvenience.newChoice(rg); - grid.setConstraints(choiceRG, gridc); - settingsDialog2.add(choiceRG); - - gridc.gridy = 5; - gridc.gridwidth = 8; - gridc.insets = new Insets(4, 16, 0, 0); - cbBS = new Checkbox("Backspace sends Delete"); - grid.setConstraints(cbBS, gridc); - settingsDialog2.add(cbBS); - - gridc.gridy = 6; - cbDEL = new Checkbox("Delete sends Backspace"); - grid.setConstraints(cbDEL, gridc); - settingsDialog2.add(cbDEL); - - gridc.gridy = 7; - cbLocPG = new Checkbox("Local PgUp/PgDn"); - grid.setConstraints(cbLocPG, gridc); - settingsDialog2.add(cbLocPG); - - gridc.gridy = 8; - cbAsciiLD = new Checkbox("Use ASCII for line draw"); - grid.setConstraints(cbAsciiLD, gridc); - settingsDialog2.add(cbAsciiLD); - - - Panel bp = new Panel(new FlowLayout()); - - Button b; - bp.add(b = new Button("OK")); - b.addActionListener(new Actions(ACT_MISC)); - bp.add(b = new Button("Cancel")); - b.addActionListener(new AWTConvenience.CloseAction(settingsDialog2)); - - gridc.gridy = 9; - gridc.fill = GridBagConstraints.HORIZONTAL; - gridc.gridwidth = GridBagConstraints.REMAINDER; - gridc.anchor = GridBagConstraints.CENTER; - grid.setConstraints(bp, gridc); - settingsDialog2.add(bp); - - settingsDialog2.addWindowListener(new AWTConvenience.CloseAdapter(b)); - - AWTConvenience.setBackgroundOfChildren(settingsDialog2); - - settingsDialog2.setResizable(true); - settingsDialog2.pack(); - } - - choicePB.select(term.getProperty("pb")); - String sdSet = term.getProperty("sd"); - if((sdSet.charAt(0) == '"' && sdSet.charAt(sdSet.length() - 1) == '"')) { - sdSet = sdSet.substring(1, sdSet.length() - 1); - } - textSD.setText(sdSet); - cbCpOnSel.setState(Boolean.valueOf(term.getProperty("cs")).booleanValue()); - cbCpWinCR.setState(Boolean.valueOf(term.getProperty("sc")).booleanValue()); - - choiceRG.select(term.getProperty("rg")); - - - - if(term.getProperty("bs").equals("DEL")) { - cbBS.setState(true); - } else { - cbBS.setState(false); - } - if(term.getProperty("de").equals("BS")) { - cbDEL.setState(true); - } else { - cbDEL.setState(false); - } - - cbAsciiLD.setState(Boolean.valueOf(term.getProperty("ad")).booleanValue()); - cbLocPG.setState(Boolean.valueOf(term.getProperty("lp")).booleanValue()); - - AWTConvenience.placeDialog(settingsDialog2); - - choiceRG.requestFocus(); - settingsDialog2.setVisible(true); - } - - Dialog findDialog = null; - TextField findText; - Label label; - Checkbox dirCheck, caseCheck; - Button findBut, cancBut; - - public final void findDialog() { - if(findDialog == null) { - findDialog = new Dialog(term.ownerFrame, titleName + " - Find", false); - GridBagLayout grid = new GridBagLayout(); - GridBagConstraints gridc = new GridBagConstraints(); - findDialog.setLayout(grid); - - gridc.fill = GridBagConstraints.NONE; - gridc.anchor = GridBagConstraints.WEST; - gridc.gridwidth = 1; - - gridc.gridy = 0; - label = new Label("Find:"); - grid.setConstraints(label, gridc); - findDialog.add(label); - - gridc.fill = GridBagConstraints.HORIZONTAL; - gridc.gridwidth = 5; - - findText = new TextField("", 26); - grid.setConstraints(findText, gridc); - findDialog.add(findText); - - gridc.gridwidth = 4; - gridc.ipadx = 4; - gridc.ipady = 4; - gridc.insets = new Insets(6, 3, 3, 6); - - findBut = new Button("Find"); - grid.setConstraints(findBut, gridc); - findDialog.add(findBut); - - gridc.insets = new Insets(0, 0, 0, 0); - gridc.ipadx = 0; - gridc.ipady = 0; - gridc.gridwidth = 3; - gridc.gridy = 1; - gridc.fill = GridBagConstraints.NONE; - - caseCheck = new Checkbox("Case sensitive"); - grid.setConstraints(caseCheck, gridc); - findDialog.add(caseCheck); - - dirCheck = new Checkbox("Find backwards"); - grid.setConstraints(dirCheck, gridc); - findDialog.add(dirCheck); - - gridc.gridwidth = 4; - gridc.ipadx = 4; - gridc.ipady = 4; - gridc.insets = new Insets(3, 3, 6, 6); - gridc.fill = GridBagConstraints.HORIZONTAL; - cancBut = new Button("Cancel"); - grid.setConstraints(cancBut, gridc); - findDialog.add(cancBut); - - cancBut.addActionListener(new Actions(ACT_FIND_CANCEL)); - - findBut.addActionListener(new Actions(ACT_FIND)); - - findDialog.addWindowListener(new AWTConvenience.CloseAdapter(cancBut)); - - AWTConvenience.setBackgroundOfChildren(findDialog); - AWTConvenience.setKeyListenerOfChildren(findDialog, - new AWTConvenience.OKCancelAdapter(findBut, cancBut), - null); - - findDialog.setResizable(true); - findDialog.pack(); - } - - AWTConvenience.placeDialog(findDialog); - findText.requestFocus(); - findDialog.setVisible(true); - } - - final static boolean doMatch(String findStr, char firstChar, char[] chars, int idx, - boolean caseSens, int len) { - String cmpStr; - if(caseSens) { - if(chars[idx] != firstChar) - return false; - cmpStr = new String(chars, idx, len); - if(cmpStr.equals(findStr)) - return true; - } else { - if(Character.toLowerCase(chars[idx]) != firstChar) - return false; - cmpStr = new String(chars, idx, len); - if(cmpStr.equalsIgnoreCase(findStr)) - return true; - } - return false; - } - - int curFindRow = 0; - int curFindCol = 0; - int findLen = 0; - - void doFind() { - String findStr = findText.getText(); - String cmpStr; - int len = findStr.length(); - boolean caseSens = caseCheck.getState(); - boolean revFind = dirCheck.getState(); - int lastRow = term.saveVisTop + term.curRow; - int startCol; - boolean found = false; - int i, j = 0; - char firstChar = (caseSens ? findStr.charAt(0) : Character.toLowerCase(findStr.charAt(0))); - - if(findLen > 0) { - term.clearSelection(curFindRow, curFindCol, curFindRow, curFindCol + findLen - 1); - } - - if(revFind) { - if(findLen > 0) { - startCol = curFindCol - 1; - } else { - curFindRow = lastRow; - startCol = term.cols - len; - } - foundItRev: - for(i = curFindRow; i >= 0; i--) { - for(j = startCol; j >= 0; j--) { - if(term.screen[i][j] == 0) - continue; - if(doMatch(findStr, firstChar, term.screen[i], j, caseSens, len)) - break foundItRev; - } - startCol = term.cols - len; - } - if(i >= 0) - found = true; - } else { - startCol = curFindCol + findLen; - foundIt: - for(i = curFindRow; i < lastRow; i++) { - for(j = startCol; j < term.cols - len; j++) { - if(term.screen[i][j] == 0) - continue; - if(doMatch(findStr, firstChar, term.screen[i], j, caseSens, len)) - break foundIt; - } - startCol = 0; - } - if(i < lastRow) - found = true; - } - if(found) { - findLen = len; - if(term.saveVisTop < i) - term.visTop = term.saveVisTop; - else if(term.visTop > i || (i - term.visTop > term.rows)) - term.visTop = i; - term.updateScrollbarValues(); - term.makeAllDirty(false); - term.makeSelection(i, j, i, j + len - 1); - curFindRow = i; - curFindCol = j; - findLen = len; - } else { - term.doBell(); - curFindRow = 0; - curFindCol = 0; - findLen = 0; - } - } - - FileDialog sendFileDialog = null; - public final void sendFileDialog() { - if(sendFileDialog == null) { - sendFileDialog = new FileDialog(term.ownerFrame, titleName + - " - Select ASCII-file to send", FileDialog.LOAD); - } - sendFileDialog.setVisible(true); - - try { - netscape.security.PrivilegeManager.enablePrivilege("UniversalFileAccess"); - } catch (netscape.security.ForbiddenTargetException e) { - // !!! - } - - String fileName = sendFileDialog.getFile(); - String dirName = sendFileDialog.getDirectory(); - if(fileName != null && fileName.length() > 0) { - try { - FileInputStream fileIn = new FileInputStream(dirName + fileName); - byte[] bytes = new byte[fileIn.available()]; - fileIn.read(bytes); - term.sendBytes(bytes); - } catch (Throwable t) { - // !!! OUCH - com.mindbright.ssh.SSHMiscDialogs.alert(titleName + " - Alert", - t.getMessage(), - term.ownerFrame); - } - } - } - - TerminalCapture termCapture; - FileDialog captureToFileDialog = null; - public final boolean captureToFileDialog() { - if(captureToFileDialog == null) { - captureToFileDialog = new FileDialog(term.ownerFrame, - titleName + " - Select file to capture to", FileDialog.SAVE); - } - captureToFileDialog.setVisible(true); - - try { - netscape.security.PrivilegeManager.enablePrivilege("UniversalFileAccess"); - } catch (netscape.security.ForbiddenTargetException e) { - // !!! - } - - String fileName = captureToFileDialog.getFile(); - String dirName = captureToFileDialog.getDirectory(); - if(fileName != null && fileName.length() > 0) { - try { - FileOutputStream fileOut = - new FileOutputStream(dirName + fileName, true); - termCapture = new TerminalCapture(fileOut); - termCapture.startCapture(term); - return true; - } catch (Throwable t) { - // !!! OUCH - com.mindbright.ssh.SSHMiscDialogs.alert(titleName + " - Alert", - t.getMessage(), - term.ownerFrame); - } - } - return false; - } - - public void endCapture() { - if(termCapture != null) { - termCapture.endCapture(); - try { - termCapture.getTarget().close(); - } catch (IOException e) { - // !!! OUCH - com.mindbright.ssh.SSHMiscDialogs.alert(titleName + " - Alert", - e.getMessage(), - term.ownerFrame); - } - } - } - - public void setEnabledOpt(int opt, boolean val) { - ((CheckboxMenuItem)menuItems[MENU_OPTIONS][opt + 1]).setEnabled(val); - } - - public void setStateOpt(int opt, boolean val) { - ((CheckboxMenuItem)menuItems[MENU_OPTIONS][opt + 1]).setState(val); - } - - public Menu getMenu(int idx) { - Menu m = new Menu(menuTexts[idx][0]); - int len = menuTexts[idx].length; - MenuItem mi; - String t; - - if(menuItems == null) - menuItems = new Object[menuTexts.length][]; - if(menuItems[idx] == null) - menuItems[idx] = new Object[menuTexts[idx].length]; - - for(int i = 1; i < len; i++) { - t = menuTexts[idx][i]; - if(t == null) { - m.addSeparator(); - continue; - } - if(t.charAt(0) == '_') { - t = t.substring(1); - mi = new CheckboxMenuItem(t); - ((CheckboxMenuItem)mi).addItemListener(this); - } else { - mi = new MenuItem(t); - mi.addActionListener(this); - } - - if(menuShortCuts[idx][i] != NO_SHORTCUT) { - mi.setShortcut(new MenuShortcut(menuShortCuts[idx][i], true)); - } - - menuItems[idx][i] = mi; - m.add(mi); - } - return m; - } - - int[] mapAction(String action) { - int[] id = new int[2]; - int i = 0, j = 0; - - for(i = 0; i < menuTexts.length; i++) { - for(j = 1; j < menuTexts[i].length; j++) { - String mt = menuTexts[i][j]; - if(mt != null && action.equals(mt)) { - id[0] = i; - id[1] = j; - i = menuTexts.length; - break; - } - } - } - return id; - } - - public void actionPerformed(ActionEvent e) { - int[] id = mapAction(((MenuItem)(e.getSource())).getLabel()); - handleMenuAction(id); - } - - public void itemStateChanged(ItemEvent e) { - int[] id = mapAction("_" + (String)e.getItem()); - handleMenuAction(id); - } - - public void handleMenuAction(int[] id) { - switch(id[0]) { - case MENU_FILE: - switch(id[1]) { - case M_FILE_CAPTURE: - if(((CheckboxMenuItem) - menuItems[MENU_FILE][M_FILE_CAPTURE]).getState()) { - if(!captureToFileDialog()) { - ((CheckboxMenuItem) - menuItems[MENU_FILE][M_FILE_CAPTURE]).setState(false); - } - } else { - endCapture(); - } - break; - case M_FILE_SEND: - ((TerminalMenuHandlerFull)term.getMenus()).sendFileDialog(); - break; - case M_FILE_CLOSE: - if(listener != null) { - listener.close(this); - } - break; - } - break; - - case MENU_EDIT: - switch(id[1]) { - case M_EDIT_COPY: - term.doCopy(); - break; - case M_EDIT_PASTE: - term.doPaste(); - break; - case M_EDIT_CPPASTE: - term.doCopy(); - term.doPaste(); - break; - case M_EDIT_SELALL: - term.selectAll(); - break; - case M_EDIT_FIND: - findDialog(); - break; - case M_EDIT_CLS: - term.clearScreen(); - term.cursorSetPos(0, 0, false); - break; - case M_EDIT_CLEARSB: - term.clearSaveLines(); - break; - case M_EDIT_VTRESET: - term.resetInterpreter(); - break; - } - break; - - case MENU_OPTIONS: - int i = id[1] - 1; - term.setProperty(TerminalDefProps.defaultPropDesc[i] - [TerminalDefProps.PROP_NAME], - String.valueOf(!term.termOptions[i])); - break; - } - } - -} diff --git a/src/main/java/com/mindbright/terminal/TerminalMenuListener.java b/src/main/java/com/mindbright/terminal/TerminalMenuListener.java deleted file mode 100644 index d3449ff..0000000 --- a/src/main/java/com/mindbright/terminal/TerminalMenuListener.java +++ /dev/null @@ -1,21 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.terminal; - -public interface TerminalMenuListener { - public void update(); - public void close(TerminalMenuHandler originMenu); -} diff --git a/src/main/java/com/mindbright/terminal/TerminalOutputListener.java b/src/main/java/com/mindbright/terminal/TerminalOutputListener.java deleted file mode 100644 index c837fe9..0000000 --- a/src/main/java/com/mindbright/terminal/TerminalOutputListener.java +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.terminal; - -public interface TerminalOutputListener { - public void write(char c); - public void write(char[] c, int off, int len); - public void write(byte[] c, int off, int len); -} diff --git a/src/main/java/com/mindbright/terminal/TerminalWin.java b/src/main/java/com/mindbright/terminal/TerminalWin.java deleted file mode 100644 index 5c43a53..0000000 --- a/src/main/java/com/mindbright/terminal/TerminalWin.java +++ /dev/null @@ -1,3108 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.terminal; - -import java.io.IOException; -import java.util.NoSuchElementException; -import java.awt.*; -import java.awt.event.*; -import java.util.Vector; -import java.util.Properties; -import java.util.Enumeration; - -public final class TerminalWin extends Canvas - implements Terminal, KeyListener, AdjustmentListener, MouseListener, - MouseMotionListener, ComponentListener, FocusListener -{ - - boolean metaKeyKludge = false; - boolean ctrlKeyKludge = false; - - int lastKeyKludge = 0; - boolean lastKeyWasPressed = false; - - boolean pendingShow = true; - - final static boolean DEBUG = false; - final static boolean DEBUGKEYEVENT = false; - - final static public int GRAVITY_SOUTHWEST = 0; - final static public int GRAVITY_NORTHWEST = 1; - - final static public int MIN_ROWS = 2; - final static public int MIN_COLS = 8; - final static public int MAX_COLS = 512; - final static public int MAX_ROWS = 512; - - Vector inListeners; - TerminalOutputListener outListener; - TerminalClipboardHandler clipboard; - TerminalInterpreter interpreter; - Scrollbar scrollbar; - boolean haveScrollbar; - PopupMenu popupmenu; - Panel myPanel; - Frame ownerFrame; - - private boolean logoDraw; - private Image logoImg; - private int logoX; - private int logoY; - private int logoW; - private int logoH; - - public int popupButton = InputEvent.BUTTON3_MASK; - public int pasteButton = InputEvent.BUTTON2_MASK; - - TerminalMenuHandler menuHandler; - - String title; - - Properties props; - boolean propsChanged; - String savedGeomPos; - boolean insideConstructor; - - byte bsCharacter; - byte delCharacter; - - boolean haveFocus; - - boolean repaintPending; - boolean cursorHollow; - boolean cursorDrawn; - boolean complexScroll; - boolean fullRefresh; - boolean writeMultiChars; - - int dirtyTop; - int dirtyBottom; - int dirtyLeft; - int dirtyRight; - - int resizeGravity; - - int rows; - int cols; - int vpixels; - int hpixels; - int borderWidth = 2; - int borderHeight = 2; - - int windowTop; - int windowBottom; - int windowLeft; - int windowRight; - - int charWidth; - int charHeight; - int charMaxAscent; - int charMaxDescent; - int charLeading; - int baselineIndex; - - int curRow; - int curCol; - int lastCursorRow; - int lastCursorCol; - - int selectRowAnchor; - int selectColAnchor; - int selectRowLast; - int selectColLast; - boolean hasSelection; - boolean selectReverse; - String selectDelims; - int selectClickRow = -1; - boolean selectClickState; - long lastLeftClick = 0; - - int curAttr; - - int curRowSave; - int curColSave; - int curAttrSave; - - Color origBgColor; - Color origFgColor; - Color cursorColor; - - public final static Color termColors[] = { - Color.black, - Color.red.darker(), - Color.green.darker(), - Color.yellow.darker(), - Color.blue.darker(), - Color.magenta.darker(), - Color.cyan.darker(), - Color.white, - Color.darkGray, - Color.red, - Color.green, - Color.yellow, - Color.blue, - Color.magenta, - Color.cyan, - Color.white - }; - - public final static String[] termColorNames = { - "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", - "i_black", "i_red", "i_green", "i_yellow", - "i_blue","i_magenta", "i_cyan", "i_white" - }; - - char[][] screen; - int[][] attributes; - - int saveLines; - int visTop; - int saveVisTop; - - // (NOTE: The real terminal attributes are in Terminal.java) - // - public final static int ATTR_CHARNOTDRAWN = 0x0000; - public final static int ATTR_LINEDRAW = 0x0100; - public final static int ATTR_SELECTED = 0x1000; - public final static int ATTR_CHARDRAWN = 0x8000; - - public final static int MASK_ATTR = 0x0000ffff; - public final static int MASK_FGCOL = 0x00ff0000; - public final static int MASK_BGCOL = 0xff000000; - public final static int SHIFT_FGCOL = 16; - public final static int SHIFT_BGCOL = 24; - - public final static char[] spacerow = new char[MAX_COLS]; - public final static int[] zerorow = new int[MAX_COLS]; - static { - for(int i = 0; i < MAX_COLS; i++) { - spacerow[i] = ' '; - zerorow[i] = 0; - } - } - - boolean[] tabStops = new boolean[MAX_COLS]; - - boolean[] termOptions; - - Image memImage; - Graphics memGraphics; - Dimension memImageSize; - - public Font plainFont; - public Font boldFont; - - public TerminalWin(Frame ownerFrame, TerminalInterpreter interpreter, - Properties initProps) - throws IllegalArgumentException - { - this(ownerFrame, interpreter, initProps, false); - } - - public TerminalWin(Frame ownerFrame, TerminalInterpreter interpreter, - Properties initProps, boolean setAsDefault) - throws IllegalArgumentException - { - super(); - - scrollbar = null; - haveScrollbar = false; - title = null; - termOptions = new boolean[Terminal.OPT_LAST_OPT]; - cursorDrawn = false; - cursorHollow = false; - curAttr = ATTR_CHARDRAWN; - curRow = 0; - curCol = 0; - visTop = 0; - saveVisTop = 0; - - if(setAsDefault) { - TerminalDefProps.setAsDefault(initProps); - } - - repaintPending = false; - savedGeomPos = ""; - - this.ownerFrame = ownerFrame; - this.interpreter = interpreter; - interpreter.setTerminal(this); - - insideConstructor = true; - setProperties(initProps, true); - insideConstructor = false; - propsChanged = false; - - resetTabs(); - - // !!! We don't receive the proper component-events on the Canvas IMHO?! - // - ownerFrame.addComponentListener(this); - - // !!! Ok, in spite of all our efforts here, we seem to need this - // for certain situations, I give up once again... - // - // ownerFrame.addKeyListener(this); - - addKeyListener(this); - addComponentListener(this); - addFocusListener(this); - addMouseMotionListener(this); - addMouseListener(this); - } - - public TerminalWin(Frame ownerFrame, TerminalInterpreter interpreter) throws IllegalArgumentException, NoSuchElementException { - this(ownerFrame, interpreter, TerminalDefProps.defaultProperties); - } - - public void setMenus(TerminalMenuHandler menus) { - menuHandler = menus; - } - - public TerminalMenuHandler getMenus() { - return menuHandler; - } - - public void updateMenus() { - if(menuHandler != null) - menuHandler.update(); - } - - public void setLogo(Image logoImg, int x, int y, int w, int h) { - this.logoImg = logoImg; - this.logoX = x; - this.logoY = y; - this.logoW = w; - this.logoH = h; - } - - public Image getLogo() { - return logoImg; - } - - public boolean showLogo() { - logoDraw = (logoImg != null); - makeAllDirty(true); - return logoDraw; - } - - public void hideLogo() { - logoDraw = false; - makeAllDirty(true); - } - - public void setProperties(Properties newProps, boolean merge) - throws IllegalArgumentException, NoSuchElementException - { - String name, value; - Enumeration enum; - int i; - Properties oldProps = props; - - props = new Properties(TerminalDefProps.defaultProperties); - - if(merge && oldProps != null) { - enum = oldProps.keys(); - while(enum.hasMoreElements()) { - name = (String)enum.nextElement(); - value = oldProps.getProperty(name); - props.put(name, value); - } - } - - enum = newProps.keys(); - while(enum.hasMoreElements()) { - name = (String)enum.nextElement(); - if(!TerminalDefProps.isProperty(name)) - throw new NoSuchElementException("unknown terminal-property '" + name + "'"); - } - - // Order is important to get this right, set "normal" settings first, then options - // !!! OUCH - // - String oldVal; - - for(i = termOptions.length; i < TerminalDefProps.defaultPropDesc.length; i++) { - name = TerminalDefProps.defaultPropDesc[i][TerminalDefProps.PROP_NAME]; - value = newProps.getProperty(name); - name = TerminalDefProps.backwardCompatProp(name); - if(value == null) - value = props.getProperty(name); - if(!merge && oldProps != null) { - oldVal = oldProps.getProperty(name); - setProperty(name, value, !value.equals(oldVal)); - } else { - setProperty(name, value, insideConstructor); - } - } - for(i = 0; i < termOptions.length; i++) { - name = TerminalDefProps.defaultPropDesc[i][TerminalDefProps.PROP_NAME]; - value = newProps.getProperty(name); - name = TerminalDefProps.backwardCompatProp(name); - if(value == null) - value = props.getProperty(name); - if(!merge && oldProps != null) { - oldVal = oldProps.getProperty(name); - setProperty(name, value, !value.equals(oldVal)); - } else { - setProperty(name, value, insideConstructor); - } - } - } - - public Properties getProperties() { - return props; - } - - public boolean getPropsChanged() { - return propsChanged; - } - - public void setPropsChanged(boolean value) { - propsChanged = value; - } - - public void resetToDefaults() { - setProperties(TerminalDefProps.defaultProperties, false); - } - - public String getProperty(String key) { - key = TerminalDefProps.backwardCompatProp(key); - return props.getProperty(key); - } - - public String getDefaultProperty(String key) { - key = TerminalDefProps.backwardCompatProp(key); - return TerminalDefProps.defaultProperties.getProperty(key); - } - - public void resetProperty(String key) { - key = TerminalDefProps.backwardCompatProp(key); - setProperty(key, getDefaultProperty(key)); - } - - public void setProperty(String key, String value) - throws IllegalArgumentException, NoSuchElementException - { - setProperty(key, value, false); - } - - public synchronized void setProperty(String key, String value, - boolean forceSet) - throws IllegalArgumentException, NoSuchElementException - { - int i; - boolean isEqual = false; - String val; - - key = TerminalDefProps.backwardCompatProp(key); - - if(((val = getProperty(key)) != null) && val.equals(value)) { - isEqual = true; - if(!forceSet) - return; - } - - for(i = 0; i < termOptions.length; i++) { - if(TerminalDefProps.defaultPropDesc[i][TerminalDefProps.PROP_NAME].equals(key)) - break; - } - if(i < termOptions.length) { - if(!(value.equals("true") || value.equals("false"))) - throw new IllegalArgumentException("value for '" + key + "' must be 'true' or 'false'"); - setOption(i, (new Boolean(value)).booleanValue()); - } else { - if(key.equals("term-type")) { - if(interpreter instanceof TerminalXTerm) - ((TerminalXTerm)interpreter).setTerminalType(value); - } else if(key.equals("font-name")) { - setFont(value, Integer.parseInt(getProperty("font-size"))); - } else if(key.equals("font-size")) { - try { - setFont(getProperty("font-name"), Integer.parseInt(value)); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("value for '" + key + "' must be an integer"); - } - } else if(key.equals("save-lines")) { - try { - int sl = Integer.parseInt(value); - if(sl < 0 || sl > 8192) - throw new NumberFormatException(); - setSaveLines(sl); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("value for '" + key + "' must be an integer (0-8192)"); - } - } else if(key.equals("scrollbar")) { - if(myPanel != null) { - if(value.equals("left") || value.equals("right")) { - if(scrollbar != null) { - myPanel.remove(scrollbar); - if(value.equals("right")) - myPanel.add(scrollbar, BorderLayout.EAST); - else - myPanel.add(scrollbar, BorderLayout.WEST); - haveScrollbar = true; - updateScrollbarValues(); - // !!! REMOVE - // scrollbar.setWindowSide(value); - ownerFrame.pack(); - requestFocus(); - } - } else if(value.equals("none")) { - if(scrollbar != null) - myPanel.remove(scrollbar); - ownerFrame.pack(); - requestFocus(); - haveScrollbar = false; - } else { - throw new IllegalArgumentException("scrollbar can be right, left or none"); - } - } - } else if(key.equals("bg-color") || - key.equals("fg-color") || - key.equals("cursor-color")) { - Color c; - try { - if(Character.isDigit(value.charAt(0))) { - c = getTermRGBColor(value); - } else { - c = getTermColor(value); - } - } catch (NumberFormatException e) { - throw new IllegalArgumentException("valid colors: 'color-name' or ',,'"); - } - if(key.equals("bg-color")) { - origBgColor = c; - setBackground(origBgColor); - } else if(key.equals("cursor-color")) { - cursorColor = c; - } else { - origFgColor = c; - setForeground(origFgColor); - } - makeAllDirty(false); - } else if(key.equals("resize-gravity")) { - int rg; - if(value.equals("top")) { - rg = GRAVITY_NORTHWEST; - } else if(value.equals("bottom")) { - rg = GRAVITY_SOUTHWEST; - } else { - throw new IllegalArgumentException("reszize gravity can be 'top' or 'bottom'"); - } - this.resizeGravity = rg; - } else if(key.equals("delete-send")) { - if(value.equals("DEL")) - delCharacter = (byte)0x7f; - else if(value.equals("BS")) { - delCharacter = (byte)0x08; - } else { - throw new IllegalArgumentException("delete character can be 'DEL' or 'BS'"); - } - } else if(key.equals("backspace-send")) { - if(value.equals("DEL")) - bsCharacter = (byte)0x7f; - else if(value.equals("BS")) { - bsCharacter = (byte)0x08; - } else { - throw new IllegalArgumentException("backspace character can be 'DEL' or 'BS'"); - } - } else if(key.equals("geometry")) { - setGeometry(value, true); - } else if(key.equals("select-delim")) { - if(!(value.charAt(0) == '"' && value.charAt(value.length() - 1) == '"')) { - value = "\"" + value + "\""; - } - selectDelims = value.substring(1, value.length()); - } else if(key.equals("paste-button")) { - if(value.equals("middle")) { - pasteButton = InputEvent.BUTTON2_MASK; - } else if(value.equals("right")) { - pasteButton = InputEvent.BUTTON3_MASK; - } else if(value.equals("shift+left")) { - pasteButton = InputEvent.BUTTON1_MASK | - InputEvent.SHIFT_MASK; - } else { - throw new IllegalArgumentException("mouse paste button can be 'middle' or 'right'"); - } - } else { - throw new NoSuchElementException("unknown terminal-property '" + key + "'"); - } - } - props.put(key, value); - - if(!isEqual) { - propsChanged = true; - updateMenus(); - } - } - - public static Color getTermRGBColor(String value) throws NumberFormatException { - int r, g, b, c1, c2; - Color c; - c1 = value.indexOf(','); - c2 = value.lastIndexOf(','); - if(c1 == -1 || c2 == -1) - throw new NumberFormatException(); - r = Integer.parseInt(value.substring(0, c1).trim()); - g = Integer.parseInt(value.substring(c1 + 1, c2).trim()); - b = Integer.parseInt(value.substring(c2 + 1).trim()); - c = new Color(r, g, b); - return c; - } - - public static Color getTermColor(String name) throws IllegalArgumentException { - int i; - for(i = 0; i < termColors.length; i++) { - if(termColorNames[i].equalsIgnoreCase(name)) - break; - } - if(i == termColors.length) - throw new IllegalArgumentException("Unknown color: " + name); - return termColors[i]; - } - - // - // !!! Ouch !!! - // - public void setGeometry(String geometry, boolean doResize) throws IllegalArgumentException { - int ro, co, xPos, yPos, xSz, ySz, delim = geometry.indexOf('x'), delX, delY; - delX = geometry.indexOf('+'); - delY = geometry.indexOf('-'); - - if(delY != -1) - delX = ((delX > delY || delX == -1) ? delY : delX); - - try { - if(delim == -1) - throw new Exception(); - - co = Integer.parseInt(geometry.substring(0, delim).trim()); - ro = Integer.parseInt(geometry.substring(delim + 1, - (delX == -1 ? geometry.length() : delX)).trim()); - xSz = (2 * borderWidth ) + (charWidth * co); - ySz = (2 * borderHeight) + (charHeight * ro); - - if(delX != -1) { - delY = geometry.indexOf('+', delX + 1); - if(delY == -1) { - delY = geometry.indexOf('-', delX + 1); - if(delY == -1) - throw new Exception(); - } - - Dimension sDim = Toolkit.getDefaultToolkit().getScreenSize(); - Insets fIns = ownerFrame.getInsets(); - int sbSz = (haveScrollbar ? scrollbar.getSize().width : 0); - - xPos = Integer.parseInt(geometry.substring(delX + 1, delY).trim()); - yPos = Integer.parseInt(geometry.substring(delY + 1).trim()); - - if(geometry.charAt(delX) == '-') - xPos = sDim.width - xSz - xPos - fIns.left - fIns.right - sbSz; - if(geometry.charAt(delY) == '-') - yPos = sDim.height - ySz - yPos - fIns.top - fIns.bottom; - - savedGeomPos = geometry.substring(delX).trim(); - - // !!! We can only calculate right position when ownerFrame isShowing otherwise - // the insets and everything is not set, then we set pendingShow to be called later - // from componentShown - // - if(isShowing()) - ownerFrame.setLocation(xPos, yPos); - - } else { - savedGeomPos = ""; - } - } catch(Exception e) { - throw new IllegalArgumentException("geometry must be 'x[position]', e.g. '80x24+0-0'"); - } - if(doResize) { - setSize(xSz, ySz); - if(isShowing()) { - componentResized(null); - ownerFrame.pack(); - requestFocus(); - } else { - pendingShow = true; - setWindowSize(ro, co); - resetWindow(); - clearScreen(); - } - } - } - - final private void setFont(String name, int size) { - plainFont = new Font(name, Font.PLAIN, size); - boldFont = new Font(name, Font.BOLD, size); - - super.setFont(plainFont); - getDimensionOfText(0, 0); - - if(isShowing()) { - componentResized(null); - } - - } - - public void setFont(Font font) { - setFont(font.getName(), font.getSize()); - } - - public void setTitle(String title) { - this.title = title; - signalWindowChanged(rows, cols, vpixels, hpixels); - } - - public String getTitle() { - return title; - } - - public void setPopupButton(int buttonNum) { - switch(buttonNum) { - case 1: - popupButton = InputEvent.BUTTON1_MASK; - break; - case 2: - popupButton = InputEvent.BUTTON2_MASK; - break; - case 3: - popupButton = InputEvent.BUTTON3_MASK; - break; - default: - break; - } - } - - public PopupMenu getPopupMenu(String header) { - if(popupmenu != null) - return popupmenu; - popupmenu = new PopupMenu(header); - this.add(popupmenu); - return popupmenu; - } - - void updateScrollbarValues() { - if(haveScrollbar) { - scrollbar.setValues(visTop, rows, 0, saveVisTop + rows); - scrollbar.setBlockIncrement(rows); - } - } - - public Panel getPanelWithScrollbar() { - if(myPanel != null) - return myPanel; - - haveScrollbar = true; - scrollbar = new Scrollbar(Scrollbar.VERTICAL); - updateScrollbarValues(); - scrollbar.addAdjustmentListener(this); - - myPanel = new Panel(new BorderLayout()); - myPanel.add(this, BorderLayout.CENTER); - String sb = getProperty("scrollbar"); - if(sb.equals("left")) - myPanel.add(scrollbar, BorderLayout.WEST); - else if(sb.equals("right")) - myPanel.add(scrollbar, BorderLayout.EAST); - else - haveScrollbar = false; // No scrollbar - - /* !!! REMOVE - if(haveScrollbar) - scrollbar.setWindowSide(sb); - */ - - return myPanel; - } - - private final void setSaveLines(int n) { - int oldSaveLines = saveLines; - int fromRow, toRow, copyRows; - boolean outOfMemory = false; - n = (n < 0 ? 0 : n); - n = (n > 8192 ? 8192 : n); - - if(saveLines != n) { - char[][] oldScreen = screen; - int[][] oldAttributes = attributes; - saveLines = n; - try { - setWindowSize(rows, cols); - } catch (OutOfMemoryError e) { - saveLines = oldSaveLines; - setWindowSize(rows, cols); - outOfMemory = true; - } - toRow = 0; - if(oldSaveLines < saveLines) { - fromRow = 0; - copyRows = oldSaveLines + rows; - } else { - if(saveVisTop <= saveLines) { - fromRow = 0; - copyRows = saveVisTop + rows; - } else { - fromRow = saveVisTop - saveLines; - copyRows = saveLines + rows; - saveVisTop -= fromRow; - } - } - System.arraycopy(oldScreen, fromRow, screen, toRow, copyRows); - System.arraycopy(oldAttributes, fromRow, attributes, toRow, copyRows); - - visTop = saveVisTop; - - updateScrollbarValues(); - - if(outOfMemory) { - outOfMemory = false; - write("\n\rOut of memory allocating scrollback buffer, reverting to " + saveLines + " lines!"); - } - - } - } - - public void clearSaveLines() { - int fromRow, toRow, copyRows; - - char[][] oldScreen = screen; - int[][] oldAttributes = attributes; - setWindowSize(rows, cols); - fromRow = saveVisTop; - System.arraycopy(oldScreen, saveVisTop, screen, 0, rows); - System.arraycopy(oldAttributes, saveVisTop, attributes, 0, rows); - saveVisTop = 0; - visTop = 0; - updateScrollbarValues(); - makeAllDirty(true); - } - - public void setWindowSize(int rows, int cols) { - if(DEBUG) System.out.println("setWindowSize: " + cols + "x" + rows); - this.rows = rows; - this.cols = cols; - screen = new char[rows + saveLines][cols]; - attributes = new int[rows + saveLines][cols]; - } - - public void setInterpreter(TerminalInterpreter interpreter) { - if(interpreter != null) - this.interpreter = interpreter; - } - - // - // Terminal interface - // - - public String terminalType() { - return interpreter.terminalType(); - } - public int rows() { - return rows; - } - public int cols() { - return cols; - } - public int vpixels() { - return vpixels; - } - public int hpixels() { - return hpixels; - } - - protected final void makeAllDirty(boolean instantUpdate) { - updateDirtyArea(0, 0, rows, cols); - if(instantUpdate && isShowing()) { - Graphics g = getGraphics(); - if(g != null) - update(g); - } else { - repaint(); - } - } - protected final void updateDirtyArea(int top, int left, int bottom, int right) { - if(top < dirtyTop) - dirtyTop = top; - if(bottom > dirtyBottom) - dirtyBottom = bottom; - if(left < dirtyLeft) - dirtyLeft = left; - if(right > dirtyRight) - dirtyRight = right; - } - synchronized final public void write(char c) { - if(outListener != null && !writeMultiChars) { - outListener.write(c); - } - if(visTop != saveVisTop && termOptions[OPT_SCROLL_SI]) { - repaintPending = false; // To make the code below do repaint() - visTop = saveVisTop; - if(haveScrollbar) - scrollbar.setValue(visTop); - updateDirtyArea(0, 0, rows, cols); - } - - int ic; - if((ic = interpreter.interpretChar(c)) != TerminalInterpreter.IGNORE) { - c = (char)ic; - if(curCol == cols) { - if(termOptions[OPT_AUTO_WRAP]) { - curRow += 1; - curCol = 0; - if(curRow == windowBottom) { - scrollUp(1); - curRow = windowBottom - 1; - } - } else - curCol--; - } - - if(termOptions[OPT_INSERTMODE]) { - insertChars(1); - } - - // Keep track of the spanning update area - // - updateDirtyArea(curRow, curCol, curRow + 1, curCol + 1); - - int idxRow = visTop + curRow; - attributes[idxRow][curCol] = curAttr; - screen[idxRow][curCol++] = c; - } - - repaint(); - } - public synchronized final void write(char[] c, int off, int len) { - waitForMore = true; - writeMultiChars = true; - int end = off + len; - for(int i = off; i < end; i++) - write(c[i]); - if(outListener != null) { - outListener.write(c, off, len); - } - writeMultiChars = false; - } - public synchronized final void write(byte[] c, int off, int len) { - write(new String(c, off, len)); // Convert to default encoding - } - public final void write(String s) { - char[] carr = s.toCharArray(); - write(carr, 0, carr.length); - } - - public void writeLineDrawChar(char c) { - if(curCol == cols) { - if(termOptions[OPT_AUTO_WRAP]) { - curRow += 1; - curCol = 0; - if(curRow == windowBottom) { - scrollUp(1); - curRow = windowBottom - 1; - } - } else - curCol--; - } - // Keep track of the spanning update area - // - updateDirtyArea(curRow, curCol, curRow + 1, curCol + 1); - - int idxRow = visTop + curRow; - attributes[idxRow][curCol] = (curAttr | ATTR_LINEDRAW); - screen[idxRow][curCol++] = c; - } - - public void addInputListener(TerminalInputListener inListener) { - if(inListeners == null) { - inListeners = new Vector(); - } - inListeners.removeElement(inListener); - inListeners.addElement(inListener); - } - - public void removeInputListener(TerminalInputListener inListener) { - if(inListeners != null) { - inListeners.removeElement(inListener); - if(inListeners.size() == 0) { - inListeners = null; - } - } - } - - public void addOutputListener(TerminalOutputListener outListener) { - // !!! TODO have several listeners... - this.outListener = outListener; - } - - public void removeOutputListener(TerminalOutputListener outListener) { - // !!! TODO have several listeners... - this.outListener = null; - } - - public void setClipboard(TerminalClipboardHandler clipboard) { - this.clipboard = clipboard; - if(hasSelection) { - clipboard.setSelection(getSelection()); - } else { - clipboard.clearSelection(); - } - } - - public TerminalClipboardHandler getClipboard() { - return clipboard; - } - - public void typedChar(char c) { - if(DEBUG) System.out.println("typedChar: " + c + "(" + (int)c + ")"); - if(inListeners != null) { - int n = inListeners.size(); - for(int i = 0; i < n; i++) { - TerminalInputListener inListener = (TerminalInputListener) - inListeners.elementAt(i); - if(inListener != null) { - inListener.typedChar(c); - } - } - } - } - - public final void sendBytes(byte[] b) { - if(DEBUG) System.out.println("Sending " + b.length + " bytes"); - if(inListeners != null) { - int n = inListeners.size(); - for(int i = 0; i < n; i++) { - TerminalInputListener inListener = (TerminalInputListener) - inListeners.elementAt(i); - if(inListener != null) { - inListener.sendBytes(b); - } - } - } - } - - public void signalWindowChanged(int rows, int cols, int vpixels, int hpixels) { - if(DEBUG) System.out.println("SIGWINCH: " + rows + ", " + cols); - if(inListeners != null) { - int n = inListeners.size(); - for(int i = 0; i < n; i++) { - TerminalInputListener inListener = (TerminalInputListener) - inListeners.elementAt(i); - if(inListener != null) { - inListener.signalWindowChanged(rows, cols, vpixels, hpixels); - } - } - } - } - - public void doBell() { - if(termOptions[OPT_VIS_BELL]) { - setOption(OPT_REV_VIDEO, !termOptions[OPT_REV_VIDEO]); - setOption(OPT_REV_VIDEO, !termOptions[OPT_REV_VIDEO]); - } else { - Toolkit toolkit = Toolkit.getDefaultToolkit(); - if(toolkit != null) { - try { - toolkit.beep(); - } catch (Exception e) { - // !!! Could not beep, we are probably an unpriviliged applet - // Automatically enable visual-bell now and "sound" it instead - // - setOption(OPT_VIS_BELL, true); - doBell(); - } - } - } - } - - public void doBS() { - if(DEBUG) System.out.println("doBS"); - cursorBackward(1); - } - - public void doTab() { - int i; - if(curCol < windowRight) { - for(i = curCol + 1; i < windowRight; i++) - if(tabStops[i]) - break; - curCol = (i < windowRight ? i : windowRight - 1); - } - if(DEBUG) System.out.println("doTab"); - } - - public void doTabs(int n) { - while(n-- > 0) - doTab(); - } - public void doBackTabs(int n) { - if(DEBUG) System.out.println("doBackTabs: " + n); - int i; - if(curCol > 0 && n >= 0) { - for(i = curCol - 1; i >= 0; i--) { - if(tabStops[i]) { - if(--n == 0) - break; - } - } - curCol = (i < 0 ? 0 : i); - } - } - - public void setTab(int col) { - tabStops[col] = true; - } - - public void clearTab(int col) { - tabStops[col] = false; - } - - public void resetTabs() { - for(int i = 0; i < MAX_COLS; i++) { - if((i % 8) == 0) - tabStops[i] = true; - else - tabStops[i] = false; - } - } - - public void clearAllTabs() { - for(int i = 0; i < MAX_COLS; i++) - tabStops[i] = false; - } - - public void doCR() { - curCol = windowLeft; - if(DEBUG) System.out.println("doCR"); - } - - public void doLF() { - curRow += 1; - if(curRow == windowBottom) { - scrollUp(1); - curRow = windowBottom - 1; - } - if(termOptions[OPT_LOCAL_ECHO] && termOptions[OPT_AUTO_LF]) { - doCR(); - } - if(DEBUG) System.out.println("doLF"); - } - - public void resetInterpreter() { - interpreter.vtReset(); - makeAllDirty(true); - } - - public void resetWindow() { - windowTop = 0; - windowBottom = rows; - windowLeft = 0; - windowRight = cols; - complexScroll = false; - } - public void setWindow(int top, int bottom) { - setWindow(top, 0, bottom, cols); - } - public void setWindow(int top, int left, int bottom, int right) { - windowTop = top; - windowLeft = left; - windowBottom = bottom; - windowRight = right; - if(DEBUG) System.out.println("setWindow: " + top + ", " + bottom + ", " + left + ", " + right); - - // Ensure that the selected area is totally outside the scrolling - // region OR that the scrolling region starts at the top of the - // screen and the selection is completely above the scrolling - // regions bottom. This makes things alot easier and is not that much - // of problem. - // - if(hasSelection) { - int selRowAnch = selectRowAnchor - visTop; - int selRowLast = selectRowLast - visTop; - if(top != 0 && (selRowAnch >= 0 || selRowLast >= 0)) { - if(!(selRowAnch < top && selRowLast < top || - selRowAnch >= bottom && selRowLast >= bottom)) { - clearSelection(); - } - } else { - if(!(selRowAnch < bottom && selRowLast < bottom)) { - clearSelection(); - } - } - } - - if(windowLeft != 0 || windowRight != cols) - complexScroll = true; - else - complexScroll = false; - - } - public int getWindowTop() { - return windowTop; - } - public int getWindowBottom() { - return windowBottom; - } - public int getWindowLeft() { - return windowLeft; - } - public int getWindowRight() { - return windowRight; - } - - public int getCursorV() { - return curRow; - } - public int getCursorH() { - return curCol; - } - - public void cursorSetPos(int v, int h, boolean relative) { - if(DEBUG) System.out.println("cursorSetPos: " + v + ", " + h + "(" + relative + ")"); - int maxV = rows - 1; - int maxH = cols - 1; - int minV = 0; - int minH = 0; - if(relative) { - v += windowTop; - maxV = windowBottom - 1; - minV = windowTop; - h += windowLeft; - maxH = windowRight - 1; - minH = windowLeft; - } - if(v < minV) - v = minV; - if(h < minH) - h = minH; - if(v > maxV) - v = maxV; - if(h > maxH) - h = maxH; - curRow = v; - curCol = h; - } - public void cursorUp(int n) { - if(DEBUG) System.out.println("cursorUp: " + n); - int min = (curRow < windowTop ? 0 : windowTop); - curRow -= n; - if(curRow < min) - curRow = min; - } - public void cursorDown(int n) { - if(DEBUG) System.out.println("cursorDown: " + n); - int max = (curRow > windowBottom - 1 ? rows - 1: windowBottom - 1); - curRow += n; - if(curRow > max) - curRow = max; - } - public void cursorForward(int n) { - if(DEBUG) System.out.println("cursorFwd: " + n); - curCol += n; - if(curCol > windowRight) - curCol = windowRight; - } - public void cursorBackward(int n) { - if(DEBUG) System.out.println("cursorBack: " + n); - curCol -= n; - if(curCol < windowLeft) { - if(termOptions[OPT_REV_WRAP]) { - curCol = windowRight - (windowLeft - curCol); - cursorUp(1); - } else { - curCol = windowLeft; - } - } - } - public void cursorIndex(int n) { - if(DEBUG) System.out.println("cursorIndex: " + n); - if(curRow > windowBottom || curRow + n < windowBottom) - cursorDown(n); - else { - int m = windowBottom - curRow; - cursorDown(m); - scrollUp((n - m) + 1); - } - } - public void cursorIndexRev(int n) { - if(DEBUG) System.out.println("cursorIndexRev: " + n); - if(curRow < windowTop || curRow - n >= windowTop) - cursorUp(n); - else { - int m = curRow - windowTop; - scrollDown(n - m); - cursorUp(m); - } - } - - public void cursorSave() { - curRowSave = curRow; - curColSave = curCol; - curAttrSave = curAttr; - } - public void cursorRestore() { - curRow = curRowSave; - curCol = curColSave; - curAttr = curAttrSave; - } - - public void scrollUp(int n) { - int windowHeight = windowBottom - windowTop; - int i, j = windowTop; - - if(DEBUG) System.out.println("scrollUp: " + n); - - if(complexScroll) { - // !!! TODO: This is untested... - if(n < windowHeight) { - j = (windowHeight - n) + windowTop; - for(i = windowTop; i < j; i++) { - System.arraycopy(screen[visTop + i + n], windowLeft, screen[visTop + i], - windowLeft, windowRight - windowLeft); - System.arraycopy(attributes[visTop + i + n], windowLeft, - attributes[visTop + i], windowLeft, (windowRight - windowLeft)); - } - } - for(i = j; i < windowBottom; i++) { - System.arraycopy(spacerow, 0, screen[visTop + i], windowLeft, windowRight - windowLeft); - System.arraycopy(zerorow, 0, attributes[visTop + i], windowLeft, (windowRight - windowLeft)); - } - } else { - if(windowTop == 0 && (windowBottom == rows) && saveLines > 0) { - int sl = (n < windowHeight ? n : windowHeight); - int ll; - if((visTop + sl) > saveLines) { - if(hasSelection) { - if(!(((selectRowAnchor - n) < 0) || ((selectRowLast - n) < 0))) { - selectRowAnchor -= n; - selectRowLast -= n; - } else { - clearSelection(); - } - } - ll = windowHeight - sl; - System.arraycopy(screen, sl, screen, 0, saveLines + ll); - System.arraycopy(attributes, sl, attributes, 0, saveLines + ll); - for(i = windowHeight - sl; i < windowHeight; i++) { - screen[saveLines + i] = new char[cols]; - attributes[saveLines + i] = new int[cols]; - } - } else { - visTop += sl; - saveVisTop = visTop; - updateScrollbarValues(); - } - } else { - if(n < windowHeight) { - j = (windowHeight - n) + windowTop; - System.arraycopy(screen, visTop + windowTop + n, screen, visTop + windowTop, - (windowHeight - n)); - System.arraycopy(attributes, visTop + windowTop + n, attributes, - visTop + windowTop, (windowHeight - n)); - } - for(i = j; i < windowBottom; i++) { - screen[visTop + i] = new char[cols]; - attributes[visTop + i] = new int[cols]; - } - } - } - - updateDirtyArea(windowTop, windowLeft, windowBottom, windowRight); - } - - public void scrollDown(int n) { - int windowHeight = windowBottom - windowTop; - int i, j = windowBottom; - - if(DEBUG) System.out.println("scrollDown: " + n); - - if(complexScroll) { - // !!! TODO: This is untested... - if(n < windowHeight) { - j = windowTop + n; - for(i = windowBottom - 1; i >= j; i--) { - System.arraycopy(screen[visTop + i - n], windowLeft, screen[visTop + i], windowLeft, windowRight - windowLeft); - System.arraycopy(attributes[visTop + i - n], windowLeft, - attributes[visTop + i], windowLeft, (windowRight - windowLeft)); - } - } - for(i = windowTop; i < j; i++) { - System.arraycopy(spacerow, 0, screen[visTop + i], windowLeft, windowRight - windowLeft); - System.arraycopy(zerorow, 0, attributes[visTop + i], windowLeft, (windowRight - windowLeft)); - } - } else { - if(n < windowHeight) { - j = windowTop + n; - System.arraycopy(screen, visTop + windowTop, screen, visTop + windowTop + n, - windowHeight - n); - System.arraycopy(attributes, visTop + windowTop, attributes, visTop + windowTop + n, - windowHeight - n); - } - for(i = windowTop; i < j; i++) { - screen[visTop + i] = new char[cols]; - attributes[visTop + i] = new int[cols]; - } - } - updateDirtyArea(windowTop, 0, windowBottom, cols); - } - - public void clearBelow() { - if(DEBUG) System.out.println("clearBelow"); - clearRight(); - int[] attrLine = new int[cols]; - int i; - for(i = 0; i < cols; i++) - attrLine[i] = (curAttr & (MASK_BGCOL | MASK_FGCOL | ATTR_BGCOLOR | ATTR_FGCOLOR)); - for(i = curRow + 1; i < windowBottom; i++) { - screen[visTop + i] = new char[cols]; - attributes[visTop + i] = new int[cols]; - System.arraycopy(attrLine, 0, attributes[visTop + i], 0, cols); - } - updateDirtyArea(curRow, 0, windowBottom, cols); - } - public void clearAbove() { - if(DEBUG) System.out.println("clearAbove"); - clearLeft(); - int[] attrLine = new int[cols]; - int i; - for(i = 0; i < cols; i++) - attrLine[i] = (curAttr & (MASK_BGCOL | MASK_FGCOL | ATTR_BGCOLOR | ATTR_FGCOLOR)); - for(i = windowTop; i < curRow; i++) { - screen[visTop + i] = new char[cols]; - attributes[visTop + i] = new int[cols]; - System.arraycopy(attrLine, 0, attributes[visTop + i], 0, cols); - } - updateDirtyArea(windowTop, 0, curRow, cols); - } - public void clearScreen() { - if(DEBUG) System.out.println("clearScreen"); - int i; - int[] attrLine = new int[cols]; - - for(i = 0; i < cols; i++) - attrLine[i] = (curAttr & (MASK_BGCOL | MASK_FGCOL | ATTR_BGCOLOR | ATTR_FGCOLOR)); - for(i = windowTop; i < windowBottom; i++) { - screen[saveVisTop + i] = new char[cols]; - attributes[saveVisTop + i] = new int[cols]; - System.arraycopy(attrLine, 0, attributes[saveVisTop + i], 0, cols); - } - - // Don't call updateDirtyArea(0, 0, rows, cols); - // we want the values reset instead of updated - // - dirtyTop = 0; - dirtyBottom = rows; - dirtyLeft = 0; - dirtyRight = cols; - repaint(); - } - public void clearRight() { - if(DEBUG) System.out.println("clearRight"); - System.arraycopy(spacerow, 0, screen[visTop + curRow], curCol, cols - curCol); - for(int i = curCol; i < cols; i++) { - attributes[visTop + curRow][i] = - (curAttr & (MASK_BGCOL | MASK_FGCOL | ATTR_BGCOLOR | ATTR_FGCOLOR)); - } - updateDirtyArea(curRow, curCol, curRow + 1, cols); - } - public void clearLeft() { - if(DEBUG) System.out.println("clearLeft"); - System.arraycopy(spacerow, 0, screen[visTop + curRow], 0, curCol); - for(int i = 0; i < curCol; i++) { - attributes[visTop + curRow][i] = - (curAttr & (MASK_BGCOL | MASK_FGCOL | ATTR_BGCOLOR | ATTR_FGCOLOR)); - } - dirtyLeft = 0; - updateDirtyArea(curRow, 0, curRow + 1, curCol); - } - public void clearLine() { - if(DEBUG) System.out.println("clearLine"); - screen[visTop + curRow] = new char[cols]; - attributes[visTop + curRow] = new int[cols]; - for(int i = 0; i < cols; i++) - attributes[visTop + curRow][i] = - (curAttr & (MASK_BGCOL | MASK_FGCOL | ATTR_BGCOLOR | ATTR_FGCOLOR)); - dirtyLeft = 0; - dirtyRight = cols; - updateDirtyArea(curRow, 0, curRow + 1, cols); - } - - public void eraseChars(int n) { - if(DEBUG) System.out.println("eraseChars"); - if(n > cols - curCol) - n = cols - curCol; - System.arraycopy(spacerow, 0, screen[visTop + curRow], curCol, n); - for(int i = 0; i < n; i++) { - attributes[visTop + curRow][curCol + i] = - (curAttr & (MASK_BGCOL | MASK_FGCOL | ATTR_BGCOLOR | ATTR_FGCOLOR)); - } - updateDirtyArea(curRow, curCol, curRow, curCol + n); - } - public void insertChars(int n) { - int edge = windowRight; - if(DEBUG) System.out.println("inserChars: " + n); - if(curCol < windowLeft || curCol > windowRight) - return; - if((curCol + n) < windowRight) { - edge = curCol + n; - System.arraycopy(screen[visTop + curRow], curCol, screen[visTop + curRow], edge, - windowRight - edge); - System.arraycopy(attributes[visTop + curRow], curCol, - attributes[visTop + curRow], edge, (windowRight - edge)); - } - System.arraycopy(spacerow, 0, screen[visTop + curRow], curCol, edge - curCol); - for(int i = curCol; i < edge; i++) { - attributes[visTop + curRow][i] = - (curAttr & (MASK_BGCOL | MASK_FGCOL | ATTR_BGCOLOR | ATTR_FGCOLOR)); - } - updateDirtyArea(curRow, curCol, curRow + 1, windowRight); - } - public void deleteChars(int n) { - int edge = curCol; - if(DEBUG) System.out.println("deleteChars: " + n); - if(curCol < windowLeft || curCol > windowRight) - return; - if((curCol + n) < windowRight) { - edge = windowRight - n; - System.arraycopy(screen[visTop + curRow], curCol + n, screen[visTop + curRow], curCol, - edge - curCol); - System.arraycopy(attributes[visTop + curRow], (curCol + n), attributes[visTop + curRow], - curCol, (edge - curCol)); - } - System.arraycopy(spacerow, 0, screen[visTop + curRow], edge, windowRight - edge); - for(int i = edge; i < windowRight; i++) { - attributes[visTop + curRow][i] = - (curAttr & (MASK_BGCOL | MASK_FGCOL | ATTR_BGCOLOR | ATTR_FGCOLOR)); - } - updateDirtyArea(curRow, curCol, curRow + 1, windowRight); - } - public void insertLines(int n) { - int i, edge = windowBottom; - if(DEBUG) System.out.println("insertLines: " + n); - - if(curRow < windowTop || curRow > windowBottom) - return; - - if(complexScroll) { - // !!! TODO: This is untested... - if(curRow + n < windowBottom) { - edge = curRow + n; - for(i = windowBottom - 1; i >= edge; i--) { - System.arraycopy(screen[visTop + i - n], windowLeft, screen[visTop + i], windowLeft, - windowRight - windowLeft); - System.arraycopy(attributes[visTop + i - n], windowLeft, attributes[visTop + i], - windowLeft, (windowRight - windowLeft)); - } - } - for(i = curRow; i < edge; i++) { - System.arraycopy(spacerow, 0, screen[visTop + i], windowLeft, windowRight - windowLeft); - System.arraycopy(zerorow, 0, attributes[visTop + i], windowLeft, (windowRight - windowLeft)); - } - } else { - if(curRow + n < windowBottom) { - edge = curRow + n; - System.arraycopy(screen, visTop + curRow, screen, visTop + edge, windowBottom - edge); - System.arraycopy(attributes, visTop + curRow, attributes, visTop + edge, - windowBottom - edge); - } - int[] attrLine = new int[cols]; - for(i = 0; i < cols; i++) - attrLine[i] = (curAttr & (MASK_BGCOL | MASK_FGCOL | ATTR_BGCOLOR | ATTR_FGCOLOR)); - for(i = curRow; i < edge; i++) { - screen[visTop + i] = new char[cols]; - attributes[visTop + i] = new int[cols]; - System.arraycopy(attrLine, 0, attributes[visTop + i], 0, cols); - } - } - - updateDirtyArea(curRow, 0, windowBottom, cols); - } - public void deleteLines(int n) { - int i, edge = curRow; - if(DEBUG) System.out.println("deleteLines: " + n); - - if(curRow < windowTop || curRow > windowBottom) - return; - - if(complexScroll) { - // !!! TODO: This is untested... - if(curRow + n < windowBottom) { - edge = windowBottom - n - 1; - for(i = curRow; i <= edge; i++) { - System.arraycopy(screen[visTop + i + n], windowLeft, screen[visTop + i], windowLeft, - windowRight - windowLeft); - System.arraycopy(attributes[visTop + i + n], windowLeft, attributes[visTop + i], - windowLeft, (windowRight - windowLeft)); - } - } - for(i = edge; i < windowBottom; i++) { - System.arraycopy(spacerow, 0, screen[visTop + i], windowLeft, windowRight - windowLeft); - System.arraycopy(zerorow, 0, attributes[visTop + i], windowLeft, (windowRight - windowLeft)); - } - } else { - if(curRow + n < windowBottom) { - edge = windowBottom - n; - System.arraycopy(screen, visTop + curRow + n, screen, visTop + curRow, - edge - curRow); - System.arraycopy(attributes, visTop + curRow + n, attributes, visTop + curRow, - edge - curRow); - } - int[] attrLine = new int[cols]; - for(i = 0; i < cols; i++) - attrLine[i] = (curAttr & (MASK_BGCOL | MASK_FGCOL | ATTR_BGCOLOR | ATTR_FGCOLOR)); - for(i = edge; i < windowBottom; i++) { - screen[visTop + i] = new char[cols]; - attributes[visTop + i] = new int[cols]; - System.arraycopy(attrLine, 0, attributes[visTop + i], 0, cols); - } - } - - updateDirtyArea(curRow, 0, windowBottom, cols); - } - - public void setOption(int opt, boolean val) { - if(DEBUG) System.out.println("setOption " + opt + "=" + val); - if(opt > termOptions.length || opt < 0) - return; - - props.put(TerminalDefProps.defaultPropDesc[opt][0], String.valueOf(val)); - - switch(opt) { - case OPT_REV_VIDEO: - Color swap; - if(val != termOptions[opt]) { - termOptions[opt] = val; - swap = origBgColor; - origBgColor = origFgColor; - origFgColor = swap; - makeAllDirty(true); - } - break; - case OPT_VIS_CURSOR: - repaint(); - break; - case OPT_AUTO_WRAP: - case OPT_REV_WRAP: - case OPT_INSERTMODE: - case OPT_AUTO_LF: - case OPT_SCROLL_SK: - case OPT_SCROLL_SI: - case OPT_LOCAL_PGKEYS: - case OPT_COPY_CRNL: - case OPT_ASCII_LDC: - case OPT_LOCAL_ECHO: - case OPT_VIS_BELL: - case OPT_MAP_CTRLSP: - case OPT_COPY_SEL: - break; - case OPT_DECCOLM: - if(termOptions[opt] != val && termOptions[OPT_DEC132COLS]) { - setProperty("gm", ((val ? 132 : 80) + "x" + rows + savedGeomPos)); - cursorSetPos(0, 0, false); - } - break; - case OPT_DEC132COLS: - if(menuHandler != null) - menuHandler.setEnabledOpt(OPT_DECCOLM, val); - break; - } - termOptions[opt] = val; - if(menuHandler != null && opt < Terminal.OPT_LAST_MENU) - menuHandler.setStateOpt(opt, val); - } - public boolean getOption(int opt) { - if(DEBUG) System.out.println("getOption " + opt); - if(opt > termOptions.length || opt < 0) - return false; - return termOptions[opt]; - } - - public void setAttribute(int attr, boolean val) { - if(DEBUG) System.out.println("setAttr " + attr + "=" + val); - if(val) - curAttr |= attr; - else - curAttr &= ~attr; - } - public boolean getAttribute(int attr) { - if(DEBUG) System.out.println("getAttr " + attr); - if((curAttr & attr) == attr) - return true; - return false; - } - public void setForegroundColor(int c) { - if(DEBUG) System.out.println("setForegroundColor: " + c); - if(c >= 0 && c < 8) { - if((curAttr & ATTR_BOLD) != 0) - c += 8; - curAttr &= ~(ATTR_FGCOLOR | MASK_FGCOL); - curAttr |= (ATTR_FGCOLOR | (c << SHIFT_FGCOL)); - } else { - curAttr &= ~ATTR_FGCOLOR; - } - } - public void setBackgroundColor(int c) { - if(DEBUG) System.out.println("setBackgroundColor: " + c); - if(c >= 0 && c < 8) { - curAttr &= ~(ATTR_BGCOLOR | MASK_BGCOL); - curAttr |= (ATTR_BGCOLOR | (c << SHIFT_BGCOL)); - } else { - curAttr &= ~ATTR_BGCOLOR; - } - } - public void clearAllAttributes() { - if(DEBUG) System.out.println("clearAllAttributes"); - curAttr = ATTR_CHARDRAWN; - } - - private void kludgeProcessKeyEvent(KeyEvent e) { - int virtKey = e.getKeyCode(); - int mod = e.getModifiers(); - char c = e.getKeyChar(); - int gMode = 0; - - // Consume TAB to be sure no one uses it so we lose focus - // - if(virtKey == KeyEvent.VK_TAB) { - e.consume(); - } - - if(specialKeyHandler(c, virtKey, mod)) - return; - - interpreter.keyHandler(virtKey, mod); - - if(c != KeyEvent.CHAR_UNDEFINED && c != (char)0) { - int transC; - // If keyKludgeFilter return -1 we should not process the char - // - if((transC = keyKludgeFilter(c, virtKey, mod)) == -1) - return; - - c = (char)transC; - - if(termOptions[OPT_LOCAL_ECHO]) - write(c); - - if((c == 0x0a || c == 0x0d) && termOptions[OPT_AUTO_LF]) { - c = 0x0a; - typedChar((char)0x0d); - } - typedChar(c); - - // Reset window to bottom on keypress option - // - if(visTop != saveVisTop && termOptions[OPT_SCROLL_SK]) { - visTop = saveVisTop; - if(haveScrollbar) - scrollbar.setValue(visTop); - makeAllDirty(false); - } - } - } - - private boolean isNewEvent(KeyEvent e, boolean byPressed) { - int ch = (int) e.getKeyChar(); - - if(lastKeyWasPressed != byPressed) { - if(ch == lastKeyKludge) - return false; - // XXX: Are there any more cases like this? - // - if((lastKeyKludge == 0x0a && ch == 0x0d) || - (lastKeyKludge == 0x0d && ch == 0x0a)) { - return false; - } - } - lastKeyKludge = ch; - lastKeyWasPressed = byPressed; - return true; - } - - // - // KeyListener interface - // - public void keyTyped(KeyEvent e) { - char c = e.getKeyChar(); - - if(DEBUGKEYEVENT) { - int virtKey = e.getKeyCode(); - System.out.println("typed: " + c + " (" + ((int)c) + ") code=" + virtKey); - } - - if(isNewEvent(e, false)) - kludgeProcessKeyEvent(e); - } - - public void keyPressed(KeyEvent e) { - int virtKey = e.getKeyCode(); - int mod = e.getModifiers(); - char c = e.getKeyChar(); - int gMode = 0; - - if(DEBUGKEYEVENT) { - System.out.println("pressed: " + c + " (" + ((int)c) + ") code=" + virtKey); - } - - if(isNewEvent(e, true)) - kludgeProcessKeyEvent(e); - } - - public void keyReleased(KeyEvent e) { - int virtKey = e.getKeyCode(); - - if(DEBUGKEYEVENT) { - char c = e.getKeyChar(); - System.out.println("released: " + c + " (" + ((int)c) + ") code=" + virtKey); - } - - switch(virtKey) { - case KeyEvent.VK_ALT: - metaKeyKludge = false; - break; - case KeyEvent.VK_CONTROL: - ctrlKeyKludge = false; - break; - } - } - - final boolean specialKeyHandler(int c, int virtKey, int mod) { - boolean keyProcessed = false; - byte[] b; - - switch(virtKey) { - case KeyEvent.VK_ALT: - if(ctrlKeyKludge) - ctrlKeyKludge = false; // !!! Seems that MS-lost sends ctrl+alt for right ALT !!! - else - metaKeyKludge = true; - keyProcessed = true; - break; - case KeyEvent.VK_CONTROL: - ctrlKeyKludge = true; - keyProcessed = true; - break; - case KeyEvent.VK_BACK_SPACE: - b = new byte[1]; - b[0] = bsCharacter; - sendBytes(b); - keyProcessed = true; - break; - case KeyEvent.VK_DELETE: - b = new byte[1]; - b[0] = delCharacter; - sendBytes(b); - keyProcessed = true; - break; - case KeyEvent.VK_PAGE_UP: - case KeyEvent.VK_PAGE_DOWN: - case KeyEvent.VK_HOME: - case KeyEvent.VK_END: - if(mod == InputEvent.SHIFT_MASK || termOptions[OPT_LOCAL_PGKEYS]) { - localPageCtrlKeys(virtKey); - keyProcessed = true; - } - break; - case KeyEvent.VK_INSERT: - if(mod == InputEvent.SHIFT_MASK) { - doPaste(); - keyProcessed = true; - } else if(mod == InputEvent.CTRL_MASK) { - doCopy(); - keyProcessed = true; - } - break; - case KeyEvent.VK_SHIFT: - case KeyEvent.VK_CAPS_LOCK: - // For some reason there seems to be characters in keyevents with - // shift/caps, better filter them out - // - keyProcessed = true; - } - - return keyProcessed; - } - final int keyKludgeFilter(char c, int virtKey, int mod) { - // - // The KeyEvent content seems to be a bit confusing (to say the least...) - // in some situations given different locale's and especially different - // platforms... This is not very funny, but then again who said anything - // about terminal-stuff beeing some kind of amusement... - // - // !!! - - int transC = (int)c; - - if(virtKey == KeyEvent.VK_SHIFT || - virtKey == KeyEvent.VK_CONTROL || - virtKey == KeyEvent.VK_CAPS_LOCK || - virtKey == KeyEvent.VK_ALT) { - // !!! Swallow keypress for these, seems to contain key chars on some - // combinations of JVM/OS/national keyboard - // - return -1; - } else if ((mod & InputEvent.CTRL_MASK) != 0) { - switch(virtKey) { - case KeyEvent.VK_M: // Bug in MRJ (sent 0x0a on ^M, should be ^J) - transC = 0x0d; - break; - case KeyEvent.VK_SPACE: // To do ctrl-space (for emacs of course) - if(termOptions[OPT_MAP_CTRLSP]) - transC = 0; - break; - default: - if(((mod & InputEvent.ALT_MASK) == 0) && - virtKey >= KeyEvent.VK_A && virtKey <= KeyEvent.VK_Z) { - // This is just to be sure that ctrl+ ends - // up generating the right 'ascii' - // - transC = ctrlAlphaKey(virtKey); - - /* !!! TEMPORARILY DISABLED DUE TO CONFLICTS WITH NATIONAL CHARS - } else if(c == '@') { - transC = 0x00; - } else if(c == '[') { - transC = 0x1b; - } else if(c == '\\') { - transC = 0x1c; - } else if(c == ']') { - transC = 0x1d; - } else if(c == '^') { - transC = 0x1e; - SEE ABOVE REMOVE !!! */ - } else if(c == '_') { - transC = 0x1f; - } - break; - } - } else { - // We always send 0x0d ^M on ENTER no matter where we are... - // - if (transC == 0x0a && virtKey == KeyEvent.VK_ENTER && !ctrlKeyKludge) { - transC = 0x0d; - /* !!! REMOVE - } else if(c == '~') { - // !!! OUCH - // We MIGHT process the sly tilde character here, Hazeltine warning... - // (whomever gets the first tilde snatches further processing of it) - // - if(!tildeTypedKludge) { - tildePressedKludge = true; - } else { - transC = -1; - } - */ - } else if(c == 65535) { - // OUCH, JDK 1.2 generates this on the Shift and Caps keys(!) - // - transC = -1; - } else if(c == 65406) { - // OUCH, IBM JDK 1.1.6 on Linux generates this on right alt (alt_gr) - // (swedish-keyboard) - // - transC = -1; - } - - // To be able to do meta- in emacs with - // - if(transC != -1 && metaKeyKludge) { - typedChar((char)27); - } - } - - return transC; - } - final int ctrlAlphaKey(int virtKey) { - int ctrlC = 0; - switch(virtKey) { - case KeyEvent.VK_A: - ctrlC = 0x01; - break; - - case KeyEvent.VK_B: - ctrlC = 0x02; - break; - - case KeyEvent.VK_C: - ctrlC = 0x03; - break; - - case KeyEvent.VK_D: - ctrlC = 0x04; - break; - - case KeyEvent.VK_E: - ctrlC = 0x05; - break; - - case KeyEvent.VK_F: - ctrlC = 0x06; - break; - - case KeyEvent.VK_G: - ctrlC = 0x07; - break; - - case KeyEvent.VK_H: - ctrlC = 0x08; - break; - - case KeyEvent.VK_I: - ctrlC = 0x09; - break; - - case KeyEvent.VK_J: - ctrlC = 0x0A; - break; - - case KeyEvent.VK_K: - ctrlC = 0x0B; - break; - - case KeyEvent.VK_L: - ctrlC = 0x0C; - break; - - case KeyEvent.VK_M: - ctrlC = 0x0D; - break; - - case KeyEvent.VK_N: - ctrlC = 0x0E; - break; - - case KeyEvent.VK_O: - ctrlC = 0x0F; - break; - - case KeyEvent.VK_P: - ctrlC = 0x10; - break; - - case KeyEvent.VK_Q: - ctrlC = 0x11; - break; - - case KeyEvent.VK_R: - ctrlC = 0x12; - break; - - case KeyEvent.VK_S: - ctrlC = 0x13; - break; - - case KeyEvent.VK_T: - ctrlC = 0x14; - break; - - case KeyEvent.VK_U: - ctrlC = 0x15; - break; - - case KeyEvent.VK_V: - ctrlC = 0x16; - break; - - case KeyEvent.VK_W: - ctrlC = 0x17; - break; - - case KeyEvent.VK_X: - ctrlC = 0x18; - break; - - case KeyEvent.VK_Y: - ctrlC = 0x19; - break; - - case KeyEvent.VK_Z: - ctrlC = 0x1A; - break; - } - return ctrlC; - } - public final void localPageCtrlKeys(int virtKey) { - switch(virtKey) { - case KeyEvent.VK_PAGE_UP: - visTop -= rows; - if(visTop < 0) - visTop = 0; - updateScrollbarValues(); - makeAllDirty(true); - break; - case KeyEvent.VK_PAGE_DOWN: - visTop += rows; - if(visTop > saveVisTop) - visTop = saveVisTop; - updateScrollbarValues(); - makeAllDirty(true); - break; - case KeyEvent.VK_HOME: - visTop = 0; - updateScrollbarValues(); - makeAllDirty(true); - break; - case KeyEvent.VK_END: - visTop = saveVisTop; - updateScrollbarValues(); - makeAllDirty(true); - break; - } - } - - // - // FocusListener, AdjustmentListener, MouseListener, MouseMotionListener, ComponentListener - // - public void focusGained(FocusEvent e) { - setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); - haveFocus = true; - updateFocusCursor(); - } - public void focusLost(FocusEvent e) { - metaKeyKludge = false; - ctrlKeyKludge = false; - setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - haveFocus = false; - updateFocusCursor(); - } - final synchronized void updateFocusCursor() { - Graphics g = getGraphics(); - if(g != null) { - hideCursor(g); - showCursor(g); - } - } - - public boolean isFocusTraversable() { - return true; - } - - // !!! Since the realization of the window is very different on different platforms - // (w.r.t. generated events etc.) we don't listen to componentResized event until - // window is shown, in that instance we also do the pending setGeometry. - // - public void componentMoved(ComponentEvent e) { - // !!! TODO: Do we want to save absolute positions??? - } - public void emulateComponentShown() { - componentShown(new java.awt.event.ComponentEvent(ownerFrame, 0)); - } - public synchronized void componentShown(ComponentEvent e) { - if(e.getComponent() == ownerFrame && pendingShow) { - if(pendingShow) { - // !!! Ad-hoc wait to let AWT thread in, seems to prevent it from sending a - // componentResized when getSize() returns bad value AFTER we have done setSize(), - // this only occurs on Linux (as far as I have seen) due to thread-scheduler lag ?!? - try { - this.wait(500); - } catch(InterruptedException ee) { - } - pendingShow = false; - setGeometry(getProperty("gm"), true); - } - } - } - public void componentHidden(ComponentEvent e) { - } - public synchronized void componentResized(ComponentEvent e) { - Dimension dim = getSize(); - int newCols = (dim.width - (2 * borderWidth)) / charWidth; - int newRows = (dim.height - (2 * borderHeight)) / charHeight; - int oldCols = cols; - int oldRows = rows; - char[][] oldScreen = screen; - int[][] oldAttributes = attributes; - - if(DEBUG) System.out.println("componentResized: " + newCols + "x" + newRows + "(" + - dim.width + "." + dim.height + ")"); - - if(pendingShow || - (e != null && e.getComponent() != this) || - (newCols <= 0 || newRows <= 0)) { - return; - } - - vpixels = dim.height; - hpixels = dim.width; - - if(newCols != oldCols) - clearSelection(); - - // We only want to reallocate and do all this work if the component REALLY has - // changed size, since we seem to get lot's of call-backs here we better check this... - // - if(newRows != rows || newCols != cols) { - setWindowSize(newRows, newCols); - resetWindow(); // !!! Is this right? - clearScreen(); - - oldCols = (oldCols < newCols ? oldCols : newCols); - if(resizeGravity == GRAVITY_NORTHWEST) { - int copyRows = (oldRows < newRows ? oldRows : newRows) + saveVisTop; - for(int i = 0; i < copyRows; i++) { - System.arraycopy(oldScreen[i], 0, screen[i], 0, oldCols); - System.arraycopy(oldAttributes[i], 0, attributes[i], 0, oldCols); - } - } else { - if(hasSelection) { - selectRowAnchor += newRows - oldRows; - selectRowLast += newRows - oldRows; - } - int i, copyRows, fromTop, toTop; - if(oldRows < newRows) { - int linesAdd = newRows - oldRows; - copyRows = oldRows + saveVisTop; - fromTop = 0; - curRow += linesAdd; - if(saveVisTop - linesAdd < 0) { - toTop = linesAdd; - } else { - toTop = 0; - visTop -= linesAdd; - saveVisTop -= linesAdd; - } - } else { - int linesLost = oldRows - newRows; - toTop = 0; - curRow -= linesLost; - if(curRow < 0) - curRow = 0; - if(saveVisTop + linesLost > saveLines) { - copyRows = newRows + saveVisTop; - fromTop = linesLost; - } else { - copyRows = oldRows + saveVisTop; - fromTop = 0; - visTop += linesLost; - saveVisTop += linesLost; - } - } - for(i = 0; i < copyRows; i++) { - System.arraycopy(oldScreen[i + fromTop], 0, screen[i + toTop], 0, oldCols); - System.arraycopy(oldAttributes[i + fromTop], 0, attributes[i + toTop], 0, oldCols); - } - } - - if(curRow >= newRows) - curRow = newRows - 1; - if(curCol >= newCols) - curCol = newCols - 1; - - if(lastCursorRow >= newRows || lastCursorCol >= newCols) { - cursorDrawn = false; - cursorHollow = false; - } - - updateScrollbarValues(); - - signalWindowChanged(rows, cols, vpixels, hpixels); - - memGraphics = null; - - String newGM = (cols + "x" + rows + savedGeomPos); - propsChanged = true; - props.put("geometry", newGM); - updateMenus(); - makeAllDirty(false); - requestFocus(); - } - - } - - public void adjustmentValueChanged(AdjustmentEvent e) { - int adjValue = e.getValue(); - if(adjValue >= 0 && adjValue <= saveVisTop) { - visTop = adjValue; - makeAllDirty(false); - } - } - - public void selectAll() { - selectRowAnchor = 0; - selectColAnchor = 0; - selectRowLast = saveVisTop + curRow; - selectColLast = curCol; - selectReverse = false; - makeSelection(selectRowAnchor, selectColAnchor, selectRowLast, selectColLast); - hasSelection = true; - if(termOptions[OPT_COPY_SEL]) - doCopy(); - } - - public void makeSelection(int startRow, int startCol, int endRow, int endCol) { - int i, j; - if(startRow != endRow) { - for(i = startCol; i < cols; i++) - attributes[startRow][i] |= ATTR_SELECTED; - for(i = startRow + 1; i < endRow; i++) - for(j = 0; j < cols; j++) - attributes[i][j] |= ATTR_SELECTED; - for(i = 0; i <= endCol; i++) - attributes[endRow][i] |= ATTR_SELECTED; - } else { - for(i = startCol; i <= endCol; i++) - attributes[startRow][i] |= ATTR_SELECTED; - } - - startRow -= visTop; - endRow -= visTop; - if(startRow < 0) - startRow = 0; - if(endRow < 0) - endRow = 0; - - updateDirtyArea(startRow, 0, endRow + 1, cols); - repaint(); - } - public void clearSelection(int startRow, int startCol, int endRow, int endCol) { - int i, j; - if(startRow != endRow) { - for(i = startCol; i < cols; i++) - attributes[startRow][i] &= ~ATTR_SELECTED; - for(i = startRow + 1; i < endRow; i++) - for(j = 0; j < cols; j++) - attributes[i][j] &= ~ATTR_SELECTED; - for(i = 0; i <= endCol; i++) - attributes[endRow][i] &= ~ATTR_SELECTED; - } else { - for(i = startCol; i <= endCol; i++) - attributes[startRow][i] &= ~ATTR_SELECTED; - } - - startRow -= visTop; - endRow -= visTop; - if(startRow < 0) - startRow = 0; - if(endRow < 0) - endRow = 0; - - updateDirtyArea(startRow, 0, endRow + 1, cols); - repaint(); - } - - public void clearSelection() { - if(!hasSelection) - return; - if(selectReverse) - clearSelection(selectRowLast, selectColLast, selectRowAnchor, selectColAnchor); - else - clearSelection(selectRowAnchor, selectColAnchor, selectRowLast, selectColLast); - hasSelection = false; - if(clipboard != null) - clipboard.clearSelection(); - } - - final int mouseRow(int y) { - int mouseRow = (y - borderHeight) / charHeight; - if(mouseRow < 0) - mouseRow = 0; - else if(mouseRow >= rows) - mouseRow = rows - 1; - return mouseRow; - } - final int mouseCol(int x) { - int mouseCol = (x - borderWidth) / charWidth; - if(mouseCol < 0) - mouseCol = 0; - else if(mouseCol >= cols) - mouseCol = cols - 1; - return mouseCol; - } - - public void mouseClicked(MouseEvent e) { - // !!! TODO: Why is this if here ??? (avoid doing at "start-up"?) - if(inListeners != null) { - if(e.getModifiers() == pasteButton) { - doPaste(); - } - } - if(e.getModifiers() == InputEvent.BUTTON1_MASK) - requestFocus(); - } - public void mouseEntered(MouseEvent e) { - } - public void mouseExited(MouseEvent e) { - } - public void mousePressed(MouseEvent e) { - long now = System.currentTimeMillis(); - - int mouseRow = mouseRow(e.getY()); - int mouseCol = mouseCol(e.getX()); - - if(DEBUG) System.out.println("char '" + screen[visTop + mouseRow][mouseCol] + "' attr: " + - attributes[visTop + mouseRow][mouseCol] + - " fgcol: " + - ((attributes[visTop + mouseRow][mouseCol] & MASK_FGCOL) >>> SHIFT_FGCOL) + - " bgcol: " + - ((attributes[visTop + mouseRow][mouseCol] & MASK_BGCOL) >>> SHIFT_BGCOL)); - - if(e.getModifiers() == (popupButton | InputEvent.CTRL_MASK)) { - if(popupmenu != null) { - // !!! Kludge, the ctrl-button upevent is caught elsewhere - // (and we don't seem to get focusLost?!) - ctrlKeyKludge = false; - popupmenu.show(this, e.getX(), e.getY()); - } - } - - interpreter.mouseHandler(mouseRow, mouseCol, true, e.getModifiers()); - - mouseRow += visTop; - - clearSelection(); - selectRowAnchor = mouseRow; - selectColAnchor = mouseCol; - selectRowLast = mouseRow; - selectColLast = mouseCol; - - if((now - lastLeftClick) < 250) { - doClickSelect(mouseRow, mouseCol); - } else { - selectClickRow = -1; - selectClickState = false; - } - lastLeftClick = now; - } - public void mouseReleased(MouseEvent e) { - int mouseRow = mouseRow(e.getY()); - int mouseCol = mouseCol(e.getX()); - - // !!! TODO: Why is this if here ??? (avoid doing at "start-up"?) - if(inListeners != null) { - if(e.getModifiers() == InputEvent.BUTTON1_MASK) { - if(hasSelection) { - if(termOptions[OPT_COPY_SEL]) - doCopy(); - } - } - } - - interpreter.mouseHandler(mouseRow, mouseCol, false, e.getModifiers()); - } - public void mouseMoved(MouseEvent e) { - } - synchronized public void mouseDragged(MouseEvent e) { - int mouseRow = (e.getY() - borderHeight) / charHeight; - int mouseCol = (e.getX() - borderWidth) / charWidth; - - if(mouseRow < 0) - mouseRow = 0; - else if(mouseRow >= rows) - mouseRow = rows - 1; - if(mouseCol < 0) - mouseCol = 0; - else if(mouseCol >= cols) - mouseCol = cols - 1; - - mouseRow += visTop; - - if(mouseRow == selectRowLast && mouseCol == selectColLast && hasSelection) { - return; - } - - boolean backwardSelection; - boolean backwardsFromLast; - - if(selectRowAnchor > mouseRow || - (selectRowAnchor == mouseRow && mouseCol < selectColAnchor)) - backwardSelection = true; - else - backwardSelection = false; - - if(backwardSelection != selectReverse) { - if(selectReverse) - clearSelection(selectRowLast, selectColLast, selectRowAnchor, selectColAnchor); - else - clearSelection(selectRowAnchor, selectColAnchor, selectRowLast, selectColLast); - selectReverse = backwardSelection; - selectRowLast = selectRowAnchor; - selectColLast = selectColAnchor; - } - - if(selectRowLast > mouseRow || - (selectRowLast == mouseRow && mouseCol < selectColLast)) - backwardsFromLast = true; - else - backwardsFromLast = false; - - if(selectReverse) { - if(backwardsFromLast) - makeSelection(mouseRow, mouseCol, selectRowLast, selectColLast); - else - clearSelection(selectRowLast, selectColLast, mouseRow, mouseCol); - } else { - if(backwardsFromLast) - clearSelection(mouseRow, mouseCol, selectRowLast, selectColLast); - else - makeSelection(selectRowLast, selectColLast, mouseRow, mouseCol); - } - - selectReverse = backwardSelection; - - selectRowLast = mouseRow; - selectColLast = mouseCol; - - hasSelection = true; - } - - // !!! Ouch !!! - // - final int nextPrintedChar(int row, int col) { - int i; - for(i = col; i < cols; i++) - if(screen[row][i] != 0) - break; - return i; - } - - final int prevPrintedChar(int row, int col) { - int i; - for(i = col; i >= 0; i--) - if(screen[row][i] != 0) - break; - return i; - } - - final String addSpaces(int start, int end) { - int n = end - start; - - if(end == cols) - return ""; - - char[] spaces = new char[n]; - System.arraycopy(spacerow, 0, spaces, 0, n); - - return new String(spaces); - } - - public String getSelection() { - if(!hasSelection) - return null; - - int startRow; - int endRow; - int startCol; - int endCol; - int i, j, n; - String eol; - - if(termOptions[OPT_COPY_CRNL]) - eol = "\r\n"; - else - eol = "\r"; - - if(selectReverse) { - startRow = selectRowLast; - startCol = selectColLast; - endRow = selectRowAnchor; - endCol = selectColAnchor; - } else { - startRow = selectRowAnchor; - startCol = selectColAnchor; - endRow = selectRowLast; - endCol = selectColLast; - } - - StringBuffer result = new StringBuffer(); - - if(startRow != endRow) { - for(i = startCol; i < cols; i++) { - if(screen[startRow][i] == 0) { - n = nextPrintedChar(startRow, i); - result.append(addSpaces(i, n)); - i = n - 1; - } else - result.append(screen[startRow][i]); - } - if(i == cols) - result.append(eol); - for(i = startRow + 1; i < endRow; i++) { - for(j = 0; j < cols; j++) { - if(screen[i][j] == 0) { - n = nextPrintedChar(i, j); - result.append(addSpaces(j, n)); - j = n - 1; - } else - result.append(screen[i][j]); - } - result.append(eol); - } - for(i = 0; i <= endCol; i++) { - if(screen[endRow][i] == 0) { - n = nextPrintedChar(endRow, i); - result.append(addSpaces(i, n)); - i = n - 1; - } else - result.append(screen[endRow][i]); - } - if(i == cols) - result.append(eol); - } else { - for(i = startCol; i <= endCol; i++) { - if(screen[startRow][i] == 0) { - n = nextPrintedChar(startRow, i); - result.append(addSpaces(i, n)); - i = n - 1; - } else - result.append(screen[startRow][i]); - } - if(i == cols) - result.append(eol); - } - - return result.toString(); - } - - public void doClickSelect(int row, int col) { - if(selectClickRow == row && selectClickState) { - selectColAnchor = 0; - selectColLast = cols - 1; - } else { - int i; - if(screen[row][col] != 0) { - for(i = col; i >= 0; i--) - if((selectDelims.indexOf(screen[row][i]) != -1) || screen[row][i] == 0) - break; - selectColAnchor = i + 1; - for(i = col; i < cols ; i++) - if((selectDelims.indexOf(screen[row][i]) != -1) || screen[row][i] == 0) - break; - selectColLast = i - 1; - } else { - selectColAnchor = prevPrintedChar(row, col) + 1; - selectColLast = nextPrintedChar(row, col) - 1; - } - selectColAnchor = (selectColAnchor > col ? col : selectColAnchor); - selectColLast = (selectColLast < col ? col : selectColLast); - } - selectClickState = !selectClickState; - selectClickRow = row; - selectRowAnchor = row; - selectRowLast = row; - selectReverse = false; - hasSelection = true; - makeSelection(selectRowAnchor, selectColAnchor, selectRowLast, selectColLast); - } - public void doCopy() { - if(clipboard != null) { - clipboard.setSelection(getSelection()); - } - } - public void doPaste() { - if(clipboard != null) { - String selection = clipboard.getSelection(); - if(selection != null) { - if(termOptions[OPT_LOCAL_ECHO]) - write(selection); - sendBytes(selection.getBytes()); - } - } - } - - // - // Methods overridden from super-class Component + some helper functions - // - - // !!! TODO: Move the char* init stuff out of this to a separate method - // - public Dimension getDimensionOfText(int rows, int cols) { - FontMetrics fm = getFontMetrics(getFont()); - charWidth = -1; // !!! Does not seem to work: fm.getMaxAdvance(); - charHeight = fm.getHeight(); - charMaxAscent = fm.getMaxAscent(); - charMaxDescent = fm.getMaxDescent(); - charLeading = fm.getLeading(); - baselineIndex = charMaxAscent + charLeading - 1; - - if(charWidth == -1) - charWidth = fm.charWidth('W'); - - return new Dimension((cols * charWidth) + (2 * borderHeight), - (rows * charHeight) + (2 * borderWidth)); - } - - public Dimension getPreferredSize() { - Dimension dim = getDimensionOfText(rows, cols); - if(DEBUG) System.out.println("getPreferredSize " + cols + "x" + rows + "(" + dim + ")"); - return dim; - } - - public Dimension getMinimumSize() { - return getDimensionOfText(MIN_ROWS, MIN_COLS); - } - - public Dimension getMaximumSize() { - return getDimensionOfText(MAX_ROWS, MAX_COLS); - } - - protected final void clearDirtyArea(Graphics source, Graphics dest) { - boolean clearAll = (dirtyLeft == 0 && - dirtyRight == cols && - dirtyTop == 0 && - dirtyBottom == rows); - int x, y, w, h; - - if(clearAll) { - Dimension dim = getSize(); - x = 0; - y = 0; - w = dim.width; - h = dim.height; - } else { - x = borderWidth + (charWidth * dirtyLeft); - y = borderHeight + (dirtyTop * charHeight); - w = (charWidth * (dirtyRight - dirtyLeft)); - h = (charHeight * (dirtyBottom - dirtyTop)); - } - - source.setColor(origBgColor); - source.fillRect(x, y, w, h); - source.setColor(origFgColor); - dest.setClip(x, y, w, h); - } - - public void repaint() { - if(!repaintPending && isShowing() && !pendingShow) { - super.repaint(); - repaintPending = true; - } - } - - public void paint(Graphics g) { - update(g); - } - - final Rectangle getClipRect(Graphics g) { - Rectangle clipRect = g.getClipBounds(); - if(clipRect == null) { - Dimension winSize = getSize(); - clipRect = new Rectangle(0, 0, winSize.width, winSize.height); - } - return clipRect; - } - - boolean waitForMore = false; - boolean insideUpdate = false; // Kludge to avoid endless loop in pathological case... - - synchronized public void update(Graphics g) { - Rectangle clipRect; - int x; - int y; - - // !!! This should not happen but better safe than sorry... - // - if(hpixels == 0 || vpixels == 0) { - Dimension dim = getSize(); - vpixels = dim.height; - hpixels = dim.width; - if(hpixels == 0 || vpixels == 0) - return; - } - - int wcnt = 1; - while(waitForMore) { - waitForMore = false; - try { - this.wait(wcnt * 25); - } catch (InterruptedException e) { - } - if(wcnt++ > 3) - waitForMore = false; - } - - if((memGraphics == null) || - (memImageSize == null) || - (hpixels != memImageSize.width) || - (vpixels != memImageSize.height)) { - memImageSize = new Dimension(hpixels, vpixels); - memImage = createImage(hpixels, vpixels); - } - memGraphics = memImage.getGraphics(); - - if(!repaintPending) { - // If we we don't have a repaint pending the cause for update must be "destroyed" - // window content. - // - dirtyTop = 0; - dirtyBottom = rows; - dirtyLeft = 0; - dirtyRight = cols; - clipRect = getClipRect(g); - memGraphics.setClip(clipRect.x, clipRect.y, clipRect.width, clipRect.height); - memGraphics.setColor(origBgColor); - memGraphics.fillRect(clipRect.x, clipRect.y, clipRect.width, clipRect.height); - memGraphics.setColor(origFgColor); - } else { - if(dirtyTop == rows) - dirtyTop = curRow; - if(dirtyBottom == 0) - dirtyBottom = curRow + 1; - if(dirtyRight == 0) - dirtyRight = curCol + 1; - if(dirtyLeft == cols) - dirtyLeft = curCol; - clearDirtyArea(memGraphics, g); - clipRect = getClipRect(g); - } - - int[] attrRow; - char[] charRow; - int attr; - int attrMasked; - for(int i = dirtyTop; i < dirtyBottom; i++) { - y = borderHeight + (i * charHeight); - attrRow = attributes[visTop + i]; - charRow = screen[visTop + i]; - for(int j = dirtyLeft; j < dirtyRight; j++) { - attr = attrRow[j]; - attrMasked = (attr & MASK_ATTR); - // Skip positions not drawn into - if(attrMasked == ATTR_CHARNOTDRAWN) - continue; - x = borderWidth + (charWidth * j); - if(((attr & ATTR_INVERSE) != 0) ^ ((attr & ATTR_SELECTED) != 0)) { - if((attr & ATTR_FGCOLOR) != 0) { - memGraphics.setColor(termColors[(attr & MASK_FGCOL) >>> SHIFT_FGCOL]); - } - memGraphics.fillRect(x, y, charWidth, charHeight); - if((attr & ATTR_BGCOLOR) != 0) { - memGraphics.setColor(termColors[(attr & MASK_BGCOL) >>> SHIFT_BGCOL]); - } else { - memGraphics.setColor(origBgColor); - } - } else { - if((attr & ATTR_BGCOLOR) != 0) { - memGraphics.setColor(termColors[(attr & MASK_BGCOL) >>> SHIFT_BGCOL]); - memGraphics.fillRect(x, y, charWidth, charHeight); - memGraphics.setColor(origFgColor); - } - if((attr & ATTR_FGCOLOR) != 0) { - memGraphics.setColor(termColors[(attr & MASK_FGCOL) >>> SHIFT_FGCOL]); - } - } - if((attrMasked & ATTR_CHARDRAWN) != 0) { - if((attr & ATTR_LINEDRAW) != 0) { - drawLineDrawChar(memGraphics, x, y, baselineIndex, charRow[j]); - } else if((attr & ATTR_BOLD) != 0) { - memGraphics.setFont(boldFont); - memGraphics.drawChars(charRow, j, 1, x, y + baselineIndex); - memGraphics.setFont(plainFont); - } else { - memGraphics.drawChars(charRow, j, 1, x, y + baselineIndex); - } - if((attr & ATTR_UNDERLINE) != 0) - memGraphics.drawLine(x, y + baselineIndex, x + charWidth, y + baselineIndex); - } - memGraphics.setColor(origFgColor); - } - } - - g.drawImage(memImage, 0, 0, this); - - Rectangle cursor = new Rectangle(borderWidth + (charWidth * lastCursorCol), - borderHeight + (lastCursorRow * charHeight), - charWidth, charHeight); - if(!clipRect.intersects(cursor)) { - g.setClip(0, 0, hpixels, vpixels); - hideCursor(g); - } else { - Rectangle intersection = clipRect.intersection(cursor); - g.setClip(0, 0, hpixels, vpixels); - if(!intersection.equals(cursor) && !insideUpdate) { - // !!! Argh, this is no fun, better repaint it... - g.setColor(origBgColor); - g.fillRect(0, 0, hpixels, vpixels); - g.setColor(origFgColor); - insideUpdate = true; - update(g); - insideUpdate = false; - return; - } - } - showCursor(g); - - if(logoDraw && logoImg != null) { - x = logoX; - y = logoY; - if(x == -1) { - x = (hpixels / 2) - (logoW / 2); - } - if(y == -1) { - y = (vpixels / 2) - (logoH / 2); - } - g.drawImage(logoImg, x, y, logoW, logoH, this); - } - - // Reset dirty area (i.e. nothing is dirty now) - // - repaintPending = false; - dirtyTop = rows; - dirtyBottom = 0; - dirtyLeft = cols; - dirtyRight = 0; - } - - final synchronized void hideCursor(Graphics g) { - // Hide last drawn cursor - // - if(cursorDrawn) { - int x = borderWidth + (charWidth * lastCursorCol); - int y = borderHeight + (lastCursorRow * charHeight); - if((attributes[visTop + lastCursorRow][lastCursorCol] & ATTR_INVERSE) != 0) - g.setColor(origFgColor); - else - g.setColor(origBgColor); - g.setXORMode(cursorColor); - if(cursorHollow) { - g.drawRect(x, y, charWidth, charHeight - 1); - } else { - g.fillRect(x, y, charWidth, charHeight); - } - g.setColor(origFgColor); - g.setPaintMode(); - cursorDrawn = false; - } - } - - final synchronized void showCursor(Graphics g) { - // Show current cursor - // - if(termOptions[OPT_VIS_CURSOR] && curCol < cols && curRow < rows) { - int x = borderWidth + (charWidth * curCol); - int y = borderHeight + (curRow * charHeight); - g.setColor(cursorColor); - if((attributes[visTop + curRow][curCol] & ATTR_INVERSE) != 0) - g.setXORMode(origFgColor); - else - g.setXORMode(origBgColor); - if(haveFocus) { - g.fillRect(x, y, charWidth, charHeight); - cursorHollow = false; - } else { - g.drawRect(x, y, charWidth, charHeight - 1); - cursorHollow = true; - } - g.setPaintMode(); - cursorDrawn = true; - lastCursorRow = curRow; - lastCursorCol = curCol; - } - } - - /* - Glyph ACS Ascii VT100 - Name Name Default Name - UK pound sign ACS_STERLING f } - arrow pointing down ACS_DARROW v . - arrow pointing left ACS_LARROW < , - arrow pointing right ACS_RARROW > + - arrow pointing up ACS_UARROW ^ - - board of squares ACS_BOARD # h - bullet ACS_BULLET o ~ - checker board (stipple) ACS_CKBOARD : a - degree symbol ACS_DEGREE \ f - diamond ACS_DIAMOND + ` - greater-than-or-equal-to ACS_GEQUAL > z - greek pi ACS_PI * { - horizontal line ACS_HLINE - q - lantern symbol ACS_LANTERN # i - large plus or crossover ACS_PLUS + n - less-than-or-equal-to ACS_LEQUAL < y - lower left corner ACS_LLCORNER + m - lower right corner ACS_LRCORNER + j - not-equal ACS_NEQUAL ! | - plus/minus ACS_PLMINUS # g - scan line 1 ACS_S1 ~ o - scan line 3 ACS_S3 - p - scan line 7 ACS_S7 - r - scan line 9 ACS_S9 _ s - solid square block ACS_BLOCK # 0 - tee pointing down ACS_TTEE + w - tee pointing left ACS_RTEE + u - tee pointing right ACS_LTEE + t - tee pointing up ACS_BTEE + v - upper left corner ACS_ULCORNER + l - upper right corner ACS_URCORNER + k - vertical line ACS_VLINE | x - */ - - final void drawLineDrawChar(Graphics g, int x, int y, int bi, char c) { - int x2 = (x + (charWidth / 2)); - int y2 = (y + (charHeight / 2)); - int xx = (x + charWidth); - int yy = (y + charHeight); - - switch(c) { - case ' ': // Blank - case '_': // Blank - break; - case '}': // UK pound - { - char[] ca = new char[1]; - ca[0] = (char)0x00a3; - g.drawChars(ca, 0, 1, x, y + bi); - break; - } - case '.': // Down arrow - break; - case ',': // Left arrow - break; - case '+': // Right arrow - break; - case '-': // Up arrow - break; - case 'h': // Board of squares - break; - case '~': // Bullet - break; - case 'a': // Checker board (stipple) - break; - case 'f': // Degrees - { - char[] ca = new char[1]; - ca[0] = (char)0x00b0; - g.drawChars(ca, 0, 1, x, y + bi); - break; - } - case '`': // Diamond - int[] polyX = new int[4]; - int[] polyY = new int[4]; - polyX[0] = x2; - polyY[0] = y; - polyX[1] = xx; - polyY[1] = y2; - polyX[2] = x2; - polyY[2] = yy; - polyX[3] = x; - polyY[3] = y2; - g.fillPolygon(polyX, polyY, 4); - break; - case 'z': // Greater than or equal - break; - case '{': // Pi - break; - case 'i': // Lantern - break; - case 'y': // Less than or equal - break; - case '|': // Not equal - break; - case 'g': // Plus/Minus - { - char[] ca = new char[1]; - ca[0] = (char)0x00b1; - g.drawChars(ca, 0, 1, x, y + bi); - break; - } - case 'o': // Horizontal line (top) - g.drawLine(x, y, xx, y); - break; - case 'p': // Horizontal line (top-half) - break; - case 'r': // Horizontal line (bottom-half) - break; - case 's': // Horizontal line (bottom) - g.drawLine(x, yy, xx, yy); - break; - case '0': // Solid square block - break; - case 'l': // Upper left corner - g.drawLine(x2, yy, x2, y2); - g.drawLine(x2, y2, xx, y2); - break; - case 'k': // Upper right corner - g.drawLine(x, y2, x2, y2); - g.drawLine(x2, y2, x2, yy); - break; - case 'm': // Lower left corner - g.drawLine(x2, y, x2, y2); - g.drawLine(x2, y2, xx, y2); - break; - case 'j': // Lower right corner - g.drawLine(x2, y, x2, y2); - g.drawLine(x2, y2, x, y2); - break; - case 'q': // Horizontal line (center) - g.drawLine(x, y2, xx, y2); - break; - case 'x': // Vertical line - g.drawLine(x2, y, x2, yy); - break; - case 'n': // Cross center lines - g.drawLine(x2, y, x2, yy); - g.drawLine(x, y2, xx, y2); - break; - case 'u': // Right tee - g.drawLine(x2, y, x2, yy); - g.drawLine(x, y2, x2, y2); - break; - case 't': // Left tee - g.drawLine(x2, y, x2, yy); - g.drawLine(x2, y2, xx, y2); - break; - case 'v': // Bottom tee - g.drawLine(x, y2, xx, y2); - g.drawLine(x2, y2, x2, y); - break; - case 'w': // Top tee - g.drawLine(x, y2, xx, y2); - g.drawLine(x2, y2, x2, yy); - break; - default: - if(DEBUG) System.out.println("Unknown line-draw-char: " + c + " (" + ((int)c) + ")"); - break; - } - } - - /* !!! Do we want this? Check Mac once again, this was for buggy AWT - class FixedScrollbar extends Scrollbar { - protected boolean onRight = true; - - public FixedScrollbar(int orientation) { - super(orientation); - } - - public void setBounds(Rectangle r) { - reshape(r.x, r.y, r.width, r.height); - } - - public void setBounds(int x, int y, int width, int height) { - reshape(x, y, width, height); - } - - // use the deprecated version, because some things still call it - public void reshape(int x, int y, int width, int height) { - if(onRight) { - x++; // under window frame - height++; // can overlap with size box - } else { - x--; // under window frame - } - - y--; // under title bar - height++; // compensate on bottom - super.reshape(x, y, width, height); - } - - public void setWindowSide(String sb) { - onRight = sb.equals("right"); - } - - } - */ - -} diff --git a/src/main/java/com/mindbright/terminal/TerminalXTerm.java b/src/main/java/com/mindbright/terminal/TerminalXTerm.java deleted file mode 100644 index 8fbc7cc..0000000 --- a/src/main/java/com/mindbright/terminal/TerminalXTerm.java +++ /dev/null @@ -1,5431 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -/* - * Author's comment: The contents of this file is heavily based upon - * xterm from the X Consortium, original copyright notices included - * below. - */ -/* -Copyright (c) 1988 X Consortium - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the X Consortium shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from the X Consortium. - -*/ -/* - * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - * - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation, and that the name of Digital Equipment - * Corporation not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior permission. - * - * - * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ -package com.mindbright.terminal; - -import java.util.NoSuchElementException; -import java.awt.event.KeyEvent; -import java.awt.event.InputEvent; - -public final class TerminalXTerm extends TerminalInterpreter { - - // !!! Set to true for extensive debug - // - public final static boolean DEBUG = false; - public final static boolean DEBUGNOTIMPL = false; - public final static boolean DEBUGPRINT = false; - - public final static int CASE_GROUND_STATE = 0; - public final static int CASE_IGNORE_STATE = 1; - public final static int CASE_IGNORE_ESC = 2; - public final static int CASE_IGNORE = 3; - public final static int CASE_BELL = 4; - public final static int CASE_BS = 5; - public final static int CASE_CR = 6; - public final static int CASE_ESC = 7; - public final static int CASE_VMOT = 8; - public final static int CASE_TAB = 9; - public final static int CASE_SI = 10; - public final static int CASE_SO = 11; - public final static int CASE_SCR_STATE = 12; - public final static int CASE_SCS0_STATE = 13; - public final static int CASE_SCS1_STATE = 14; - public final static int CASE_SCS2_STATE = 15; - public final static int CASE_SCS3_STATE = 16; - public final static int CASE_ESC_IGNORE = 17; - public final static int CASE_ESC_DIGIT = 18; - public final static int CASE_ESC_SEMI = 19; - public final static int CASE_DEC_STATE = 20; - public final static int CASE_ICH = 21; - public final static int CASE_CUU = 22; - public final static int CASE_CUD = 23; - public final static int CASE_CUF = 24; - public final static int CASE_CUB = 25; - public final static int CASE_CUP = 26; - public final static int CASE_ED = 27; - public final static int CASE_EL = 28; - public final static int CASE_IL = 29; - public final static int CASE_DL = 30; - public final static int CASE_DCH = 31; - public final static int CASE_DA1 = 32; - public final static int CASE_TRACK_MOUSE = 33; - public final static int CASE_TBC = 34; - public final static int CASE_SET = 35; - public final static int CASE_RST = 36; - public final static int CASE_SGR = 37; - public final static int CASE_CPR = 38; - public final static int CASE_DECSTBM = 39; - public final static int CASE_DECREQTPARM = 40; - public final static int CASE_DECSET = 41; - public final static int CASE_DECRST = 42; - public final static int CASE_DECALN = 43; - public final static int CASE_GSETS = 44; - public final static int CASE_DECSC = 45; - public final static int CASE_DECRC = 46; - public final static int CASE_DECKPAM = 47; - public final static int CASE_DECKPNM = 48; - public final static int CASE_IND = 49; - public final static int CASE_NEL = 50; - public final static int CASE_HTS = 51; - public final static int CASE_RI = 52; - public final static int CASE_SS2 = 53; - public final static int CASE_SS3 = 54; - public final static int CASE_CSI_STATE = 55; - public final static int CASE_OSC = 56; - public final static int CASE_RIS = 57; - public final static int CASE_LS2 = 58; - public final static int CASE_LS3 = 59; - public final static int CASE_LS3R = 60; - public final static int CASE_LS2R = 61; - public final static int CASE_LS1R = 62; - public final static int CASE_PRINT = 63; - public final static int CASE_XTERM_SAVE = 64; - public final static int CASE_XTERM_RESTORE = 65; - public final static int CASE_XTERM_TITLE = 66; - public final static int CASE_DECID = 67; - public final static int CASE_HP_MEM_LOCK = 68; - public final static int CASE_HP_MEM_UNLOCK = 69; - public final static int CASE_HP_BUGGY_LL = 70; - public final static int CASE_SEQ_CAPTURE = 71; - public final static int CASE_ESC_SEMIOSC = 72; - public final static int CASE_XTERM_SEQ = 73; - public final static int CASE_ENQ = 74; - public final static int CASE_XTERMWIN = 75; - public final static int CASE_CNL = 76; - public final static int CASE_CPL = 77; - public final static int CASE_CHA = 78; - public final static int CASE_CHT = 79; - public final static int CASE_SU = 80; - public final static int CASE_SD = 81; - public final static int CASE_ECH = 82; - public final static int CASE_CBT = 83; - public final static int CASE_HPA = 84; - public final static int CASE_REP = 85; - public final static int CASE_VPA = 86; - - public final static int[] asciiLineDrawChars = { - ' ', // 0x5f - _ - '+', // 0x60 - ` - ':', // 0x61 - a - ' ', // 0x62 - b - ' ', // 0x63 - c - ' ', // 0x64 - d - ' ', // 0x65 - e - '\\', // 0x66 - f - '#', // 0x67 - g - '#', // 0x68 - h - '#', // 0x69 - i - '+', // 0x6a - j - '+', // 0x6b - k - '+', // 0x6c - l - '+', // 0x6d - m - '+', // 0x6e - n - '~', // 0x6f - o - '-', // 0x70 - p - '-', // 0x71 - q - '-', // 0x72 - r - '_', // 0x73 - s - '+', // 0x74 - t - '+', // 0x75 - u - '+', // 0x76 - v - '+', // 0x77 - w - '|', // 0x78 - x - '<', // 0x79 - y - '>', // 0x7a - z - '*', // 0x7b - { - '!', // 0x7c - | - 'f', // 0x7d - } - 'o', // 0x7e - ~ - - '>', // 0x2b - + - '<', // 0x2c - , - '^', // 0x2d - - - 'v', // 0x2e - . - }; - - public final static int XVK_UP = 0; - public final static int XVK_DOWN = 1; - public final static int XVK_RIGHT = 2; - public final static int XVK_LEFT = 3; - public final static int XVK_PAGE_UP = 4; - public final static int XVK_PAGE_DOWN = 5; - public final static int XVK_END = 6; - public final static int XVK_HOME = 7; - public final static int XVK_INSERT = 8; - public final static int XVK_F1 = 9; - public final static int XVK_F2 = 10; - public final static int XVK_F3 = 11; - public final static int XVK_F4 = 12; - public final static int XVK_F5 = 13; - public final static int XVK_F6 = 14; - public final static int XVK_F7 = 15; - public final static int XVK_F8 = 16; - public final static int XVK_F9 = 17; - public final static int XVK_F10 = 18; - public final static int XVK_F11 = 19; - public final static int XVK_F12 = 20; - public final static int XVK_NUMPAD0 = 21; - public final static int XVK_NUMPAD1 = 22; - public final static int XVK_NUMPAD2 = 23; - public final static int XVK_NUMPAD3 = 24; - public final static int XVK_NUMPAD4 = 25; - public final static int XVK_NUMPAD5 = 26; - public final static int XVK_NUMPAD6 = 27; - public final static int XVK_NUMPAD7 = 28; - public final static int XVK_NUMPAD8 = 29; - public final static int XVK_NUMPAD9 = 30; - public final static int XVK_MULTIPLY = 31; - public final static int XVK_ADD = 32; - public final static int XVK_SUBTRACT = 33; - public final static int XVK_DIVIDE = 34; - public final static int XVK_MAX = 35; - - public final int[] vk2xvk = { - KeyEvent.VK_UP, - KeyEvent.VK_DOWN, - KeyEvent.VK_RIGHT, - KeyEvent.VK_LEFT, - KeyEvent.VK_PAGE_UP, - KeyEvent.VK_PAGE_DOWN, - KeyEvent.VK_END, - KeyEvent.VK_HOME, - KeyEvent.VK_INSERT, - KeyEvent.VK_F1, - KeyEvent.VK_F2, - KeyEvent.VK_F3, - KeyEvent.VK_F4, - KeyEvent.VK_F5, - KeyEvent.VK_F6, - KeyEvent.VK_F7, - KeyEvent.VK_F8, - KeyEvent.VK_F9, - KeyEvent.VK_F10, - KeyEvent.VK_F11, - KeyEvent.VK_F12, - KeyEvent.VK_NUMPAD0, - KeyEvent.VK_NUMPAD1, - KeyEvent.VK_NUMPAD2, - KeyEvent.VK_NUMPAD3, - KeyEvent.VK_NUMPAD4, - KeyEvent.VK_NUMPAD5, - KeyEvent.VK_NUMPAD6, - KeyEvent.VK_NUMPAD7, - KeyEvent.VK_NUMPAD8, - KeyEvent.VK_NUMPAD9, - KeyEvent.VK_MULTIPLY, - KeyEvent.VK_ADD, - KeyEvent.VK_SUBTRACT, - KeyEvent.VK_DIVIDE, - }; - - public final static int EMUL_XTERM = 0; - public final static int EMUL_LINUX = 1; - public final static int EMUL_SCOANSI = 2; - public final static int EMUL_ATT6386 = 3; - public final static int EMUL_SUN = 4; - public final static int EMUL_AIX = 5; - public final static int EMUL_VT220 = 6; - public final static int EMUL_VT100 = 7; - public final static int EMUL_ANSI = 8; - public final static int EMUL_VT52 = 9; - - public final static int EMUL_ALTERNATENAME = 10; - public final static int EMUL_XTERMCOL = EMUL_ALTERNATENAME + EMUL_XTERM; - public final static int EMUL_LINUXLAT = EMUL_ALTERNATENAME + EMUL_LINUX; - public final static int EMUL_AT386 = EMUL_ALTERNATENAME + EMUL_ATT6386; - public final static int EMUL_VT102 = EMUL_ALTERNATENAME + EMUL_VT100; - public final static int EMUL_VT320 = EMUL_ALTERNATENAME + EMUL_VT220; - - public final static boolean hasNullPadding(int personality) { - if(personality == EMUL_VT220 || - personality == EMUL_VT100 || - personality == EMUL_ANSI || - personality == EMUL_VT52) - return true; - return false; - } - - public final static int DEFAULT_TERM = EMUL_XTERM; - - public final static String[] terminalTypes = { - "xterm", "linux", "scoansi", "att6386", "sun", "aixterm", - "vt220", "vt100", "ansi", "vt52", - - "xterm-color", "linux-lat", "", "at386", "", "", "vt320", "vt102" - }; - - int whoAmI; - int whoAmIReally; - - public final static String[][] specialKeyMap = { - //xterm linux scoansi att6386 sun aixterm vt220 vt100 ansi vt52 - { "A", "A", "A", "A", "A", "A", "A", "A", "A", "A" }, - { "B", "B", "B", "B", "B", "B", "B", "B", "B", "B" }, - { "C", "C", "C", "C", "C", "C", "C", "C", "C", "C" }, - { "D", "D", "D", "D", "D", "D", "D", "D", "D", "D" }, - - { "5~", "5~", "I", "V", "216z", "150q", "5~", "5~", "5~", "5~" }, - { "6~", "6~", "G", "U", "222z", "154q", "6~", "6~", "6~", "6~" }, - { "F", "4~", "F", "Y", "220z", "146q", "4~", "4~", "4~", "4~" }, - { "H", "1~", "H", "H", "214z", "H", "1~", "1~", "1~", "1~" }, - { "2~", "2~", "L", "@", "2~", "139q", "2~", "2~", "L", "L" }, - - { "11~", "[A", "M", "P", "224z", "001q", "P", "P", "P", "P" }, - { "12~", "[B", "N", "Q", "225z", "002q", "Q", "Q", "Q", "Q" }, - { "13~", "[C", "O", "R", "226z", "003q", "R", "R", "R", "R" }, - { "14~", "[D", "P", "S", "227z", "004q", "S", "S", "S", "S" }, - { "15~", "[E", "Q", "T", "228z", "005q", "17~", null, null, null }, - { "17~", "17~", "R", "U", "229z", "006q", "18~", null, null, null }, - { "18~", "18~", "S", "V", "230z", "007q", "19~", null, null, null }, - { "19~", "19~", "T", "W", "231z", "008q", "20~", null, null, null }, - { "20~", "20~", "U", "X", "232z", "009q", "21~", null, null, null }, - { "21~", "21~", "V", "Y", "233z", "010q", "29~", null, null, null }, - { "23~", "23~", null, "Z", "234z", "011q", null, null, null, null }, - { "24~", "24~", null, "A", "235z", "012q", null, null, null, null }, - - // !!! NUMPAD missing, this is not trivial given java's messy so called virtual keys... :-( - }; - - public final static String[][] specialKeyMapShift = { - //xterm linux scoansi att6386 sun aixterm vt220 vt100 ansi vt52 - { "A", "A", "A", "A", "A", "A", "A", "A", "A", "A" }, - { "B", "B", "B", "B", "B", "B", "B", "B", "B", "B" }, - { "C", "C", "C", "C", "C", "C", "C", "C", "C", "C" }, - { "D", "D", "D", "D", "D", "D", "D", "D", "D", "D" }, - - { "5~", "5~", "I", "V", "216z", "150q", "5~", "5~", "5~", "5~" }, - { "6~", "6~", "G", "U", "222z", "154q", "6~", "6~", "6~", "6~" }, - { "4~", "4~", "F", "Y", "220z", "146q", "4~", "4~", "4~", "4~" }, - { "@", "1~", "H", "H", "214z", "H", "1~", "1~", "1~", "1~" }, - { "2~", "2~", "L", "@", "2~", "139q", "2~", "2~", "L", "L" }, - - { "23~", "23~", "M", "P", "224z", "013q", "P", "P", "P", "P" }, - { "24~", "24~", "N", "Q", "225z", "014q", "Q", "Q", "Q", "Q" }, - { "25~", "25~", "O", "R", "226z", "015q", "R", "R", "R", "R" }, - { "26~", "26~", "P", "S", "227z", "016q", "S", "S", "S", "S" }, - { "28~", "28~", "Q", "T", "228z", "017q", "17~", null, null, null }, - { "29~", "29~", "R", "U", "229z", "018q", "18~", null, null, null }, - { "31~", "31~", "S", "V", "230z", "019q", "19~", null, null, null }, - { "32~", "32~", "T", "W", "231z", "020q", "20~", null, null, null }, - { "33~", "33~", "U", "X", "232z", "021q", "21~", null, null, null }, - { "34~", "34~", "V", "Y", "233z", "022q", "29~", null, null, null }, - { "23$", null, null, "Z", "234z", "023q", null, null, null, null }, - { "24$", null, null, "A", "235z", "024q", null, null, null, null }, - - // !!! NUMPAD missing, this is not trivial given java's messy so called virtual keys... :-( - }; - - public final static String[][] specialKeyMapCtrl = { - //xterm linux scoansi att6386 sun aixterm vt220 vt100 ansi vt52 - { "A", "A", "A", "A", "A", "A", "A", "A", "A", "A" }, - { "B", "B", "B", "B", "B", "B", "B", "B", "B", "B" }, - { "C", "C", "C", "C", "C", "C", "C", "C", "C", "C" }, - { "D", "D", "D", "D", "D", "D", "D", "D", "D", "D" }, - - { "5~", "5~", "I", "V", "216z", "150q", "5~", "5~", "5~", "5~" }, - { "6~", "6~", "G", "U", "222z", "154q", "6~", "6~", "6~", "6~" }, - { "4~", "4~", "F", "Y", "220z", "146q", "4~", "4~", "4~", "4~" }, - { "@", "1~", "H", "H", "214z", "H", "1~", "1~", "1~", "1~" }, - { "2~", "2~", "L", "@", "2~", "139q", "2~", "2~", "L", "L" }, - - { "11^", null, "M", "P", "224z", "025q", "P", "P", "P", "P" }, - { "12^", null, "N", "Q", "225z", "026q", "Q", "Q", "Q", "Q" }, - { "13^", null, "O", "R", "226z", "027q", "R", "R", "R", "R" }, - { "14^", null, "P", "S", "227z", "028q", "S", "S", "S", "S" }, - { "15^", null, "Q", "T", "228z", "029q", "17~", null, null, null }, - { "17^", null, "R", "U", "229z", "030q", "18~", null, null, null }, - { "18^", null, "S", "V", "230z", "031q", "19~", null, null, null }, - { "19^", null, "T", "W", "231z", "032q", "20~", null, null, null }, - { "20^", null, "U", "X", "232z", "033q", "21~", null, null, null }, - { "21^", null, "V", "Y", "233z", "034q", "29~", null, null, null }, - { "23^", null, null, "Z", "234z", "035q", null, null, null, null }, - { "24^", null, null, "A", "235z", "036q", null, null, null, null }, - - // !!! NUMPAD missing, this is not trivial given java's messy so called virtual keys... :-( - }; - - public final static String[][] specialKeyMapCtrlShift = { - //xterm linux scoansi att6386 sun aixterm vt220 vt100 ansi vt52 - { "A", "A", "A", "A", "A", "A", "A", "A", "A", "A" }, - { "B", "B", "B", "B", "B", "B", "B", "B", "B", "B" }, - { "C", "C", "C", "C", "C", "C", "C", "C", "C", "C" }, - { "D", "D", "D", "D", "D", "D", "D", "D", "D", "D" }, - - { "5~", "5~", "I", "V", "216z", "150q", "5~", "5~", "5~", "5~" }, - { "6~", "6~", "G", "U", "222z", "154q", "6~", "6~", "6~", "6~" }, - { "4~", "4~", "F", "Y", "220z", "146q", "4~", "4~", "4~", "4~" }, - { "@", "1~", "H", "H", "214z", "H", "1~", "1~", "1~", "1~" }, - { "2~", "2~", "L", "@", "2~", "139q", "2~", "2~", "L", "L" }, - - { "23^", null, "M", "P", "224z", "001q", "P", "P", "P", "P" }, - { "24^", null, "N", "Q", "225z", "002q", "Q", "Q", "Q", "Q" }, - { "25^", null, "O", "R", "226z", "003q", "R", "R", "R", "R" }, - { "26^", null, "P", "S", "227z", "004q", "S", "S", "S", "S" }, - { "28^", null, "Q", "T", "228z", "005q", "17~", null, null, null }, - { "29^", null, "R", "U", "229z", "006q", "18~", null, null, null }, - { "31^", null, "S", "V", "230z", "007q", "19~", null, null, null }, - { "32^", null, "T", "W", "231z", "008q", "20~", null, null, null }, - { "33^", null, "U", "X", "232z", "009q", "21~", null, null, null }, - { "34^", null, "V", "Y", "233z", "010q", "29~", null, null, null }, - { "23@", null, null, "Z", "234z", "011q", null, null, null, null }, - { "24@", null, null, "A", "235z", "012q", null, null, null, null }, - - // !!! NUMPAD missing, this is not trivial given java's messy so called virtual keys... :-( - }; - - public final static String[][][] theSpecialKeyMaps = { - specialKeyMap, - specialKeyMapShift, - specialKeyMapCtrl, - specialKeyMapCtrlShift - }; - - public final static int R_ESC = 0; - public final static int R_SS2 = 1; - public final static int R_SS3 = 2; - public final static int R_DCS = 3; - public final static int R_CSI = 4; - public final static int R_OSC = 5; - public final static int R_PM = 6; - public final static int R_APC = 7; - - public final static String[] replyTypes = { - "\033", - "\033N", - "\033O", - "\033P", - "\033[", - "\033]", - "\033^", - "\033_", - }; - - public final static char CHARSET_UK = 'A'; - public final static char CHARSET_ASCII = 'B'; - public final static char CHARSET_LINES = '0'; - public final static char CHARSET_ASCII_ALT = '1'; - public final static char CHARSET_LINES_ALT = '2'; - - char[] gSets = new char[4]; - int scsType; - int curGL; - int curSS; - - int curGLDECSC; - char[] gSetsDECSC = new char[4]; - - String xtermSeq = null; - String reply = null; - - public final static int PARAMNOTUSED = -1; - - int[] parseState; - - boolean windowRelative; - boolean keypadAppl; - - boolean cursorKeysMode; - - public final static int MOUSE_DONTSEND = 0; - public final static int MOUSE_X10COMP = 1; - public final static int MOUSE_DECVT200 = 2; - public final static int MOUSE_HLTRACK = 3; - int sendMousePos; - - int[] param = new int[10]; - int nparam ; - - public TerminalXTerm() { - this(DEFAULT_TERM); - } - - public TerminalXTerm(int personality) { - try { - setTerminalTypeInternal(personality); - } catch (NoSuchElementException e) { - try { - setTerminalTypeInternal(DEFAULT_TERM); - } catch (NoSuchElementException ee) { - // !!! Can't happen... - } - } - } - - public static String listAvailableTerminalTypes() { - int i; - String list = " "; - for(i = 0; i < terminalTypes.length; i++) - list += terminalTypes[i] + " "; - return list; - } - - public static String[] getTerminalTypes() { - int i, n = 0; - for(i = 0; i < terminalTypes.length; i++) - if(!terminalTypes[i].equals("")) - n++; - - String[] types = new String[n]; - - n = 0; - for(i = 0; i < terminalTypes.length; i++) - if(!terminalTypes[i].equals("")) - types[n++] = terminalTypes[i]; - - return types; - } - - public String terminalType() { - return terminalTypes[whoAmI]; - } - - private void setTerminalTypeInternal(int type) throws NoSuchElementException { - if(type < terminalTypes.length && type > -1) { - whoAmI = type; - whoAmIReally = type; - if(whoAmI >= EMUL_ALTERNATENAME) - whoAmIReally -= EMUL_ALTERNATENAME; - vtReset(); - } else { - throw new NoSuchElementException(type + " is not a supported terminal-emulation"); - } - } - - protected void setTerminalType(String type) throws NoSuchElementException { - int i; - for(i = 0; i < terminalTypes.length; i++) - if(terminalTypes[i].equalsIgnoreCase(type)) - break; - setTerminalTypeInternal(i); - } - - final int mapLineDrawToAscii(char c) { - if(c >= (char)0x5f && c <= (char)0x7e) - c = (char)asciiLineDrawChars[(int)c - 0x5f]; - else if(c >= (char)0x2b && c <= (char)0x2e) { - c = (char)asciiLineDrawChars[((int)c - 0x2b) + 0x20]; - } else if (c == 0x20) { - // !! - } else { - if(DEBUGNOTIMPL) notImplemented("ASCII line-draw-char: " + c + " (" + ((int)c) + ")"); - } - return (int)c; - } - - final char mapLineDrawToLinux(char c) { - switch(c) { - case ' ': - c = ' '; - break; - case '\004': - c = '`'; - break; - case '\261': - c = 'a'; - break; - case '\370': - c = 'f'; - break; - case '\361': - c = 'g'; - break; - case '\260': - c = 'h'; - break; - case '\331': - case '\211': - c = 'j'; - break; - case '\277': - case '\214': - c = 'k'; - break; - case '\332': - case '\206': - c = 'l'; - break; - case '\300': - case '\203': - c = 'm'; - break; - case '\305': - c = 'n'; - break; - case '\304': - case '\212': - c = 'q'; - break; - case '\362': - c = 'r'; - break; - case '\303': - case '\207': - c = 't'; - break; - case '\264': - case '\215': - c = 'u'; - break; - case '\301': - c = 'v'; - break; - case '\302': - c = 'w'; - break; - case '\263': - case '\205': - c = 'x'; - break; - case '\363': - case '\371': - c = 'y'; - break; - case '\372': - c = 'z'; - break; - case '\343': - case '\373': - c = '{'; - break; - case '\374': - case '\330': - c = '|'; - break; - case '\375': - case '\234': - c = '}'; - break; - case '\376': - c = '~'; - break; - case '\031': - c = '.'; - break; - case '\333': - c = '+'; - break; - case '\030': - c = '-'; - break; - default: - if(DEBUGNOTIMPL) notImplemented("linux line-draw-char: " + c + " (" + ((int)c) + ")"); - break; - } - return c; - } - - final char mapLineDrawToATT6386(char c) { - switch(c) { - case ' ': - c = ' '; - break; - case '`': - c = '`'; - break; - case '1': - c = 'a'; - break; - case 'x': - c = 'f'; - break; - case 'q': - c = 'g'; - break; - case '0': - c = 'h'; - break; - case 'Y': - c = 'j'; - break; - case '?': - c = 'k'; - break; - case 'Z': - c = 'l'; - break; - case '@': - c = 'm'; - break; - case 'E': - c = 'n'; - break; - case 'o': - c = 'o'; - break; - case 'p': - c = 'p'; - break; - case 'D': - c = 'q'; - break; - case 'r': - c = 'r'; - break; - case 's': - c = 's'; - break; - case 'C': - c = 't'; - break; - case '4': - c = 'u'; - break; - case 'A': - c = 'v'; - break; - case 'B': - c = 'w'; - break; - case '3': - c = 'x'; - break; - case 'y': - c = 'y'; - break; - case 'z': - c = 'z'; - break; - case '{': - c = '{'; - break; - case '|': - c = '|'; - break; - case '}': - c = '}'; - break; - case '~': - c = '~'; - break; - default: - if(DEBUGNOTIMPL) notImplemented("att6386 line-draw-char: " + c + " (" + ((int)c) + ")"); - } - return c; - } - - public int interpretChar(char c) { - int val, h, v; - - // If we have encountered a national-character we should print it! - // The character comes from ssh as 8-bit but we do a - // locale-specific translation to a java unicode-String... it's - // definately not in for interpretation, silly bug... :-) - // - if(((int)c) > 0xff) { - return (int)c; - } - - switch(parseState[c]) { - case CASE_PRINT: - if(DEBUGPRINT) System.out.println("PRINT: " + c + "(" + ((int)c) + ")"); - int ic = IGNORE; - switch(gSets[curGL]) { - case CHARSET_UK: - if(c == (char)'#') - ic = 0x00a3; // unicode pound-sign - break; - case CHARSET_ASCII: - case CHARSET_ASCII_ALT: - // Do nothing... - ic = (int)c; - - // Make ctrl-chars print nice (OK, we should really do this in TerminalWin but this is simpler...) - // - if(ic < 32) { - if(ic == 0 && hasNullPadding(whoAmIReally)) - return IGNORE; - term.write('^'); - ic += 64; - } - - break; - case CHARSET_LINES: - case CHARSET_LINES_ALT: - if(!term.getOption(Terminal.OPT_ASCII_LDC)) { - if(whoAmIReally == EMUL_LINUX) { - c = mapLineDrawToLinux(c); - } else if(whoAmIReally == EMUL_ATT6386) { - c = mapLineDrawToATT6386(c); - } - term.writeLineDrawChar(c); - } else { - ic = mapLineDrawToAscii(c); - } - break; - default: - if(DEBUGNOTIMPL) notImplemented("unknown char-set: " + gSets[curGL] + " (" + ((int)gSets[curGL]) + ")"); - } - return ic; - case CASE_GROUND_STATE: - if(DEBUG) System.out.println("GND_STATE"); - parseState = groundTable; - break; - case CASE_IGNORE_STATE: - if(DEBUG) System.out.println("IGN_STATE"); - parseState = ignTable; - break; - case CASE_IGNORE_ESC: - if(DEBUG) System.out.println("IGN_ESC"); - parseState = iesTable; - break; - case CASE_IGNORE: - if(DEBUG) System.out.println("IGNORE"); - break; - case CASE_BELL: - if(DEBUG) System.out.println("BELL"); - term.doBell(); - break; - case CASE_BS: - if(DEBUG) System.out.println("BS"); - term.doBS(); - break; - case CASE_CR: - if(DEBUG) System.out.println("CR"); - term.doCR(); - parseState = groundTable; - break; - case CASE_ESC: - if(DEBUG) System.out.println("ESC"); - parseState = escTable; - break; - case CASE_VMOT: - if(DEBUG) System.out.println("VMOT"); - term.doLF(); - parseState = groundTable; - break; - case CASE_TAB: - if(DEBUG) System.out.println("TAB"); - term.doTab(); - break; - case CASE_SI: - if(DEBUG) System.out.println("SI(curGL = 0)"); - curGL = 0; - break; - case CASE_SO: - if(DEBUG) System.out.println("S0(curGL = 1)"); - curGL = 1; - break; - case CASE_SCR_STATE: - if(DEBUG) System.out.println("SCR_STATE"); - parseState = scrTable; - break; - case CASE_SCS0_STATE: - if(DEBUG) System.out.println("SCS0"); - scsType = 0; - parseState = scsTable; - break; - case CASE_SCS1_STATE: - if(DEBUG) System.out.println("SCS1"); - scsType = 1; - parseState = scsTable; - break; - case CASE_SCS2_STATE: - if(DEBUG) System.out.println("SCS2"); - scsType = 2; - parseState = scsTable; - break; - case CASE_SCS3_STATE: - if(DEBUG) System.out.println("SCS3"); - scsType = 3; - parseState = scsTable; - break; - case CASE_ESC_IGNORE: - if(DEBUG) System.out.println("ESC_IGN"); - parseState = eigTable; - break; - case CASE_ESC_DIGIT: - if(DEBUG) System.out.println("ESC_DIGIT (" + ((int)(c - '0')) + ")"); - val = param[nparam - 1]; - if(val == PARAMNOTUSED) - val = 0; - param[nparam - 1] = 10 * val + (c - '0'); - break; - case CASE_ESC_SEMI: - if(DEBUG) System.out.println("ESC_SEMI"); - param[nparam++] = PARAMNOTUSED; - break; - case CASE_ESC_SEMIOSC: - if(DEBUG) System.out.println("ESC_SEMIOSC"); - param[nparam++] = PARAMNOTUSED; - xtermSeq = ""; - parseState = xtermSeqTable; - break; - case CASE_DEC_STATE: - if(DEBUG) System.out.println("DEC_STATE"); - parseState = decTable; - break; - case CASE_ICH: - if(DEBUG) System.out.println("ICH"); - val = param[0]; - if(val < 1) - val = 1; - term.insertChars(val); - parseState = groundTable; - break; - case CASE_CPL: - term.doCR(); - // Fall through - case CASE_CUU: - if(DEBUG) System.out.println("CUU/CPL"); - val = param[0]; - if(val < 1) - val = 1; - term.cursorUp(val); - parseState = groundTable; - break; - case CASE_CNL: - term.doCR(); - // Fall through - case CASE_CUD: - if(DEBUG) System.out.println("CUD/CNL"); - val = param[0]; - if(val < 1) - val = 1; - term.cursorDown(val); - parseState = groundTable; - break; - case CASE_CUF: - if(DEBUG) System.out.println("CUF"); - val = param[0]; - if(val < 1) - val = 1; - term.cursorForward(val); - parseState = groundTable; - break; - case CASE_CUB: - if(DEBUG) System.out.println("CUB"); - val = param[0]; - if(val < 1) - val = 1; - term.cursorBackward(val); - parseState = groundTable; - break; - case CASE_CUP: - if(DEBUG) System.out.println("CUP"); - v = param[0]; - h = param[1]; - if(v < 1) - v = 1; - if(nparam < 2 || h < 1) - h = 1; - term.cursorSetPos(v - 1, h - 1, windowRelative); - parseState = groundTable; - break; - case CASE_ED: - if(DEBUG) System.out.println("ED"); - switch(param[0]) { - case PARAMNOTUSED: - case 0: - term.clearBelow(); - break; - case 1: - term.clearAbove(); - break; - case 2: - term.clearScreen(); - term.cursorSetPos(0, 0, windowRelative); - break; - } - parseState = groundTable; - break; - case CASE_EL: - if(DEBUG) System.out.println("EL"); - switch(param[0]) { - case PARAMNOTUSED: - case 0: - term.clearRight(); - break; - case 1: - term.clearLeft(); - break; - case 2: - term.clearLine(); - break; - } - parseState = groundTable; - break; - case CASE_IL: - if(DEBUG) System.out.println("IL"); - val = param[0]; - if(val < 1) - val = 1; - term.insertLines(val); - parseState = groundTable; - break; - case CASE_DL: - if(DEBUG) System.out.println("DL"); - val = param[0]; - if(val < 1) - val = 1; - term.deleteLines(val); - parseState = groundTable; - break; - case CASE_DCH: - if(DEBUG) System.out.println("DCH"); - val = param[0]; - if(val < 1) - val = 1; - term.deleteChars(val); - parseState = groundTable; - break; - case CASE_DECID: - if(DEBUG) System.out.println("DECID"); - param[0] = PARAMNOTUSED; - // Fall through - case CASE_DA1: - if(DEBUG) System.out.println("DA1"); - reply = replyTypes[R_CSI] + "?1;2c"; - term.sendBytes(reply.getBytes()); - parseState = groundTable; - break; - case CASE_TRACK_MOUSE: - if(DEBUGNOTIMPL) notImplemented("TRACK_MOUSE"); - break; - case CASE_TBC: - if(DEBUG) System.out.println("TBC " + "(" + term.getCursorH() + ")"); - if(param[0] <= 0) { - term.clearTab(term.getCursorH()); - } else if(param[0] == 3) { - term.clearAllTabs(); - } - parseState = groundTable; - break; - case CASE_SET: - if(DEBUG) System.out.println("SET"); - ansiModes(true); - parseState = groundTable; - break; - case CASE_RST: - if(DEBUG) System.out.println("RST"); - ansiModes(false); - parseState = groundTable; - break; - case CASE_SGR: - if(DEBUG) System.out.println("SGR"); - sgrModes(); - parseState = groundTable; - break; - case CASE_CPR: - if(DEBUG) System.out.println("CPR"); - reply = null; - if(param[0] == 5) - reply = replyTypes[R_CSI] + "0n"; - else if(param[0] == 6) - reply = replyTypes[R_CSI] + (term.getCursorV() + 1) + ";" + (term.getCursorH() + 1) + "R"; - if(reply != null) - term.sendBytes(reply.getBytes()); - parseState = groundTable; - break; - case CASE_DECSTBM: - if(DEBUG) System.out.println("DECSTBM"); - int top = param[0]; - int bot = param[1]; - if(top < 1) - top = 1; - if(nparam < 2 || bot == PARAMNOTUSED || bot == 0 || bot > term.rows()) - bot = term.rows(); - if(bot > top) { - term.setWindow(top - 1, bot); - term.cursorSetPos(0, 0, windowRelative); - } - parseState = groundTable; - break; - case CASE_DECREQTPARM: - if(DEBUG) System.out.println("DECREQTPARM"); - if(param[0] == PARAMNOTUSED || param[0] == 1 || param[0] == 0) - reply = (replyTypes[R_CSI] + String.valueOf((term.getCursorV() + 2)) + ";1;1;112;112;1;0x"); - if(reply != null) - term.sendBytes(reply.getBytes()); - parseState = groundTable; - break; - case CASE_DECSET: - if(DEBUG) System.out.println("DECSET"); - dpModes(true); - parseState = groundTable; - break; - case CASE_DECRST: - if(DEBUG) System.out.println("DECRST"); - dpModes(false); - parseState = groundTable; - break; - case CASE_DECALN: - if(DEBUGNOTIMPL) notImplemented("DECALN"); - parseState = groundTable; - break; - case CASE_GSETS: - if(DEBUG) System.out.println("GSETS: '" + c + "'"); - gSets[scsType] = c; - parseState = groundTable; - break; - case CASE_DECSC: - if(DEBUG) System.out.println("DECSC"); - term.cursorSave(); - curGLDECSC = curGL; - System.arraycopy(gSets, 0, gSetsDECSC, 0, 4); - parseState = groundTable; - break; - case CASE_DECRC: - if(DEBUG) System.out.println("DECRC"); - term.cursorRestore(); - curGL = curGLDECSC; - System.arraycopy(gSetsDECSC, 0, gSets, 0, 4); - parseState = groundTable; - break; - case CASE_DECKPAM: - if(DEBUG) System.out.println("DECKPAM"); - keypadAppl = true; - parseState = groundTable; - break; - case CASE_DECKPNM: - if(DEBUG) System.out.println("DECKPNM"); - keypadAppl = false; - parseState = groundTable; - break; - case CASE_IND: - term.cursorIndex(1); - parseState = groundTable; - break; - case CASE_NEL: - if(DEBUG) System.out.println("NEL"); - term.cursorIndex(1); - term.doCR(); - parseState = groundTable; - break; - case CASE_HTS: - if(DEBUG) System.out.println("HTS (" + term.getCursorH() + ")"); - term.setTab(term.getCursorH()); - parseState = groundTable; - break; - case CASE_RI: - if(DEBUG) System.out.println("RI"); - term.cursorIndexRev(1); - parseState = groundTable; - break; - case CASE_SS2: - curSS = 2; - parseState = groundTable; - break; - case CASE_SS3: - curSS = 3; - parseState = groundTable; - break; - case CASE_CSI_STATE: - if(DEBUG) System.out.println("CSI_STATE"); - param[0] = PARAMNOTUSED; - nparam = 1; - parseState = csiTable; - break; - case CASE_OSC: - param[0] = PARAMNOTUSED; - nparam = 1; - parseState = oscTable; - break; - case CASE_RIS: - if(DEBUG) System.out.println("RIS"); - vtReset(); - parseState = groundTable; - break; - case CASE_LS2: - if(DEBUG) System.out.println("SI(curGL = 2)"); - curGL = 2; - parseState = groundTable; - break; - case CASE_LS3: - if(DEBUG) System.out.println("SI(curGL = 3)"); - curGL = 3; - parseState = groundTable; - break; - case CASE_LS3R: - if(DEBUGNOTIMPL) notImplemented("LS3R"); - parseState = groundTable; - break; - case CASE_LS2R: - if(DEBUGNOTIMPL) notImplemented("LS2R"); - parseState = groundTable; - break; - case CASE_LS1R: - if(DEBUGNOTIMPL) notImplemented("LS1R"); - parseState = groundTable; - break; - case CASE_XTERM_SAVE: - xtermSavemodes(); - parseState = groundTable; - break; - case CASE_XTERM_RESTORE: - xtermRestoremodes(); - parseState = groundTable; - break; - case CASE_XTERM_TITLE: - if(DEBUGNOTIMPL) notImplemented("XTERM_TITLE"); - break; - case CASE_HP_MEM_LOCK: - if(DEBUGNOTIMPL) notImplemented("HP_MEM_LOCK"); - parseState = groundTable; - break; - case CASE_HP_MEM_UNLOCK: - if(DEBUGNOTIMPL) notImplemented("HP_MEM_UNLOCK"); - parseState = groundTable; - break; - case CASE_HP_BUGGY_LL: - if(DEBUGNOTIMPL) notImplemented("HP_BUGGY_LL"); - parseState = groundTable; - break; - case CASE_XTERM_SEQ: - if(DEBUG) System.out.println("XTERM_SEQ"); - xtermModes(); - parseState = groundTable; - break; - case CASE_SEQ_CAPTURE: - if(DEBUG) System.out.println("XTERM_SEQ_CAP" + c); - xtermSeq += c; - break; - case CASE_ENQ: - term.sendBytes(terminalType().getBytes()); - break; - case CASE_XTERMWIN: - xtermWinCtrl(); - parseState = groundTable; - case CASE_CHT: - if(DEBUG) System.out.println("CHT"); - val = param[0]; - if(val == PARAMNOTUSED) - val = 1; - term.doTabs(val); - parseState = groundTable; - break; - case CASE_SU: - if(DEBUG) System.out.println("SU"); - val = param[0]; - if(val == PARAMNOTUSED) - val = 1; - term.scrollUp(val); - parseState = groundTable; - break; - case CASE_SD: - if(DEBUG) System.out.println("SD"); - val = param[0]; - if(val == PARAMNOTUSED) - val = 1; - term.scrollDown(val); - parseState = groundTable; - break; - case CASE_ECH: - if(DEBUG) System.out.println("ECH"); - val = param[0]; - if(val == PARAMNOTUSED) - val = 1; - term.eraseChars(val); - parseState = groundTable; - break; - case CASE_CBT: - if(DEBUG) System.out.println("CBT"); - val = param[0]; - if(val == PARAMNOTUSED) - val = 1; - term.doBackTabs(val); - parseState = groundTable; - break; - case CASE_CHA: - case CASE_HPA: - if(DEBUG) System.out.println("HPA/CHA"); - h = param[0]; - if(h < 1) - h = 1; - term.cursorSetPos(term.getCursorV(), h - 1, false); - parseState = groundTable; - break; - case CASE_REP: - if(DEBUGNOTIMPL) notImplemented("REP"); - parseState = groundTable; - break; - case CASE_VPA: - if(DEBUG) System.out.println("VPA"); - v = param[0]; - if(v < 1) - v = 1; - term.cursorSetPos(v - 1, term.getCursorH(), false); - parseState = groundTable; - break; - default: - if(DEBUGNOTIMPL) System.out.println("** Unknown state !!!"); - break; - } - return IGNORE; - } - - protected void ansiModes(boolean set) { - for(int i = 0; i < nparam; i++) { - switch(param[i]) { - case 2: - if(DEBUGNOTIMPL) notImplemented("ANSI_AM"); - break; - case 4: - if(DEBUG) System.out.println("IRM " + set); - term.setOption(Terminal.OPT_INSERTMODE, set); - break; - case 12: - if(DEBUGNOTIMPL) notImplemented("ANSI_SRM"); - break; - case 20: - if(DEBUG) System.out.println("LNM"); - term.setOption(Terminal.OPT_AUTO_LF, set); - break; - default: - if(DEBUGNOTIMPL) notImplemented("ansi-mode: " + param[i] + "(" + set + ")"); - } - } - } - - protected void sgrModes() { - for(int i = 0; i < nparam; i++) { - switch(param[i]) { - case PARAMNOTUSED: - case 0: - term.clearAllAttributes(); - break; - case 1: - case 5: - // !!! Should be Hilite/blinking... - term.setAttribute(Terminal.ATTR_BOLD, true); - break; - case 4: - term.setAttribute(Terminal.ATTR_UNDERLINE, true); - break; - case 7: - term.setAttribute(Terminal.ATTR_INVERSE, true); - break; - case 8: - if(DEBUGNOTIMPL) notImplemented("SGR invisible"); - break; - case 22: - term.setAttribute(Terminal.ATTR_BOLD, false); - break; - case 24: - term.setAttribute(Terminal.ATTR_UNDERLINE, false); - break; - case 25: - term.setAttribute(Terminal.ATTR_BOLD, false); // !!! Actually no-blink - break; - case 27: - term.setAttribute(Terminal.ATTR_INVERSE, false); - break; - case 28: - if(DEBUGNOTIMPL) notImplemented("SGR visible"); - break; - case 10: - if(DEBUG) System.out.println("SGR ASCII: " + scsType); - gSets[scsType] = CHARSET_ASCII; - break; - case 11: - case 12: - if(DEBUG) System.out.println("SGR LINEDRAW: " + scsType); - gSets[scsType] = CHARSET_LINES; - break; - case 30: - case 31: - case 32: - case 33: - case 34: - case 35: - case 36: - case 37: - term.setForegroundColor(param[i] - 30); - break; - case 90: - case 91: - case 92: - case 93: - case 94: - case 95: - case 96: - case 97: - term.setForegroundColor(param[i] - 90); - break; - case 40: - case 41: - case 42: - case 43: - case 44: - case 45: - case 46: - case 47: - term.setBackgroundColor(param[i] - 40); - break; - case 100: - case 101: - case 102: - case 103: - case 104: - case 105: - case 106: - case 107: - term.setBackgroundColor(param[i] - 100); - break; - case 39: - term.setForegroundColor(-1); // Reset to default color - break; - case 49: - term.setBackgroundColor(-1); // Reset to default color - break; - default: - if(DEBUGNOTIMPL) notImplemented("SGR: " + param[i]); - } - } - } - - protected void dpModes(boolean set) { - for(int i = 0; i < nparam; i++) { - switch(param[i]) { - case 1: - if(DEBUG) System.out.println("DECCKM"); - cursorKeysMode = set; - break; - case 2: - if(DEBUG) System.out.println("ANSI/VT52"); - if(set) { - resetGSets(); - } - break; - case 3: - if(DEBUG) System.out.println("DECCOLM"); - term.setOption(Terminal.OPT_DECCOLM, set); - break; - case 4: - if(DEBUGNOTIMPL)notImplemented("DECSCLM"); - break; - case 5: - if(DEBUG) System.out.println("DECSCNM"); - term.setOption(Terminal.OPT_REV_VIDEO, set); - break; - case 6: - if(DEBUG) System.out.println("DECOM"); - windowRelative = set; - break; - case 7: - if(DEBUG) System.out.println("DECAWM"); - term.setOption(Terminal.OPT_AUTO_WRAP, set); - break; - case 8: - // Not much we can do about autorepeat... - if(DEBUG) System.out.println("DECARM"); - break; - case 9: - if(DEBUG) System.out.println("MOUSE_X10"); - if(set) - sendMousePos = MOUSE_X10COMP; - else - sendMousePos = MOUSE_DONTSEND; - break; - case 18: - if(DEBUGNOTIMPL) notImplemented("DECPFF"); - break; - case 19: - if(DEBUGNOTIMPL) notImplemented("DECPEF"); - break; - case 25: - if(DEBUG) System.out.println("VT220-VISCUR"); - term.setOption(Terminal.OPT_VIS_CURSOR, set); - break; - case 38: - if(DEBUGNOTIMPL) notImplemented("DECTEK"); - break; - case 40: - if(DEBUG) System.out.println("DEC132COLS"); - term.setOption(Terminal.OPT_DEC132COLS, set); - break; - case 41: - if(DEBUGNOTIMPL) notImplemented("DECCUR-HACK"); - break; - case 42: - if(DEBUGNOTIMPL) notImplemented("DECNRCM"); - break; - case 44: - if(DEBUGNOTIMPL) notImplemented("DECMRGBEL"); - break; - case 45: - if(DEBUG) System.out.println("DECREVWR"); - term.setOption(Terminal.OPT_REV_WRAP, set); - break; - case 46: - if(DEBUGNOTIMPL) notImplemented("DECLOG"); - break; - case 47: - toggleAlternateBuffer(set); - break; - case 67: - if(DEBUGNOTIMPL) notImplemented("DECBKM"); - break; - case 1000: - if(DEBUG) System.out.println("MOUSE_DECVT200"); - if(set) - sendMousePos = MOUSE_DECVT200; - else - sendMousePos = MOUSE_DONTSEND; - break; - case 1001: - if(DEBUGNOTIMPL) notImplemented("MOUSE_HLTRACK"); - if(set) - sendMousePos = MOUSE_HLTRACK; - else - sendMousePos = MOUSE_DONTSEND; - break; - case 1002: - if(DEBUGNOTIMPL) notImplemented("Cell Motion Mouse Tracking"); - break; - case 1003: - if(DEBUGNOTIMPL) notImplemented("All Motion Mouse Tracking"); - break; - case 1047: - if(DEBUGNOTIMPL) notImplemented("Use Alternate Screen Buffer"); - break; - case 1048: - if(DEBUGNOTIMPL) notImplemented("Save cursor as in DECSC"); - break; - case 1049: - if(DEBUGNOTIMPL) notImplemented("Save cursor as in DECSC + Use Alternate Screen Buffer"); - break; - default: - if(DEBUGNOTIMPL) notImplemented("DEC-private: " + param[i] + "(" + set + ")"); - } - } - } - - protected void xtermModes() { - switch(param[0]) { - case 0: - if(DEBUG) System.out.println("XTERM-Change icon-name/title: " + xtermSeq); - case 1: - if(DEBUG) System.out.println("XTERM-Change icon-name: " + xtermSeq); - case 2: - if(DEBUG) System.out.println("XTERM-Change title: " + xtermSeq); - if(term instanceof TerminalWin) { - ((TerminalWin)term).setTitle(xtermSeq); - } - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - if(DEBUGNOTIMPL) notImplemented("XTERM-Change colors: " + xtermSeq); - break; - case 20: - if(DEBUGNOTIMPL) notImplemented("XITERM-Change bg-pixmap: " + xtermSeq); - break; - case 39: - if(DEBUGNOTIMPL) notImplemented("XITERM-Change fg-color: " + xtermSeq); - break; - case 49: - if(DEBUGNOTIMPL) notImplemented("XITERM-Change bg-color: " + xtermSeq); - break; - case 46: - if(DEBUGNOTIMPL) notImplemented("XTERM-new log-file: " + xtermSeq); - break; - case 50: - if(DEBUGNOTIMPL) notImplemented("XTERM-set font: " + xtermSeq); - break; - default: - if(DEBUGNOTIMPL) notImplemented("XTERM-unknown: " + xtermSeq); - break; - } - } - - protected void xtermWinCtrl() { - for(int i = 0; i < nparam; i++) { - switch(param[i]) { - case 1: - if(DEBUGNOTIMPL) notImplemented("XTERM-deiconify"); - break; - case 2: - if(DEBUGNOTIMPL) notImplemented("XTERM-iconify"); - break; - case 3: - if(DEBUGNOTIMPL) notImplemented("XTERM-move (x,y): " + param[++i] + ", " + param[++i]); - break; - case 4: - if(DEBUGNOTIMPL) notImplemented("XTERM-resize (h,w): " + param[++i] + ", " + param[++i]); - break; - case 5: - if(DEBUGNOTIMPL) notImplemented("XTERM-raise"); - break; - case 6: - if(DEBUGNOTIMPL) notImplemented("XTERM-lower"); - break; - case 7: - if(DEBUGNOTIMPL) notImplemented("XTERM-refresh"); - break; - case 8: - if(DEBUGNOTIMPL) notImplemented("XTERM-resize-txt (h,w): " + param[++i] + ", " + param[++i]); - break; - case 11: - if(DEBUGNOTIMPL) notImplemented("XTERM-report state"); - break; - case 13: - if(DEBUGNOTIMPL) notImplemented("XTERM-report pos."); - break; - case 14: - if(DEBUGNOTIMPL) notImplemented("XTERM-report size"); - break; - case 18: - if(DEBUGNOTIMPL) notImplemented("XTERM-report size-txt"); - break; - case 20: - if(DEBUGNOTIMPL) notImplemented("XTERM-report icon-label"); - break; - case 21: - if(DEBUGNOTIMPL) notImplemented("XTERM-report title"); - break; - case 24: - default: - if(DEBUGNOTIMPL) notImplemented("XTERM-resize to lines: " + param[i]); - break; - } - } - } - - protected void xtermSavemodes() { - // !!! TODO, not much... - } - - protected void xtermRestoremodes() { - // !!! TODO, not much... - } - - protected void toggleAlternateBuffer(boolean set) { - // !!! TODO, do we want this? I don't like it... - } - - final protected void resetGSets() { - gSets[0] = CHARSET_ASCII; - gSets[1] = CHARSET_LINES; - gSets[2] = CHARSET_ASCII; - gSets[3] = CHARSET_ASCII; - curGL = 0; - } - - public void vtReset() { - resetGSets(); - curSS = 0; - parseState = groundTable; - windowRelative = false; - keypadAppl = false; - cursorKeysMode = false; - sendMousePos = MOUSE_DONTSEND; - if(term != null) { - term.resetWindow(); - term.clearScreen(); - term.cursorSetPos(0, 0, false); - term.resetTabs(); - } - } - - protected void notImplemented(String cmd) { - System.out.println("not implemented: " + cmd); - } - - final int mapVKToXVK(int vk) { - int i; - for(i = 0; i < XVK_MAX; i++) { - if(vk2xvk[i] == vk) - break; - } - return i; - } - - public final int mapModToTab(int modifiers) { - int table = 0; - if((modifiers & InputEvent.SHIFT_MASK) != 0) - table = 1; - if((modifiers & InputEvent.CTRL_MASK) != 0) - table += 2; - return table; - } - - public final String mapSpecialKeys(int virtualKey, int modifiers) { - int xvk = mapVKToXVK(virtualKey); - int modTable = mapModToTab(modifiers); - String[][] specKeyMap = theSpecialKeyMaps[modTable]; - return specKeyMap[xvk][whoAmIReally]; - } - - public void keyHandler(int virtualKey, int modifiers) { - String specialKey = null; - String prefix = ""; - - // - // - switch(virtualKey) { - case KeyEvent.VK_UP: - case KeyEvent.VK_DOWN: - case KeyEvent.VK_RIGHT: - case KeyEvent.VK_LEFT: - if(cursorKeysMode) - prefix = replyTypes[R_SS3]; - else - prefix = replyTypes[R_CSI]; - specialKey = mapSpecialKeys(virtualKey, modifiers); - break; - case KeyEvent.VK_PAGE_UP: - case KeyEvent.VK_PAGE_DOWN: - case KeyEvent.VK_END: - case KeyEvent.VK_HOME: - if(!term.getOption(Terminal.OPT_LOCAL_PGKEYS)) { - prefix = replyTypes[R_CSI]; - specialKey = mapSpecialKeys(virtualKey, modifiers); - } - break; - case KeyEvent.VK_INSERT: - prefix = replyTypes[R_CSI]; - specialKey = mapSpecialKeys(virtualKey, modifiers); - break; - case KeyEvent.VK_F1: - case KeyEvent.VK_F2: - case KeyEvent.VK_F3: - case KeyEvent.VK_F4: - case KeyEvent.VK_F5: - case KeyEvent.VK_F6: - case KeyEvent.VK_F7: - case KeyEvent.VK_F8: - case KeyEvent.VK_F9: - case KeyEvent.VK_F10: - case KeyEvent.VK_F11: - case KeyEvent.VK_F12: - if(whoAmIReally == EMUL_VT100 || whoAmIReally == EMUL_ANSI || whoAmIReally == EMUL_ATT6386) { - prefix = replyTypes[R_SS3]; - } else if(whoAmIReally == EMUL_VT220) { - if(virtualKey > KeyEvent.VK_F4) - prefix = replyTypes[R_CSI]; - else - prefix = replyTypes[R_SS3]; - } else if(whoAmIReally == EMUL_VT52) { - prefix = replyTypes[R_ESC]; - } else { - prefix = replyTypes[R_CSI]; - } - specialKey = mapSpecialKeys(virtualKey, modifiers); - break; - case KeyEvent.VK_NUMPAD0: - case KeyEvent.VK_NUMPAD1: - case KeyEvent.VK_NUMPAD2: - case KeyEvent.VK_NUMPAD3: - case KeyEvent.VK_NUMPAD4: - case KeyEvent.VK_NUMPAD5: - case KeyEvent.VK_NUMPAD6: - case KeyEvent.VK_NUMPAD7: - case KeyEvent.VK_NUMPAD8: - case KeyEvent.VK_NUMPAD9: - case KeyEvent.VK_MULTIPLY: - case KeyEvent.VK_ADD: - case KeyEvent.VK_SUBTRACT: - case KeyEvent.VK_DIVIDE: -/* - !!! I give up on these, java is pretty immature concerning the virtual keys IMHO... - Anyway, we should only send the key when in keypadAppl mode (the - keyReleased/keyTyped must be handled accordingly since we must suppres - the keyTyped...). All this is pretty messy, it would be POSSIBLE to do - a huge kludge doing keyboard input using MOSTLY the keyReleased events - and filling it in with the keyTyped that are not giving a sane - VK_*. However, I am not in the mood of doing this right now. The - virtual key handling/mapping should be refined in java IMHO - - if(keypadAppl) { - prefix = replyTypes[R_SS3]; - specialKey = mapSpecialKeys(virtualKey); - } -*/ - default: - // !!! System.out.println("XTerm keyHandler: " + virtualKey); - break; - } - if(specialKey != null) { - specialKey = prefix + specialKey; - term.sendBytes(specialKey.getBytes()); - } - } - - int xButton(int modifiers) { - int butt = 0; - if((modifiers & InputEvent.BUTTON1_MASK) != 0) - butt = 0; - else if((modifiers & InputEvent.BUTTON2_MASK) != 0) - butt = 1; - else if((modifiers & InputEvent.BUTTON3_MASK) != 0) - butt = 2; - return butt; - } - - int xKeyState(int modifiers) { - int key = 0; - if((modifiers & InputEvent.SHIFT_MASK) != 0) - key |= 1; - if((modifiers & InputEvent.ALT_MASK) != 0) - key |= 2; - if((modifiers & InputEvent.CTRL_MASK) != 0) - key |= 4; - return (key << 2); - } - - public void mouseHandler(int row, int col, boolean press, int modifiers) { - switch(sendMousePos) { - case MOUSE_DONTSEND: - break; - case MOUSE_X10COMP: - if(press) { - term.sendBytes(("\033[M" + (char)(' ' + xButton(modifiers)) + - (char)(' ' + col + 1) + (char)(' ' + row + 1)).getBytes()); - } - break; - case MOUSE_DECVT200: - term.sendBytes(("\033[M" + (char)(' ' + (press ? - (xButton(modifiers) | xKeyState(modifiers)) : - 3)) + - (char)(' ' + col + 1) + (char)(' ' + row + 1)).getBytes()); - break; - case MOUSE_HLTRACK: - break; - } - } - - public final static int[] groundTable = - { - /* NUL SOH STX ETX */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* EOT ENQ ACK BEL */ - CASE_PRINT, - CASE_ENQ, - CASE_PRINT, - CASE_BELL, - /* BS HT NL VT */ - CASE_BS, - CASE_TAB, - CASE_VMOT, - CASE_VMOT, - /* NP CR SO SI */ - CASE_VMOT, - CASE_CR, - CASE_SO, - CASE_SI, - /* DLE DC1 DC2 DC3 */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* DC4 NAK SYN ETB */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* CAN EM SUB ESC */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_ESC, - /* FS GS RS US */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* SP ! " # */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* $ % & ' */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* ( ) * + */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* , - . / */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* 0 1 2 3 */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* 4 5 6 7 */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* 8 9 : ; */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* < = > ? */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* @ A B C */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* D E F G */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* H I J K */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* L M N O */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* P Q R S */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* T U V W */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* X Y Z [ */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* \ ] ^ _ */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* ` a b c */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* d e f g */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* h i j k */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* l m n o */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* p q r s */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* t u v w */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* x y z { */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* | } ~ DEL */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_GROUND_STATE, - /* 0x80 0x81 0x82 0x83 */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* 0x84 0x85 0x86 0x87 */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* 0x88 0x89 0x8a 0x8b */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* 0x8c 0x8d 0x8e 0x8f */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* 0x90 0x91 0x92 0x93 */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* 0x94 0x95 0x96 0x97 */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* 0x99 0x99 0x9a 0x9b */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* 0x9c 0x9d 0x9e 0x9f */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* nobreakspace exclamdown cent sterling */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* currency yen brokenbar section */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* diaeresis copyright ordfeminine guillemotleft */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* notsign hyphen registered macron */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* degree plusminus twosuperior threesuperior */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* acute mu paragraph periodcentered */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* cedilla onesuperior masculine guillemotright */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* onequarter onehalf threequarters questiondown */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* Agrave Aacute Acircumflex Atilde */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* Adiaeresis Aring AE Ccedilla */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* Egrave Eacute Ecircumflex Ediaeresis */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* Igrave Iacute Icircumflex Idiaeresis */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* Eth Ntilde Ograve Oacute */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* Ocircumflex Otilde Odiaeresis multiply */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* Ooblique Ugrave Uacute Ucircumflex */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* Udiaeresis Yacute Thorn ssharp */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* agrave aacute acircumflex atilde */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* adiaeresis aring ae ccedilla */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* egrave eacute ecircumflex ediaeresis */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* igrave iacute icircumflex idiaeresis */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* eth ntilde ograve oacute */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* ocircumflex otilde odiaeresis division */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* oslash ugrave uacute ucircumflex */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - /* udiaeresis yacute thorn ydiaeresis */ - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - CASE_PRINT, - }; - - // ESC [ - public final static int[] csiTable= - { - /* NUL SOH STX ETX */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* EOT ENQ ACK BEL */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_BELL, - /* BS HT NL VT */ - CASE_BS, - CASE_TAB, - CASE_VMOT, - CASE_VMOT, - /* NP CR SO SI */ - CASE_VMOT, - CASE_CR, - CASE_SO, - CASE_SI, - /* DLE DC1 DC2 DC3 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* DC4 NAK SYN ETB */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* CAN EM SUB ESC */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_ESC, - /* FS GS RS US */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* SP ! " # */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* $ % & ' */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* ( ) * + */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* , - . / */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* 0 1 2 3 */ - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - /* 4 5 6 7 */ - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - /* 8 9 : ; */ - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - CASE_IGNORE, - CASE_ESC_SEMI, - /* < = > ? */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_DEC_STATE, - /* @ A B C */ - CASE_ICH, - CASE_CUU, - CASE_CUD, - CASE_CUF, - /* D E F G */ - CASE_CUB, - CASE_CNL, - CASE_CPL, - CASE_CHA, - /* H I J K */ - CASE_CUP, - CASE_CHT, - CASE_ED, - CASE_EL, - /* L M N O */ - CASE_IL, - CASE_DL, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* P Q R S */ - CASE_DCH, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_SU, - /* T U V W */ - CASE_SD, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* X Y Z [ */ - CASE_ECH, - CASE_GROUND_STATE, - CASE_CBT, - CASE_GROUND_STATE, - /* \ ] ^ _ */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_SD, - CASE_GROUND_STATE, - /* ` a b c */ - CASE_HPA, - CASE_GROUND_STATE, - CASE_REP, - CASE_DA1, - /* d e f g */ - CASE_VPA, - CASE_GROUND_STATE, - CASE_CUP, - CASE_TBC, - /* h i j k */ - CASE_SET, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* l m n o */ - CASE_RST, - CASE_SGR, - CASE_CPR, - CASE_GROUND_STATE, - /* p q r s */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_DECSTBM, - CASE_DECSC, - /* t u v w */ - CASE_XTERMWIN, - CASE_DECRC, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* x y z { */ - CASE_DECREQTPARM, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* | } ~ DEL */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* 0x80 0x81 0x82 0x83 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x84 0x85 0x86 0x87 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x88 0x89 0x8a 0x8b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x8c 0x8d 0x8e 0x8f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x90 0x91 0x92 0x93 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x94 0x95 0x96 0x97 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x99 0x99 0x9a 0x9b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x9c 0x9d 0x9e 0x9f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* nobreakspace exclamdown cent sterling */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* currency yen brokenbar section */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* diaeresis copyright ordfeminine guillemotleft */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* notsign hyphen registered macron */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* degree plusminus twosuperior threesuperior */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* acute mu paragraph periodcentered */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* cedilla onesuperior masculine guillemotright */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* onequarter onehalf threequarters questiondown */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Agrave Aacute Acircumflex Atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Adiaeresis Aring AE Ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Egrave Eacute Ecircumflex Ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Igrave Iacute Icircumflex Idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Eth Ntilde Ograve Oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ocircumflex Otilde Odiaeresis multiply */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ooblique Ugrave Uacute Ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Udiaeresis Yacute Thorn ssharp */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* agrave aacute acircumflex atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* adiaeresis aring ae ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* egrave eacute ecircumflex ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* igrave iacute icircumflex idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* eth ntilde ograve oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* ocircumflex otilde odiaeresis division */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* oslash ugrave uacute ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* udiaeresis yacute thorn ydiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - }; - - // ESC [ ? - public final static int[] decTable = - { - /* NUL SOH STX ETX */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* EOT ENQ ACK BEL */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_BELL, - /* BS HT NL VT */ - CASE_BS, - CASE_TAB, - CASE_VMOT, - CASE_VMOT, - /* NP CR SO SI */ - CASE_VMOT, - CASE_CR, - CASE_SO, - CASE_SI, - /* DLE DC1 DC2 DC3 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* DC4 NAK SYN ETB */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* CAN EM SUB ESC */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_ESC, - /* FS GS RS US */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* SP ! " # */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* $ % & ' */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* ( ) * + */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* , - . / */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* 0 1 2 3 */ - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - /* 4 5 6 7 */ - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - /* 8 9 : ; */ - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - CASE_IGNORE, - CASE_ESC_SEMI, - /* < = > ? */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* @ A B C */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* D E F G */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* H I J K */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* L M N O */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* P Q R S */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* T U V W */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* X Y Z [ */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* \ ] ^ _ */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* ` a b c */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* d e f g */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* h i j k */ - CASE_DECSET, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* l m n o */ - CASE_DECRST, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* p q r s */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_XTERM_RESTORE, - CASE_XTERM_SAVE, - /* t u v w */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* x y z { */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* | } ~ DEL */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* 0x80 0x81 0x82 0x83 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x84 0x85 0x86 0x87 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x88 0x89 0x8a 0x8b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x8c 0x8d 0x8e 0x8f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x90 0x91 0x92 0x93 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x94 0x95 0x96 0x97 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x99 0x99 0x9a 0x9b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x9c 0x9d 0x9e 0x9f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* nobreakspace exclamdown cent sterling */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* currency yen brokenbar section */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* diaeresis copyright ordfeminine guillemotleft */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* notsign hyphen registered macron */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* degree plusminus twosuperior threesuperior */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* acute mu paragraph periodcentered */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* cedilla onesuperior masculine guillemotright */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* onequarter onehalf threequarters questiondown */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Agrave Aacute Acircumflex Atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Adiaeresis Aring AE Ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Egrave Eacute Ecircumflex Ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Igrave Iacute Icircumflex Idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Eth Ntilde Ograve Oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ocircumflex Otilde Odiaeresis multiply */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ooblique Ugrave Uacute Ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Udiaeresis Yacute Thorn ssharp */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* agrave aacute acircumflex atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* adiaeresis aring ae ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* egrave eacute ecircumflex ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* igrave iacute icircumflex idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* eth ntilde ograve oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* ocircumflex otilde odiaeresis division */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* oslash ugrave uacute ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* udiaeresis yacute thorn ydiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - }; - - // ESC ] ? - public final static int[] oscTable = - { - /* NUL SOH STX ETX */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* EOT ENQ ACK BEL */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* BS HT NL VT */ - CASE_BS, - CASE_TAB, - CASE_VMOT, - CASE_VMOT, - /* NP CR SO SI */ - CASE_VMOT, - CASE_CR, - CASE_SO, - CASE_SI, - /* DLE DC1 DC2 DC3 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* DC4 NAK SYN ETB */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* CAN EM SUB ESC */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_ESC, - /* FS GS RS US */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* SP ! " # */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* $ % & ' */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* ( ) * + */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* , - . / */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* 0 1 2 3 */ - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - /* 4 5 6 7 */ - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - /* 8 9 : ; */ - CASE_ESC_DIGIT, - CASE_ESC_DIGIT, - CASE_IGNORE, - CASE_ESC_SEMIOSC, - /* < = > ? */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* @ A B C */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* D E F G */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* H I J K */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* L M N O */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* P Q R S */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* T U V W */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* X Y Z [ */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* \ ] ^ _ */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* ` a b c */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* d e f g */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* h i j k */ - CASE_DECSET, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* l m n o */ - CASE_DECRST, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* p q r s */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_XTERM_RESTORE, - CASE_XTERM_SAVE, - /* t u v w */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* x y z { */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* | } ~ DEL */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* 0x80 0x81 0x82 0x83 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x84 0x85 0x86 0x87 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x88 0x89 0x8a 0x8b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x8c 0x8d 0x8e 0x8f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x90 0x91 0x92 0x93 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x94 0x95 0x96 0x97 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x99 0x99 0x9a 0x9b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x9c 0x9d 0x9e 0x9f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* nobreakspace exclamdown cent sterling */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* currency yen brokenbar section */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* diaeresis copyright ordfeminine guillemotleft */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* notsign hyphen registered macron */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* degree plusminus twosuperior threesuperior */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* acute mu paragraph periodcentered */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* cedilla onesuperior masculine guillemotright */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* onequarter onehalf threequarters questiondown */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Agrave Aacute Acircumflex Atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Adiaeresis Aring AE Ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Egrave Eacute Ecircumflex Ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Igrave Iacute Icircumflex Idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Eth Ntilde Ograve Oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ocircumflex Otilde Odiaeresis multiply */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ooblique Ugrave Uacute Ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Udiaeresis Yacute Thorn ssharp */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* agrave aacute acircumflex atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* adiaeresis aring ae ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* egrave eacute ecircumflex ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* igrave iacute icircumflex idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* eth ntilde ograve oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* ocircumflex otilde odiaeresis division */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* oslash ugrave uacute ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* udiaeresis yacute thorn ydiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - }; - - // - public final static int[] xtermSeqTable = - { - /* NUL SOH STX ETX */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* EOT ENQ ACK BEL */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_XTERM_SEQ, - /* BS HT NL VT */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* NP CR SO SI */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* DLE DC1 DC2 DC3 */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* DC4 NAK SYN ETB */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* CAN EM SUB ESC */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* FS GS RS US */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* SP ! " # */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* $ % & ' */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* ( ) * + */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* , - . / */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* 0 1 2 3 */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* 4 5 6 7 */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* 8 9 : ; */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* < = > ? */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* @ A B C */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* D E F G */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* H I J K */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* L M N O */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* P Q R S */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* T U V W */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* X Y Z [ */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* \ ] ^ _ */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* ` a b c */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* d e f g */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* h i j k */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* l m n o */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* p q r s */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* t u v w */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* x y z { */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* | } ~ DEL */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_IGNORE, - /* 0x80 0x81 0x82 0x83 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x84 0x85 0x86 0x87 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x88 0x89 0x8a 0x8b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x8c 0x8d 0x8e 0x8f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x90 0x91 0x92 0x93 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x94 0x95 0x96 0x97 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x99 0x99 0x9a 0x9b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x9c 0x9d 0x9e 0x9f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* nobreakspace exclamdown cent sterling */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* currency yen brokenbar section */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* diaeresis copyright ordfeminine guillemotleft */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* notsign hyphen registered macron */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* degree plusminus twosuperior threesuperior */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* acute mu paragraph periodcentered */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* cedilla onesuperior masculine guillemotright */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* onequarter onehalf threequarters questiondown */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* Agrave Aacute Acircumflex Atilde */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* Adiaeresis Aring AE Ccedilla */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* Egrave Eacute Ecircumflex Ediaeresis */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* Igrave Iacute Icircumflex Idiaeresis */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* Eth Ntilde Ograve Oacute */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* Ocircumflex Otilde Odiaeresis multiply */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* Ooblique Ugrave Uacute Ucircumflex */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* Udiaeresis Yacute Thorn ssharp */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* agrave aacute acircumflex atilde */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* adiaeresis aring ae ccedilla */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* egrave eacute ecircumflex ediaeresis */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* igrave iacute icircumflex idiaeresis */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* eth ntilde ograve oacute */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* ocircumflex otilde odiaeresis division */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* oslash ugrave uacute ucircumflex */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - /* udiaeresis yacute thorn ydiaeresis */ - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - CASE_SEQ_CAPTURE, - }; - - // CASE_ESC_IGNORE - public final static int[] eigTable = - { - /* NUL SOH STX ETX */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* EOT ENQ ACK BEL */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_BELL, - /* BS HT NL VT */ - CASE_BS, - CASE_TAB, - CASE_VMOT, - CASE_VMOT, - /* NP CR SO SI */ - CASE_VMOT, - CASE_CR, - CASE_SO, - CASE_SI, - /* DLE DC1 DC2 DC3 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* DC4 NAK SYN ETB */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* CAN EM SUB ESC */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_ESC, - /* FS GS RS US */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* SP ! " # */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* $ % & ' */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* ( ) * + */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* , - - . / */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0 1 2 3 */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* 4 5 6 7 */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* 8 9 : ; */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* < = > ? */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* @ A B C */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* D E F G */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* H I J K */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* L M N O */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* P Q R S */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* T U V W */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* X Y Z [ */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* \ ] ^ _ */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* ` a b c */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* d e f g */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* h i j k */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* l m n o */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* p q r s */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* t u v w */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* x y z { */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* | } ~ DEL */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* 0x80 0x81 0x82 0x83 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x84 0x85 0x86 0x87 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x88 0x89 0x8a 0x8b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x8c 0x8d 0x8e 0x8f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x90 0x91 0x92 0x93 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x94 0x95 0x96 0x97 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x99 0x99 0x9a 0x9b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x9c 0x9d 0x9e 0x9f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* nobreakspace exclamdown cent sterling */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* currency yen brokenbar section */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* diaeresis copyright ordfeminine guillemotleft */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* notsign hyphen registered macron */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* degree plusminus twosuperior threesuperior */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* acute mu paragraph periodcentered */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* cedilla onesuperior masculine guillemotright */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* onequarter onehalf threequarters questiondown */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Agrave Aacute Acircumflex Atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Adiaeresis Aring AE Ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Egrave Eacute Ecircumflex Ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Igrave Iacute Icircumflex Idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Eth Ntilde Ograve Oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ocircumflex Otilde Odiaeresis multiply */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ooblique Ugrave Uacute Ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Udiaeresis Yacute Thorn ssharp */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* agrave aacute acircumflex atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* adiaeresis aring ae ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* egrave eacute ecircumflex ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* igrave iacute icircumflex idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* eth ntilde ograve oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* ocircumflex otilde odiaeresis division */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* oslash ugrave uacute ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* udiaeresis yacute thorn ydiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - }; - - // ESC - public final static int[] escTable = - { - /* NUL SOH STX ETX */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* EOT ENQ ACK BEL */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_BELL, - /* BS HT NL VT */ - CASE_BS, - CASE_TAB, - CASE_VMOT, - CASE_VMOT, - /* NP CR SO SI */ - CASE_VMOT, - CASE_CR, - CASE_SO, - CASE_SI, - /* DLE DC1 DC2 DC3 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* DC4 NAK SYN ETB */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* CAN EM SUB ESC */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_ESC, - /* FS GS RS US */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* SP ! " # */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_SCR_STATE, - /* $ % & ' */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* ( ) * + */ - CASE_SCS0_STATE, - CASE_SCS1_STATE, - CASE_SCS2_STATE, - CASE_SCS3_STATE, - /* , - . / */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* 0 1 2 3 */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* 4 5 6 7 */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_DECSC, - /* 8 9 : ; */ - CASE_DECRC, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* < = > ? */ - CASE_GROUND_STATE, - CASE_DECKPAM, - CASE_DECKPNM, - CASE_GROUND_STATE, - /* @ A B C */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* D E F G */ - CASE_IND, - CASE_NEL, - CASE_HP_BUGGY_LL, - CASE_GROUND_STATE, - /* H I J K */ - CASE_HTS, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* L M N O */ - CASE_GROUND_STATE, - CASE_RI, - CASE_SS2, - CASE_SS3, - /* P Q R S */ - CASE_IGNORE_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* T U V W */ - CASE_XTERM_TITLE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* X Y Z [ */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_DECID, - CASE_CSI_STATE, - /* \ ] ^ _ */ - CASE_GROUND_STATE, - CASE_OSC, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* ` a b c */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_RIS, - /* d e f g */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* h i j k */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* l m n o */ - CASE_HP_MEM_LOCK, - CASE_HP_MEM_UNLOCK, - CASE_LS2, - CASE_LS3, - /* p q r s */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* t u v w */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* x y z { */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* | } ~ DEL */ - CASE_LS3R, - CASE_LS2R, - CASE_LS1R, - CASE_GROUND_STATE, - /* 0x80 0x81 0x82 0x83 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x84 0x85 0x86 0x87 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x88 0x89 0x8a 0x8b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x8c 0x8d 0x8e 0x8f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x90 0x91 0x92 0x93 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x94 0x95 0x96 0x97 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x99 0x99 0x9a 0x9b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x9c 0x9d 0x9e 0x9f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* nobreakspace exclamdown cent sterling */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* currency yen brokenbar section */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* diaeresis copyright ordfeminine guillemotleft */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* notsign hyphen registered macron */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* degree plusminus twosuperior threesuperior */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* acute mu paragraph periodcentered */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* cedilla onesuperior masculine guillemotright */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* onequarter onehalf threequarters questiondown */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Agrave Aacute Acircumflex Atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Adiaeresis Aring AE Ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Egrave Eacute Ecircumflex Ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Igrave Iacute Icircumflex Idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Eth Ntilde Ograve Oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ocircumflex Otilde Odiaeresis multiply */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ooblique Ugrave Uacute Ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Udiaeresis Yacute Thorn ssharp */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* agrave aacute acircumflex atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* adiaeresis aring ae ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* egrave eacute ecircumflex ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* igrave iacute icircumflex idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* eth ntilde ograve oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* ocircumflex otilde odiaeresis division */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* oslash ugrave uacute ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* udiaeresis yacute thorn ydiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - }; - - // CASE_IGNORE_ESC - public final static int[] iesTable = - { - /* NUL SOH STX ETX */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* EOT ENQ ACK BEL */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* BS HT NL VT */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* NP CR SO SI */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* DLE DC1 DC2 DC3 */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* DC4 NAK SYN ETB */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* CAN EM SUB ESC */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* FS GS RS US */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* SP ! " # */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* $ % & ' */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* ( ) * + */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* , - . / */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* 0 1 2 3 */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* 4 5 6 7 */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* 8 9 : ; */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* < = > ? */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* @ A B C */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* D E F G */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* H I J K */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* L M N O */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* P Q R S */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* T U V W */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* X Y Z [ */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* \ ] ^ _ */ - CASE_GROUND_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* ` a b c */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* d e f g */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* h i j k */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* l m n o */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* p q r s */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* t u v w */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* x y z { */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* | } ~ DEL */ - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - CASE_IGNORE_STATE, - /* 0x80 0x81 0x82 0x83 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x84 0x85 0x86 0x87 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x88 0x89 0x8a 0x8b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x8c 0x8d 0x8e 0x8f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x90 0x91 0x92 0x93 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x94 0x95 0x96 0x97 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x99 0x99 0x9a 0x9b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x9c 0x9d 0x9e 0x9f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* nobreakspace exclamdown cent sterling */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* currency yen brokenbar section */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* diaeresis copyright ordfeminine guillemotleft */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* notsign hyphen registered macron */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* degree plusminus twosuperior threesuperior */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* acute mu paragraph periodcentered */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* cedilla onesuperior masculine guillemotright */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* onequarter onehalf threequarters questiondown */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Agrave Aacute Acircumflex Atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Adiaeresis Aring AE Ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Egrave Eacute Ecircumflex Ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Igrave Iacute Icircumflex Idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Eth Ntilde Ograve Oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ocircumflex Otilde Odiaeresis multiply */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ooblique Ugrave Uacute Ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Udiaeresis Yacute Thorn ssharp */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* agrave aacute acircumflex atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* adiaeresis aring ae ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* egrave eacute ecircumflex ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* igrave iacute icircumflex idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* eth ntilde ograve oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* ocircumflex otilde odiaeresis division */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* oslash ugrave uacute ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* udiaeresis yacute thorn ydiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - }; - - // CASE_IGNORE_STATE - public final static int[] ignTable = - { - /* NUL SOH STX ETX */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* EOT ENQ ACK BEL */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* BS HT NL VT */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* NP CR SO SI */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* DLE DC1 DC2 DC3 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* DC4 NAK SYN ETB */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* CAN EM SUB ESC */ - CASE_GROUND_STATE, - CASE_IGNORE, - CASE_GROUND_STATE, - CASE_IGNORE_ESC, - /* FS GS RS US */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* SP ! " # */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* $ % & ' */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* ( ) * + */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* , - . / */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0 1 2 3 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 4 5 6 7 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 8 9 : ; */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* < = > ? */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* @ A B C */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* D E F G */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* H I J K */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* L M N O */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* P Q R S */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* T U V W */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* X Y Z [ */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* \ ] ^ _ */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* ` a b c */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* d e f g */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* h i j k */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* l m n o */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* p q r s */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* t u v w */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* x y z { */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* | } ~ DEL */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x80 0x81 0x82 0x83 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x84 0x85 0x86 0x87 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x88 0x89 0x8a 0x8b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x8c 0x8d 0x8e 0x8f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x90 0x91 0x92 0x93 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x94 0x95 0x96 0x97 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x99 0x99 0x9a 0x9b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x9c 0x9d 0x9e 0x9f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* nobreakspace exclamdown cent sterling */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* currency yen brokenbar section */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* diaeresis copyright ordfeminine guillemotleft */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* notsign hyphen registered macron */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* degree plusminus twosuperior threesuperior */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* acute mu paragraph periodcentered */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* cedilla onesuperior masculine guillemotright */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* onequarter onehalf threequarters questiondown */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Agrave Aacute Acircumflex Atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Adiaeresis Aring AE Ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Egrave Eacute Ecircumflex Ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Igrave Iacute Icircumflex Idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Eth Ntilde Ograve Oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ocircumflex Otilde Odiaeresis multiply */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ooblique Ugrave Uacute Ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Udiaeresis Yacute Thorn ssharp */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* agrave aacute acircumflex atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* adiaeresis aring ae ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* egrave eacute ecircumflex ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* igrave iacute icircumflex idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* eth ntilde ograve oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* ocircumflex otilde odiaeresis division */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* oslash ugrave uacute ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* udiaeresis yacute thorn ydiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - }; - - // ESC # - public final static int[] scrTable = - { - /* NUL SOH STX ETX */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* EOT ENQ ACK BEL */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_BELL, - /* BS HT NL VT */ - CASE_BS, - CASE_TAB, - CASE_VMOT, - CASE_VMOT, - /* NP CR SO SI */ - CASE_VMOT, - CASE_CR, - CASE_SO, - CASE_SI, - /* DLE DC1 DC2 DC3 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* DC4 NAK SYN ETB */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* CAN EM SUB ESC */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_ESC, - /* FS GS RS US */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* SP ! " # */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* $ % & ' */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* ( ) * + */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* , - . / */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* 0 1 2 3 */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* 4 5 6 7 */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* 8 9 : ; */ - CASE_DECALN, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* < = > ? */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* @ A B C */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* D E F G */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* H I J K */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* L M N O */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* P Q R S */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* T U V W */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* X Y Z [ */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* \ ] ^ _ */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* ` a b c */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* d e f g */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* h i j k */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* l m n o */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* p q r s */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* t u v w */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* x y z { */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* | } ~ DEL */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* 0x80 0x81 0x82 0x83 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x84 0x85 0x86 0x87 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x88 0x89 0x8a 0x8b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x8c 0x8d 0x8e 0x8f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x90 0x91 0x92 0x93 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x94 0x95 0x96 0x97 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x99 0x99 0x9a 0x9b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x9c 0x9d 0x9e 0x9f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* nobreakspace exclamdown cent sterling */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* currency yen brokenbar section */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* diaeresis copyright ordfeminine guillemotleft */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* notsign hyphen registered macron */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* degree plusminus twosuperior threesuperior */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* acute mu paragraph periodcentered */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* cedilla onesuperior masculine guillemotright */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* onequarter onehalf threequarters questiondown */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Agrave Aacute Acircumflex Atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Adiaeresis Aring AE Ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Egrave Eacute Ecircumflex Ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Igrave Iacute Icircumflex Idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Eth Ntilde Ograve Oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ocircumflex Otilde Odiaeresis multiply */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ooblique Ugrave Uacute Ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Udiaeresis Yacute Thorn ssharp */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* agrave aacute acircumflex atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* adiaeresis aring ae ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* egrave eacute ecircumflex ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* igrave iacute icircumflex idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* eth ntilde ograve oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* ocircumflex otilde odiaeresis division */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* oslash ugrave uacute ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* udiaeresis yacute thorn ydiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - }; - - // ESC ( etc. - public final static int[] scsTable = - { - /* NUL SOH STX ETX */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* EOT ENQ ACK BEL */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_BELL, - /* BS HT NL VT */ - CASE_BS, - CASE_TAB, - CASE_VMOT, - CASE_VMOT, - /* NP CR SO SI */ - CASE_VMOT, - CASE_CR, - CASE_SO, - CASE_SI, - /* DLE DC1 DC2 DC3 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* DC4 NAK SYN ETB */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* CAN EM SUB ESC */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_ESC, - /* FS GS RS US */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* SP ! " # */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* $ % & ' */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* ( ) * + */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* , - . / */ - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - CASE_ESC_IGNORE, - /* 0 1 2 3 */ - CASE_GSETS, - CASE_GSETS, - CASE_GSETS, - CASE_GROUND_STATE, - /* 4 5 6 7 */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* 8 9 : ; */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* < = > ? */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* @ A B C */ - CASE_GROUND_STATE, - CASE_GSETS, - CASE_GSETS, - CASE_GROUND_STATE, - /* D E F G */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* H I J K */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* L M N O */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* P Q R S */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* T U V W */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* X Y Z [ */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* \ ] ^ _ */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* ` a b c */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* d e f g */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* h i j k */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* l m n o */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* p q r s */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* t u v w */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* x y z { */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* | } ~ DEL */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* 0x80 0x81 0x82 0x83 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x84 0x85 0x86 0x87 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x88 0x89 0x8a 0x8b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x8c 0x8d 0x8e 0x8f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x90 0x91 0x92 0x93 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x94 0x95 0x96 0x97 */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x99 0x99 0x9a 0x9b */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* 0x9c 0x9d 0x9e 0x9f */ - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - CASE_IGNORE, - /* nobreakspace exclamdown cent sterling */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* currency yen brokenbar section */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* diaeresis copyright ordfeminine guillemotleft */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* notsign hyphen registered macron */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* degree plusminus twosuperior threesuperior */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* acute mu paragraph periodcentered */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* cedilla onesuperior masculine guillemotright */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* onequarter onehalf threequarters questiondown */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Agrave Aacute Acircumflex Atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Adiaeresis Aring AE Ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Egrave Eacute Ecircumflex Ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Igrave Iacute Icircumflex Idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Eth Ntilde Ograve Oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ocircumflex Otilde Odiaeresis multiply */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Ooblique Ugrave Uacute Ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* Udiaeresis Yacute Thorn ssharp */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* agrave aacute acircumflex atilde */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* adiaeresis aring ae ccedilla */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* egrave eacute ecircumflex ediaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* igrave iacute icircumflex idiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* eth ntilde ograve oacute */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* ocircumflex otilde odiaeresis division */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* oslash ugrave uacute ucircumflex */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - /* udiaeresis yacute thorn ydiaeresis */ - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - CASE_GROUND_STATE, - }; - -} diff --git a/src/main/java/com/mindbright/util/ASCIIArmour.java b/src/main/java/com/mindbright/util/ASCIIArmour.java deleted file mode 100644 index 0c156be..0000000 --- a/src/main/java/com/mindbright/util/ASCIIArmour.java +++ /dev/null @@ -1,350 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.util; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.IOException; - -import java.util.Hashtable; -import java.util.Vector; -import java.util.Enumeration; -import java.util.StringTokenizer; - -public final class ASCIIArmour { - public final static int DEFAULT_LINE_LENGTH = 70; - - String EOL; - String headerLine; - Hashtable headerFields; - Vector fieldsOrder; - String tailLine; - - boolean blankHeaderSep; - int lineLen; - boolean haveChecksum; - - boolean unknownHeaderLines; - String headerLinePrePostFix; - - public ASCIIArmour(String headerLine, String tailLine, - boolean blankHeaderSep, int lineLen) { - this.EOL = "\r\n"; - this.headerLine = headerLine; - this.tailLine = tailLine; - this.blankHeaderSep = blankHeaderSep; - this.lineLen = lineLen; - this.unknownHeaderLines = false; - this.headerFields = new Hashtable(); - this.fieldsOrder = new Vector(); - } - - public ASCIIArmour(String headerLine, String tailLine) { - this(headerLine, tailLine, false, DEFAULT_LINE_LENGTH); - } - - public ASCIIArmour(String headerLinePrePostFix) { - this(headerLinePrePostFix, headerLinePrePostFix); - this.unknownHeaderLines = true; - } - - public void setCanonicalLineEnd(boolean value) { - if(value) { - EOL = "\r\n"; - } else { - EOL = "\n"; - } - } - - public void setBlankHeaderSep(boolean value) { - this.blankHeaderSep = value; - } - - public void setLineLength(int lineLen) { - this.lineLen = lineLen; - } - - public String getHeaderLine() { - return headerLine; - } - - public void setHeaderLine(String headerLine) { - unknownHeaderLines = false; - this.headerLine = headerLine; - } - - public void setTailLine(String tailLine) { - unknownHeaderLines = false; - this.tailLine = tailLine; - } - - public Hashtable getHeaderFields() { - return headerFields; - } - - public String getHeaderField(String headerName) { - return (String)headerFields.get(headerName); - } - - public void setHeaderField(String headerName, String value) { - if(value != null) { - headerFields.put(headerName, value); - fieldsOrder.addElement(headerName.intern()); - } else { - headerFields.remove(headerName); - fieldsOrder.removeElement(headerName.intern()); - } - } - - public byte[] encode(byte[] data) { - return encode(data, 0, data.length); - } - - public byte[] encode(byte[] data, int offset, int length) { - if(unknownHeaderLines) { - return null; - } - int n = ((length / 3) * 4); - StringBuffer buf = new StringBuffer(headerLine.length() + - tailLine.length() + - n + (n / lineLen) + 512); - buf.append(headerLine); - buf.append(EOL); - - int headLen = buf.length(); - - buf.append(printHeaders()); - - if(blankHeaderSep && (headLen < buf.length())) { - buf.append(EOL); - } - - byte[] base64 = Base64.encode(data, offset, length); - for(int i = 0; i < base64.length; i += lineLen) { - int j = lineLen; - if(i + j > base64.length) - j = base64.length - i; - String line = new String(base64, i, j); - buf.append(line); - buf.append(EOL); - } - if(haveChecksum) { - // !!! TODO: - } - buf.append(tailLine); - buf.append(EOL); - - return buf.toString().getBytes(); - } - - public void encode(OutputStream out, byte[] data, int off, int len) - throws IOException - { - byte[] outData = encode(data, off, len); - out.write(outData); - } - - public void encode(OutputStream out, byte[] data) throws IOException { - encode(out, data, 0, data.length); - } - - public byte[] decode(byte[] data) { - return decode(data, 0, data.length); - } - - public byte[] decode(byte[] data, int offset, int length) { - String armourChunk = new String(data, offset, length); - StringTokenizer st = new StringTokenizer(armourChunk, "\n"); - boolean foundHeader = false; - boolean foundData = false; - boolean foundTail = false; - String line = ""; - while(!foundHeader && st.hasMoreTokens()) { - line = st.nextToken(); - if(line.startsWith(headerLine)) { - foundHeader = true; - if(unknownHeaderLines) { - headerLine = line; - } - } - } - headerFields = new Hashtable(); - String lastName = null; - while(!foundData && st.hasMoreTokens()) { - line = st.nextToken(); - if(lastName != null) { - String val = (String)headerFields.get(lastName); - headerFields.put(lastName, val + StringUtil.trimRight(line)); - lastName = null; - continue; - } - int i = line.indexOf(':'); - if(i < 0) { - foundData = true; - } else { - String name = line.substring(0, i).trim(); - String value = line.substring(i + 1).trim(); - if(value.length() > 0 && value.charAt(0) == '"' && - value.charAt(value.length() - 1) == '\\') { - lastName = name; - value = value.substring(0, value.length() - 1); - } - headerFields.put(name, value); - } - } - if(blankHeaderSep) { - // !!! - } - StringBuffer base64Data = new StringBuffer(); - while(!foundTail) { - if(line.startsWith(tailLine)) { - foundTail = true; - if(unknownHeaderLines) { - tailLine = line; - } - } else { - base64Data.append(line); - if(st.hasMoreTokens()) - line = st.nextToken(); - else - return null; - } - } - - data = Base64.decode(base64Data.toString().getBytes()); - - return data; - } - - public byte[] decode(InputStream in) throws IOException { - StringBuffer lineBuf = new StringBuffer(); - StringBuffer dataBuf = new StringBuffer(); - int found = 0; - int c; - while(found < 2) { - c = in.read(); - if(c == -1) - throw new IOException("Premature EOF, corrupt ascii-armour"); - if(c == '\r') - continue; - if(c != '\n') { - lineBuf.append((char)c); - } else { - String line = new String(lineBuf); - if(found == 0) { - if(line.startsWith(headerLine)) { - dataBuf.append(line); - dataBuf.append(EOL); - found++; - } - } else { - dataBuf.append(line); - dataBuf.append(EOL); - if(line.startsWith(tailLine)) { - found++; - } - } - lineBuf.setLength(0); - } - } - return decode(dataBuf.toString().getBytes()); - } - - public String printHeaders() { - Enumeration headerNames = fieldsOrder.elements(); - StringBuffer buf = new StringBuffer(); - while(headerNames.hasMoreElements()) { - String fieldName = (String)headerNames.nextElement(); - buf.append(fieldName); - buf.append(": "); - String val = (String)headerFields.get(fieldName); - if(val.length() > 0 && val.charAt(0) == '"' && - fieldName.length() + 2 + val.length() > lineLen) { - int n = lineLen - (fieldName.length() + 2); - buf.append(val.substring(0, n)); - buf.append("\\"); - buf.append(EOL); - val = val.substring(n); - } - buf.append(val); - buf.append(EOL); - } - return buf.toString(); - } - - /* !!! DEBUG - public static void main(String[] argv) { - byte[] data = "Hej svejs i lingonskogen!!!".getBytes(); - ASCIIArmour armour = - new ASCIIArmour("---- BEGIN GARBAGE ----", - "---- END GARBAGE ----"); - armour.setHeaderField("Subject", "mats"); - armour.setHeaderField("Comment", "\"this is a comment\""); - - byte[] encoded = armour.encode(data); - - System.out.println("Encoded block:"); - System.out.println(new String(encoded)); - - System.out.println("Decoded: " + new String(armour.decode(encoded))); - System.out.println("Headers:"); - System.out.println(armour.printHeaders()); - - encoded = ("---- BEGIN SSH2 PUBLIC KEY ----\r\n" + - "Subject: root\r\n" + - "Comment: \"host key for hal, accepted by root Mon Sep 20 1999 10:10:02 +0100\"\r\n" + - "AAAAB3NzaC1kc3MAAACBAKpCbpj86G+05T53tn6Y+tJ1N87Kx2RbQTDC48LWHYNRZ3c4He\r\n" + - "0tmQNFbyg14m/dYrdBI0GxPWQH0RYuyL5YLhBrcscmdz7Ca8buEgehcQULlAJ1P0gZ3hvW\r\n" + - "qru55vgU8O0kZVNGSsA+cmXRpq689W6RU0u9qaW03FNdeH7tTq/1AAAAFQDCLg54vUWNe0\r\n" + - "n5kMFnEH/DiV5dgQAAAIEAmlOAXHQ/3nrFDnLiTIfCkCvAj/P2rMQUViYXXi9cQ+Qd8Ie5\r\n" + - "TmyFJ6t9iJQZ6x3HlScGfQOJcD4h4ydxuXr+rRd6yi48kSB5/g3EscL+6+LMYdMGSGA2ni\r\n" + - "l1Vpjm49xZHxHlvTQ+KExk6Pcyb9D5zTW9uoOTBA08SPpYAlbZ4+MAAACAKEeiebGmZg5x\r\n" + - "sbxQt6HUPU3Cov9KeXw98qmn4Rr2ENWSTriwl8uxoD8wCuURHaJ61YX5spAj4QkVESqc7Y\r\n" + - "NBcZgpST0sUWCF0rNPZm8D6K0hgaUmtfrUJ6EzwxqfKH3YduMHFz5RSv492TSZvKKv+Ucb\r\n" + - "X4hEjfmP6SKc+Q4wGaQ=\r\n" + - "---- END SSH2 PUBLIC KEY ----\r\n").getBytes(); - armour = - new ASCIIArmour("---- BEGIN SSH2 PUBLIC KEY ----", - "---- END SSH2 PUBLIC KEY ----"); - - byte[] decoded = null; - try { - armour = - new ASCIIArmour("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----", - "---- END SSH2 ENCRYPTED PRIVATE KEY ----"); - decoded = armour.decode(new java.io.FileInputStream("/home/matsa/tstkey.prv")); - } catch (Exception e) { - System.out.println("Error: " + e); - } - - System.out.println("Decoded: "); - com.mindbright.util.HexDump.hexDump(decoded, 0, decoded.length); - System.out.println("Headers:"); - System.out.println(armour.printHeaders()); - - try { - java.io.FileOutputStream f = - new java.io.FileOutputStream("/home/matsa/tstkey2.prv"); - armour.setCanonicalLineEnd(false); - armour.encode(f, decoded); - f.close(); - } catch (Exception e) { - System.out.println("Error: " + e); - } - } - */ - -} diff --git a/src/main/java/com/mindbright/util/Base64.java b/src/main/java/com/mindbright/util/Base64.java deleted file mode 100644 index 5ee9e5f..0000000 --- a/src/main/java/com/mindbright/util/Base64.java +++ /dev/null @@ -1,129 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.util; - -public final class Base64 { - - private final static int[] fromBase64 = { - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 62, -1, -1, -1, 63, - 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, -1, -1, -1, -1, -1, -1, - -1, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, -1, -1, -1, -1, -1, - -1, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, -1, -1, -1, -1, -1 - }; - - private final static byte[] toBase64 = { - // 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - // 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99,100,101,102, - // 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', - 103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118, - // 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' - 119,120,121,122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, (byte)'=' - }; - - private final static int PAD_CHAR = 64; - - public static byte[] encode(byte[] data) { - return encode(data, 0, data.length); - } - - public static byte[] encode(byte[] data, int offset, int length) { - byte[] encoded; - int x1, x2, x3, x4; - int i, j, r, n; - - r = length % 3; - n = offset + (length - r); - encoded = new byte[((length / 3) * 4) + (r != 0 ? 4 : 0)]; - - for(i = offset, j = 0; i < n; i += 3, j += 4) { - x1 = (data[i] & 0xfc) >> 2; - x2 = (((data[i ] & 0x03) << 4) | ((data[i + 1] & 0xf0) >> 4)); - x3 = (((data[i + 1] & 0x0f) << 2) | ((data[i + 2] & 0xc0) >> 6)); - x4 = (data[i + 2] & 0x3f); - encoded[j ] = toBase64[x1]; - encoded[j + 1] = toBase64[x2]; - encoded[j + 2] = toBase64[x3]; - encoded[j + 3] = toBase64[x4]; - } - - if(r != 0) { - x1 = (data[i] & 0xfc) >> 2; - x2 = (data[i] & 0x03) << 4; - x3 = PAD_CHAR; - x4 = PAD_CHAR; - if(r == 2) { - x2 |= ((data[i + 1] & 0xf0) >> 4); - x3 = (data[i + 1] & 0x0f) << 2; - } - encoded[j++] = toBase64[x1]; - encoded[j++] = toBase64[x2]; - encoded[j++] = toBase64[x3]; - encoded[j++] = toBase64[x4]; - } - - return encoded; - } - - public static byte[] decode(byte[] data) { - return decode(data, 0, data.length); - } - - public static byte[] decode(byte[] encoded, int offset, int length) { - byte[] data; - int i, j, n, v = 0, c, bits = 0; - - n = offset + length; - data = new byte[(length * 3) / 4]; - - for(i = offset, j = 0; i < n; i++) { - c = fromBase64[encoded[i]]; - if(c < 0) { - if(encoded[i] == toBase64[PAD_CHAR]) - break; - continue; - } - v = (v << 6) | c; - bits += 6; - if(bits >= 8) { - bits -= 8; - data[j++] = (byte) ((v >> bits) & 0xff); - } - } - - if(data.length > j) { - byte[] tmp = new byte[j]; - System.arraycopy(data, 0, tmp, 0, j); - data = tmp; - } - - return data; - } - -} diff --git a/src/main/java/com/mindbright/util/CRC32.java b/src/main/java/com/mindbright/util/CRC32.java deleted file mode 100644 index bbc0f2e..0000000 --- a/src/main/java/com/mindbright/util/CRC32.java +++ /dev/null @@ -1,87 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.util; - -public final class CRC32 { - - public static final long crc32_tab[] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL - }; - - public static long getValue(byte[] buf, int off, int len) { - long crc32val; - int i; - - crc32val = 0; - for (i = 0; i < len; i ++) { - crc32val = crc32_tab[(int)((crc32val ^ buf[off + i]) & 0xff)] ^ (crc32val >> 8); - } - - return crc32val; - } - -} diff --git a/src/main/java/com/mindbright/util/EncryptedProperties.java b/src/main/java/com/mindbright/util/EncryptedProperties.java deleted file mode 100644 index 55ab48a..0000000 --- a/src/main/java/com/mindbright/util/EncryptedProperties.java +++ /dev/null @@ -1,188 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.util; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.ByteArrayOutputStream; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.Properties; -import java.util.Enumeration; - -import com.mindbright.jca.security.MessageDigest; - -// !!! TODO, change this to real cipher -import com.mindbright.ssh.SSHCipher; -import com.mindbright.ssh.SSHAccessDeniedException; - -public class EncryptedProperties extends Properties { - public final static String HASH_KEY = "EncryptedProperties.hash"; - public final static String CIPHER_KEY = "EncryptedProperties.cipher"; - public final static String CONTENTS_KEY = "EncryptedProperties.contents"; - public final static String SIZE_KEY = "EncryptedProperties.size"; - public final static String PROPS_HEADER = "Sealed with com.mindbright.util.EncryptedProperties" + - "(ver. $Name: $" + "$Date: 2001/09/17 09:35:44 $)"; - - private boolean isNormalPropsFile; - - public EncryptedProperties() { - super(); - isNormalPropsFile = false; - } - - public EncryptedProperties(Properties defaultProperties) { - super(defaultProperties); - isNormalPropsFile = false; - } - - public boolean isNormalPropsFile() { - return isNormalPropsFile; - } - - public synchronized void save(OutputStream out, String header, String password, - String cipherName) throws IOException { - ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); - Properties encProps = new Properties(); - byte[] contents, hash; - String hashStr; - SSHCipher cipher = SSHCipher.getInstance(cipherName); - int size; - - if(cipher == null) - throw new IOException("Unknown cipher '" + cipherName + "'"); - - save(bytesOut, header); - - contents = bytesOut.toByteArray(); - size = contents.length; - try { - MessageDigest md5 = MessageDigest.getInstance("MD5"); - md5.update(contents); - hash = md5.digest(); - } catch(Exception e) { - throw new IOException("MD5 not implemented, can't generate session-id"); - } - - hash = Base64.encode(hash); - hashStr = new String(hash); - - // Assume cipher-block length no longer than 8 - // - byte[] tmp = new byte[contents.length + (8 - (contents.length % 8))]; - System.arraycopy(contents, 0, tmp, 0, contents.length); - contents = new byte[tmp.length]; - - cipher.setKey(hashStr + password); - cipher.encrypt(tmp, 0, contents, 0, contents.length); - - contents = Base64.encode(contents); - - encProps.put(HASH_KEY, new String(hash)); - encProps.put(CIPHER_KEY, cipherName.substring(3)); // !!! Cut pre 'SSH' - encProps.put(CONTENTS_KEY, new String(contents)); - encProps.put(SIZE_KEY, String.valueOf(size)); - encProps.save(out, PROPS_HEADER); - out.flush(); - } - - public synchronized void load(InputStream in, String password) throws IOException, SSHAccessDeniedException { - Properties encProps = new Properties(); - String hashStr, cipherName, contentsStr, sizeStr; - byte[] contents, hash, hashCalc; - SSHCipher cipher; - int size; - - encProps.load(in); - - hashStr = encProps.getProperty(HASH_KEY); - cipherName = "SSH" + encProps.getProperty(CIPHER_KEY); - contentsStr = encProps.getProperty(CONTENTS_KEY); - sizeStr = encProps.getProperty(SIZE_KEY); - - // Assume normal properties if our keys are not found (i.e. for - // "backwards compatible" reading of properties which will be encrypted - // if saved) - // - if(hashStr == null || cipherName == null || - contentsStr == null || sizeStr == null) { - isNormalPropsFile = true; - Enumeration keys = encProps.keys(); - while(keys.hasMoreElements()) { - String key = (String)keys.nextElement(); - put(key, encProps.getProperty(key)); - } - return; - } - - size = Integer.parseInt(sizeStr); - - hash = Base64.decode(hashStr.getBytes()); - contents = Base64.decode(contentsStr.getBytes()); - - cipher = SSHCipher.getInstance(cipherName); - if(cipher == null) - throw new IOException("Unknown cipher '" + cipherName + "'"); - - cipher.setKey(hashStr + password); - cipher.decrypt(contents, 0, contents, 0, contents.length); - - byte[] tmp = new byte[size]; - System.arraycopy(contents, 0, tmp, 0, size); - contents = tmp; - - try { - MessageDigest md5 = MessageDigest.getInstance("MD5"); - md5.update(contents); - hashCalc = md5.digest(); - } catch(Exception e) { - throw new IOException("MD5 not implemented, can't generate session-id"); - } - - for(int i = 0; i < hash.length; i++) { - if(hash[i] != hashCalc[i]) - throw new SSHAccessDeniedException("Access denied"); - } - - ByteArrayInputStream bytesIn = new ByteArrayInputStream(contents); - load(bytesIn); - } - - /* !!! DEBUG - public static void main(String[] argv) { - EncryptedProperties test = new EncryptedProperties(); - - test.put("Foo", "bar"); - test.put("foo", "bAR"); - test.put("bar", "FOO"); - test.put("BAR", "foo"); - - try { - test.save(new java.io.FileOutputStream("/tmp/fooprops"), "These are some meaningless props...", - "foobar", "Blowfish"); - test = new EncryptedProperties(); - test.load(new java.io.FileInputStream("/tmp/fooprops"), "foobar"); - - System.out.println("test: " + test.getProperty("BAR") + test.getProperty("Foo")); - - } catch (Exception e) { - System.out.println("Error:" + e); - e.printStackTrace(); - } - } - */ - -} diff --git a/src/main/java/com/mindbright/util/HexDump.java b/src/main/java/com/mindbright/util/HexDump.java deleted file mode 100644 index a4573a2..0000000 --- a/src/main/java/com/mindbright/util/HexDump.java +++ /dev/null @@ -1,130 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.util; - -import java.math.BigInteger; - -public class HexDump { - - /* hexadecimal digits. - */ - private static final char[] HEX_DIGITS = { - '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' - }; - - /** - * Returns a string of 8 hexadecimal digits (most significant - * digit first) corresponding to the integer n, which is - * treated as unsigned. - */ - public static String intToString (int n) { - char[] buf = new char[8]; - for(int i = 7; i >= 0; i--) { - buf[i] = HEX_DIGITS[n & 0x0F]; - n >>>= 4; - } - return new String(buf); - } - - /** - * Returns a string of hexadecimal digits from a byte array. Each - * byte is converted to 2 hex symbols. - */ - public static String toString(byte[] ba) { - return toString(ba, 0, ba.length); - } - - public static String toString(byte[] ba, int offset, int length) { - char[] buf = new char[length * 2]; - for(int i = offset, j = 0, k; i < offset+length; ) { - k = ba[i++]; - buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F]; - buf[j++] = HEX_DIGITS[ k & 0x0F]; - } - return new String(buf); - } - - public static String formatHex(int i, int sz) { - String str = Integer.toHexString(i); - while(str.length() < sz) { - str = "0" + str; - } - return str; - } - - public static void print(byte[] buf, int off, int len) { - print(null, true, buf, off, len); - } - - public static synchronized void print(String header, boolean showAddr, - byte[] buf, int off, int len) - { - int i, j, jmax; - int c; - - if(header != null) { - System.out.println(header); - } - - for(i = 0; i < len; i += 0x10) { - StringBuffer line = new StringBuffer(); - - if(showAddr) { - line.append(formatHex(i + off, 8)); - line.append(": "); - } - - jmax = len - i; - jmax = jmax > 16 ? 16 : jmax; - - for(j = 0; j < jmax; j++) { - c = ((int)buf[off+i+j] + 0x100) % 0x100; - line.append(formatHex(c, 2)); - if ((j % 2) == 1) - line.append(" "); - } - - for(; j < 16; j++) { - line.append(" "); - if ((j % 2) == 1) - line.append(" "); - } - - line.append(" "); - - for(j = 0; j < jmax; j++) { - c = ((int)buf[off+i+j] + 0x100) % 0x100; - c = c < 32 || c >= 127 ? '.' : c; - line.append((char)c); - } - - System.out.println(line.toString()); - } - } - - public static void print(byte[] buf) { - print(buf, 0, buf.length); - } - - public static void print(BigInteger bi) { - byte[] raw = bi.toByteArray(); - if(raw.length == 1 && raw[0] == (byte)0x00) - raw = new byte[0]; - print(raw); - } - - -} diff --git a/src/main/java/com/mindbright/util/InputStreamPipe.java b/src/main/java/com/mindbright/util/InputStreamPipe.java deleted file mode 100644 index 47ef1e4..0000000 --- a/src/main/java/com/mindbright/util/InputStreamPipe.java +++ /dev/null @@ -1,286 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.util; - -import java.io.InputStream; -import java.io.IOException; - -public final class InputStreamPipe extends InputStream { - - private static final int DEFAULT_BUFFER_SIZE = 8192; - - private OutputStreamPipe source; - private byte[] circBuf; - private int rOffset; - private int wOffset; - private boolean isWaitGet; - private boolean isWaitPut; - private boolean eof; - private boolean closed; - - public InputStreamPipe(int bufferSize) { - this.circBuf = new byte[bufferSize]; - this.isWaitGet = false; - this.isWaitPut = false; - this.rOffset = 0; - this.wOffset = 0; - } - - public InputStreamPipe() { - this(DEFAULT_BUFFER_SIZE); - } - - public InputStreamPipe(OutputStreamPipe source) throws IOException { - this(); - connect(source); - } - - public void connect(OutputStreamPipe source) throws IOException { - if(this.source == source) { - return; - } - if(this.source != null) { - throw new IOException("Pipe already connected"); - } - this.source = source; - source.connect(this); - } - - public synchronized int read() throws IOException { - while(isEmpty()) { - if(closed) { - throw new IOException("InputStreamPipe closed"); - } - if(eof) { - return -1; - } - isWaitGet = true; - try { - this.wait(); - } catch (InterruptedException e) { - // !!! - } - } - isWaitGet = false; - - int b = (circBuf[rOffset++] & 0xff); - - if(rOffset == circBuf.length) - rOffset = 0; - - if(isWaitPut) { - this.notifyAll(); - isWaitPut = false; - } - - return b; - } - - public synchronized int read(byte[] buf, int off, int len) - throws IOException - { - while(isEmpty()) { - if(closed) { - throw new IOException("InputStreamPipe closed"); - } - if(eof) { - return -1; - } - isWaitGet = true; - try { - this.wait(); - } catch (InterruptedException e) { - // !!! - } - } - isWaitGet = false; - - int n = available(); - n = (n > len ? len : n); - - if(rOffset < wOffset) { - System.arraycopy(circBuf, rOffset, buf, off, n); - } else { - int rest = circBuf.length - rOffset; - if(rest < n) { - System.arraycopy(circBuf, rOffset, buf, off, rest); - System.arraycopy(circBuf, 0, buf, off + rest, n - rest); - } else { - System.arraycopy(circBuf, rOffset, buf, off, n); - } - } - - rOffset += n; - if(rOffset >= circBuf.length) - rOffset -= circBuf.length; - - if(isWaitPut) { - this.notifyAll(); - isWaitPut = false; - } - - return n; - } - - public int available() { - return circBuf.length - freeSpace() - 1; - } - - public synchronized void close() throws IOException { - closed = true; - this.notifyAll(); - } - - public synchronized void flush() { - this.notifyAll(); - } - - protected synchronized void put(int b) throws IOException { - putFlowControl(); - circBuf[wOffset++] = (byte)b; - if(wOffset == circBuf.length) - wOffset = 0; - if(isWaitGet) - this.notify(); - } - - protected synchronized void put(byte[] buf, int off, int len) - throws IOException - { - while(len > 0) { - putFlowControl(); - int n = freeSpace(); - n = (n > len ? len : n); - - if(wOffset < rOffset) { - System.arraycopy(buf, off, circBuf, wOffset, n); - } else { - int rest = circBuf.length - wOffset; - if(rest < n) { - System.arraycopy(buf, off, circBuf, wOffset, rest); - System.arraycopy(buf, off + rest, circBuf, 0, n - rest); - } else { - System.arraycopy(buf, off, circBuf, wOffset, n); - } - } - - wOffset += n; - if(wOffset >= circBuf.length) { - wOffset -= circBuf.length; - } - len -= n; - off += n; - - if(isWaitGet) - this.notify(); - } - } - - protected synchronized void eof() { - eof = true; - this.notify(); - } - - private int freeSpace() { - int fSpc = rOffset - wOffset; - if(fSpc <= 0) - fSpc += circBuf.length; - fSpc--; - return fSpc; - } - - private synchronized boolean isEmpty() { - return (rOffset == wOffset) || closed; - } - - private void putFlowControl() throws IOException { - if(eof) { - throw new IOException("InputStreamPipe already got eof"); - } - if(closed) { - throw new IOException("InputStreamPipe closed"); - } - int fs = freeSpace(); - isWaitPut = (fs == 0); - if(isWaitPut) { - try { - this.wait(); - } catch (InterruptedException e) { - // !!! - } - } - } - - /* DEBUG/Test - public static void main(String[] argv) { - try { - final InputStreamPipe in = new InputStreamPipe(); - final OutputStreamPipe out = new OutputStreamPipe(in); - //final java.io.PipedInputStream in = new java.io.PipedInputStream(); - //final java.io.PipedOutputStream out = new java.io.PipedOutputStream(in); - - final byte[] msg = new byte[4711]; - for(int i = 0; i < 4711; i++) { - msg[i] = (byte)((i * i) ^ (i + i)); - } - Thread w = new Thread(new Runnable() { - public void run() { - try { - for(int i = 0; i < 1000; i++) { - out.write(msg); - } - } catch (IOException e) { - System.out.println("Error in w: " + e); - e.printStackTrace(); - } - } - }); - Thread r = new Thread(new Runnable() { - public void run() { - try { - byte[] imsg = new byte[4711]; - for(int i = 0; i < 1000; i++) { - int l = 4711; - int o = 0; - while(o < 4711) { - int n = in.read(imsg, o, l); - o += n; - l -= n; - } - } - } catch (IOException e) { - System.out.println("Error in w: " + e); - e.printStackTrace(); - } - } - }); - long start = System.currentTimeMillis(); - System.out.println("Start: " + (start / 1000)); - w.start(); - r.start(); - r.join(); - long now = System.currentTimeMillis(); - System.out.println("End: " + (now / 1000)); - System.out.println("Lapsed: " + (now - start)); - - } catch (Exception e) { - System.out.println("Error: " + e); - e.printStackTrace(); - } - } - */ - -} diff --git a/src/main/java/com/mindbright/util/Log.java b/src/main/java/com/mindbright/util/Log.java deleted file mode 100644 index 53953c8..0000000 --- a/src/main/java/com/mindbright/util/Log.java +++ /dev/null @@ -1,94 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.util; - -public class Log { - public final static int LEVEL_EMERG = 0; - public final static int LEVEL_ALERT = 1; - public final static int LEVEL_ERROR = 2; - public final static int LEVEL_WARNING = 3; - public final static int LEVEL_NOTICE = 4; - public final static int LEVEL_INFO = 5; - public final static int LEVEL_DEBUG = 6; - public final static int LEVEL_DEBUG2 = 7; - - volatile int currentLevel = 0; - - public Log(int level) { - this.currentLevel = level; - } - - public void message(int level, String callClass, String message) { - message(level, callClass, null, message); - } - - public synchronized void message(int level, String callClass, - String callMethod, - String message) { - if(level <= currentLevel) { - String methStr = (callMethod != null ? "." + callMethod + "()" : - ""); - System.err.println("** " + callClass + methStr + " : '" + - message + "'"); - } - } - - public void error(String callClass, String callMethod, String message) { - message(LEVEL_ERROR, callClass, callMethod, message); - } - - public void warning(String callClass, String message) { - message(LEVEL_ERROR, callClass, null, message); - } - - public void notice(String callClass, String message) { - message(LEVEL_NOTICE, callClass, null, message); - } - - public void info(String callClass, String message) { - message(LEVEL_INFO, callClass, null, message); - } - - public void debug(String callClass, String callMethod, String message) { - message(LEVEL_DEBUG, callClass, callMethod, message); - } - - public void debug(String callClass, String message) { - message(LEVEL_DEBUG, callClass, null, message); - } - - public void debug2(String callClass, String callMethod, String message) { - message(LEVEL_DEBUG2, callClass, callMethod, message); - } - - public synchronized void debug2(String callClass, String callMethod, - String message, - byte[] dumpBuf, int off, int len) { - message(LEVEL_DEBUG2, callClass, callMethod, message); - if(currentLevel == LEVEL_DEBUG2) { - HexDump.print(dumpBuf, off, len); - } - } - - public void debug2(String callClass, String callMethod, String message, - byte[] dumpBuf) { - debug2(callClass, callMethod, message, dumpBuf, 0, dumpBuf.length); - } - - public void setLevel(int level) { - currentLevel = level; - } -} diff --git a/src/main/java/com/mindbright/util/Math.java b/src/main/java/com/mindbright/util/Math.java deleted file mode 100644 index 6c8f90e..0000000 --- a/src/main/java/com/mindbright/util/Math.java +++ /dev/null @@ -1,137 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.util; - -import java.math.BigInteger; - -import com.mindbright.jca.security.SecureRandom; - -public final class Math { - - public static BigInteger findRandomGenerator(BigInteger order, - BigInteger modulo, - SecureRandom random) { - BigInteger one = BigInteger.valueOf(1); - BigInteger aux = modulo.subtract(BigInteger.valueOf(1)); - BigInteger t = aux.mod(order); - BigInteger generator; - - if(t.longValue() != 0) { - return null; - } - - t = aux.divide(order); - - while(true) { - generator = new BigInteger(modulo.bitLength(), random); - generator = generator.mod(modulo); - generator = generator.modPow(t, modulo); - if(generator.compareTo(one) != 0) - break; - } - - aux = generator.modPow(order, modulo); - - if(aux.compareTo(one) != 0) { - return null; - } - - return generator; - } - - public static BigInteger[] findRandomStrongPrime(int primeBits, - int orderBits, - SecureRandom random) { - BigInteger one = BigInteger.valueOf(1); - BigInteger u, aux, aux2, t; - long[] table_q, table_u, prime_table; - PrimeSieve sieve = new PrimeSieve(16000); - int table_count = sieve.availablePrimes() - 1; - int i, j; - boolean flag; - BigInteger prime = null, order = null; - - order = new BigInteger(orderBits, 20, random); - - prime_table = new long[table_count]; - table_q = new long[table_count]; - table_u = new long[table_count]; - - i = 0; - for(int pN = 2; pN != 0; pN = sieve.getNextPrime(pN), i++) { - prime_table[i] = (long)pN; - } - - for(i = 0; i < table_count; i++) { - table_q[i] = - (order.mod(BigInteger.valueOf(prime_table[i])).longValue() * - (long)2) % prime_table[i]; - } - - while(true) { - u = new BigInteger(primeBits, random); - u.setBit(primeBits - 1); - aux = order.shiftLeft(1); - aux2 = u.mod(aux); - u = u.subtract(aux2); - u = u.add(one); - - if(u.bitLength() <= (primeBits - 1)) - continue; - - for(j = 0; j < table_count; j++) { - table_u[j] = - u.mod(BigInteger.valueOf(prime_table[j])).longValue(); - } - - aux2 = order.shiftLeft(1); - - for(i = 0; i < (1 << 24); i++) { - long cur_p; - long value; - - flag = true; - for(j = 1; j < table_count; j++) { - cur_p = prime_table[j]; - value = table_u[j]; - if(value >= cur_p) - value -= cur_p; - if(value == 0) - flag = false; - table_u[j] = value + table_q[j]; - } - if(!flag) - continue; - - aux = aux2.multiply(BigInteger.valueOf(i)); - prime = u.add(aux); - - if(prime.bitLength() > primeBits) - continue; - - if(prime.isProbablePrime(20)) - break; - } - - if(i < (1 << 24)) - break; - } - - return new BigInteger[] { prime, order }; - } - -} - diff --git a/src/main/java/com/mindbright/util/OutputStreamPipe.java b/src/main/java/com/mindbright/util/OutputStreamPipe.java deleted file mode 100644 index 2c6d530..0000000 --- a/src/main/java/com/mindbright/util/OutputStreamPipe.java +++ /dev/null @@ -1,60 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.util; - -import java.io.OutputStream; -import java.io.IOException; - -public final class OutputStreamPipe extends OutputStream { - - private InputStreamPipe sink; - - public OutputStreamPipe(InputStreamPipe sink) throws IOException { - connect(sink); - } - - public OutputStreamPipe() { - } - - public void connect(InputStreamPipe sink) throws IOException { - if(this.sink == sink) { - return; - } - if(this.sink != null) { - throw new IOException("Already connected"); - } - this.sink = sink; - } - - public void write(int b) throws IOException { - sink.put(b); - } - - public void write(byte b[], int off, int len) throws IOException { - sink.put(b, off, len); - } - - public void flush() { - if(sink != null) { - sink.flush(); - } - } - - public void close() throws IOException { - sink.eof(); - } - -} diff --git a/src/main/java/com/mindbright/util/PrimeSieve.java b/src/main/java/com/mindbright/util/PrimeSieve.java deleted file mode 100644 index 4b98a7b..0000000 --- a/src/main/java/com/mindbright/util/PrimeSieve.java +++ /dev/null @@ -1,102 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.util; - -public final class PrimeSieve { - - public final static byte[] bitCounts = { - 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,1, - 2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,1,2, - 2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3, - 4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,1,2,2,3, - 2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3,4,3, - 4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,2,3,3,4,3,4, - 4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,3,4,4,5,4,5,5, - 6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 - }; - - int[] table; - - public PrimeSieve(int x) { - if(x < 4) - x = 4; - - int len = (x - 3) / (32 * 2); - table = new int[len]; - - int max = len * 32; - int stop = (int)java.lang.Math.sqrt((double)max) + 1; - for(int i = 0; i < stop ; i++) { - if((table[i / 32] & (1 << (i & (32 - 1)))) == 0) { - int k = 3 + i * 2; - for (int j = i + k; j < max; j += k) { - table[j / 32] |= (1 << (j & (32 - 1))); - } - } - } - } - - public int availablePrimes() { - int i, bits, w, primes; - for(i = 0, primes = 2; i < table.length; i++) { - w = table[i]; - for(bits = 0; w != 0; w >>>= 8) { - bits += (int)bitCounts[w & 0xff]; - } - primes += (32 - bits); - } - return primes; - } - - public int getNextPrime(int x) { - int p = ((x - 3) / 2) + 1; - switch (x) { - /* Trivial cases. */ - case 0: - return 2; - case 1: - return 2; - case 2: - return 3; - /* Cases above 2 are handled with the table. */ - default: - while(true) { - if((p / 32) >= table.length) - return 0; - - if((table[p / 32] & (1 << (p & (32 - 1)))) == 0) - return p * 2 + 3; - p++; - } - } - } - - /* - public static void main(String[] argv) { - PrimeSieve primes = new PrimeSieve(100); - int n = primes.availablePrimes(); - System.out.println("num of primes: " + n - 1); - int p = 2; - int i; - for(i = 0; p != 0; i++) { - System.out.println(p); - p = primes.getNextPrime(p); - } - System.out.println("i = " + i); - } - */ - -} diff --git a/src/main/java/com/mindbright/util/Progress.java b/src/main/java/com/mindbright/util/Progress.java deleted file mode 100644 index 8e1e9a2..0000000 --- a/src/main/java/com/mindbright/util/Progress.java +++ /dev/null @@ -1,20 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.util; - -public interface Progress { - public void progress(int value); -} diff --git a/src/main/java/com/mindbright/util/Queue.java b/src/main/java/com/mindbright/util/Queue.java deleted file mode 100644 index 7ecdc59..0000000 --- a/src/main/java/com/mindbright/util/Queue.java +++ /dev/null @@ -1,167 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.util; - -public final class Queue { - - final static int QUEUE_DEPTH = 256; - final static int QUEUE_HIWATER = 192; - - Object[] queue; - boolean isWaitGet; - boolean isWaitPut; - boolean isBlocking; - int rOffset; - int wOffset; - int maxQueueDepth; - - // Copies used for saving real values when disabling queue - // - int rOffsetCP; - int wOffsetCP; - int maxQueueDepthCP; - - public Queue() { - this.queue = new Object[QUEUE_DEPTH + 1]; - this.isWaitGet = false; - this.isWaitPut = false; - this.isBlocking = true; - this.rOffset = 0; - this.wOffset = 0; - this.maxQueueDepth = QUEUE_DEPTH; - } - - public synchronized void setMaxDepth(int maxDepth) { - maxQueueDepth = maxDepth; - } - - public synchronized void putLast(Object obj) { - putFlowControl(); - queue[wOffset++] = obj; - if(wOffset == (QUEUE_DEPTH + 1)) - wOffset = 0; - if(isWaitGet) - this.notify(); - } - - public synchronized void putFirst(Object obj) { - putFlowControl(); - rOffset--; - if(rOffset == -1) - rOffset = QUEUE_DEPTH; - queue[rOffset] = obj; - if(isWaitGet) - this.notify(); - } - - public synchronized void release() { - if(isWaitGet) - this.notify(); - } - - public synchronized void disable() { - rOffsetCP = rOffset; - wOffsetCP = wOffset; - maxQueueDepthCP = maxQueueDepth; - rOffset = 0; - wOffset = 0; - maxQueueDepth = 0; - } - - public synchronized void enable() { - rOffset = rOffsetCP; - wOffset = wOffsetCP; - maxQueueDepth = maxQueueDepthCP; - if(!isEmpty()) { - this.release(); - } - if(isWaitPut && (freeSpace() > (QUEUE_DEPTH - QUEUE_HIWATER))) { - this.notifyAll(); - isWaitPut = false; - } - } - - public synchronized boolean isBlocked() { - return isWaitGet; - } - - public void waitUntilBlocked() { - blockLoop: - while(!isBlocked()) { - try { - Thread.sleep(100); - } catch (InterruptedException e) { - break blockLoop; - } - } - } - - public synchronized void setBlocking(boolean block) { - isBlocking = block; - release(); - } - - public synchronized boolean isEmpty() { - return (rOffset == wOffset); - } - - private final void putFlowControl() { - int fs = freeSpace(); - if(fs == (QUEUE_DEPTH - maxQueueDepth)) { - isWaitPut = true; - } - if(isWaitPut) { - try { - this.wait(); - } catch (InterruptedException e) { - // !!! - } - } - } - - private final int freeSpace() { - int fSpc = rOffset - wOffset; - if(fSpc <= 0) - fSpc += (QUEUE_DEPTH + 1); - fSpc--; - return fSpc; - } - - public synchronized Object getFirst() { - Object obj = null; - while(isEmpty()) { - if(!isBlocking) { - return null; - } - isWaitGet = true; - try { - this.wait(); - } catch (InterruptedException e) { - // !!! - } - } - isWaitGet = false; - obj = queue[rOffset]; - queue[rOffset++] = null; - if(rOffset == (QUEUE_DEPTH + 1)) - rOffset = 0; - if(isWaitPut && (freeSpace() > (QUEUE_DEPTH - QUEUE_HIWATER))) { - this.notifyAll(); - isWaitPut = false; - } - return obj; - } -} diff --git a/src/main/java/com/mindbright/util/RandomSeed.java b/src/main/java/com/mindbright/util/RandomSeed.java deleted file mode 100644 index a30f507..0000000 --- a/src/main/java/com/mindbright/util/RandomSeed.java +++ /dev/null @@ -1,423 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.util; - -import java.io.PrintWriter; -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.InputStream; -import java.io.File; -import java.io.IOException; -import java.net.InetAddress; -import java.util.Properties; -import java.util.Enumeration; - -import java.awt.Component; -import java.awt.event.MouseMotionListener; -import java.awt.event.MouseListener; -import java.awt.event.KeyListener; -import java.awt.event.FocusListener; -import java.awt.event.ComponentListener; -import java.awt.event.ComponentEvent; -import java.awt.event.KeyEvent; -import java.awt.event.MouseEvent; -import java.awt.event.FocusEvent; - -import com.mindbright.jca.security.MessageDigest; - -public final class RandomSeed - implements MouseMotionListener, MouseListener, - KeyListener, FocusListener, ComponentListener -{ - private InputStream devRand; - private InputStream devURand; - private String devRandName; - private String devURandName; - private byte[] entropyPool; - private int entropyRIdx; - private int entropyWIdx; - private volatile int entropyCount; - - private boolean haveEntropyGenerator; - - private long tickT; - private int evtCnt; - private int mouseCnt; - private int evtHash; - private int keyHash; - private int mouseHash; - private int lastX; - private int lastY; - - private Progress progress; - - private static class Sleeper extends Thread { - long sleepTime; - - public Sleeper(long sleepTime) { - this.sleepTime = sleepTime; - this.start(); - } - - public void run() { - Thread.yield(); - try { - Thread.sleep(sleepTime); - } catch (InterruptedException ex) { - } - } - } - - public RandomSeed() { - init(); - // Generate 64 bits of entropy as default - for(int i = 0; i < 16; i++) { - addEntropyBits((byte)spin(8), 4); - } - } - - public RandomSeed(String devRandName, String devURandName) { - init(); - this.devRandName = devRandName; - this.devURandName = devURandName; - this.devRand = openRandFile(devRandName); - this.devURand = openRandFile(devURandName); - } - - private void init() { - entropyPool = new byte[1200]; - entropyCount = 16; - entropyRIdx = 0; - entropyWIdx = 0; - tickT = 0L; - evtCnt = 0; - mouseCnt = 0; - devRand = null; - devURand = null; - progress = null; - byte[] sysState = getSystemStateHash(); - System.arraycopy(sysState, 0, entropyPool, 0, sysState.length); - } - - private InputStream openRandFile(String name) { - InputStream in = null; - try { - File file = new File(name); - if(file.exists() && file.canRead()) { - in = new FileInputStream(file); - } - } catch (Throwable t) { - in = null; - } - return in; - } - - public void addProgress(Progress progress) { - this.progress = progress; - } - - public void removeProgress() { - this.progress = null; - } - - // !!! TODO, handle removal of generator - public void addEntropyGenerator(Component c) { - c.addComponentListener(this); - c.addKeyListener(this); - c.addFocusListener(this); - c.addMouseMotionListener(this); - c.addMouseListener(this); - haveEntropyGenerator = true; - } - - public void addEntropyBits(byte bits, int count) { - entropyPool[entropyWIdx++] ^= bits; - if(entropyWIdx == entropyPool.length) { - entropyWIdx = 0; - } - entropyCount += count; - if(progress != null) { - progress.progress(entropyCount); - } - } - - public boolean haveDevRandom() { - return (devRand != null); - } - - public boolean haveDevURandom() { - return (devURand != null); - } - - public boolean haveEntropyGenerator() { - return haveEntropyGenerator; - } - - public int getAvailableBits() { - return entropyCount; - } - - public void resetEntropyCount() { - entropyCount = 0; - } - - public byte[] getBytes(int numBytes) { - if(haveDevURandom()) { - try { - for(int i = 0; i < numBytes; i++) { - int bits = devURand.read(); - addEntropyBits((byte)bits, 8); - } - } catch (IOException e) { - throw new Error("Error reading '" + devURandName + "'"); - } - } - - return getBytesInternal(numBytes); - } - - public byte[] getBytesBlocking(int numBytes) { - return getBytesBlocking(numBytes, true); - } - - public byte[] getBytesBlocking(int numBytes, boolean generatorIfPresent) { - int bits = (numBytes * 8); - while(entropyCount < bits) { - if(haveDevRandom()) { - try { - int b = devRand.read(); - addEntropyBits((byte)b, 8); - } catch (IOException e) { - throw new Error("Error reading '" + devRandName + "'"); - } - } else if(generatorIfPresent && haveEntropyGenerator) { - try { - Thread.sleep(500); - } catch (InterruptedException ex) { - } - } else { - addEntropyBits((byte)spin(8), 4); - } - } - - return getBytesInternal(numBytes); - } - - private byte[] getBytesInternal(int numBytes) { - MessageDigest sha1 = null; - try { - sha1 = MessageDigest.getInstance("SHA1"); - } catch (Exception e) { - throw new Error("Error in RandomSeed, no sha1 hash"); - } - - int curLen = 0; - byte[] bytes = new byte[numBytes]; - int offset = entropyRIdx; - while(curLen < numBytes) { - sha1.update((byte)System.currentTimeMillis()); - sha1.update(entropyPool, offset, 40); // estimate 4 bits/byte - sha1.update((byte)evtCnt); - byte[] material = sha1.digest(); - System.arraycopy(material, 0, bytes, curLen, - ((numBytes - curLen > material.length) ? - material.length : (numBytes - curLen))); - curLen += material.length; - offset += 40; - offset %= entropyPool.length; - } - - entropyRIdx = offset; - entropyCount -= (numBytes * 8); - if(entropyCount < 0) { - entropyCount = 0; - } - - return bytes; - } - - public static byte[] getSystemStateHash() { - MessageDigest sha1; - try { - sha1 = MessageDigest.getInstance("SHA1"); - } catch (Exception e) { - throw new Error("Error in RandomSeed, no sha1 hash"); - } - - sha1.update((byte)System.currentTimeMillis()); - sha1.update((byte)Runtime.getRuntime().totalMemory()); - sha1.update((byte)Runtime.getRuntime().freeMemory()); - sha1.update(stackDump(new Throwable())); - - try { - Properties props = System.getProperties(); - Enumeration names = props.propertyNames(); - while(names.hasMoreElements()) { - String name = (String)names.nextElement(); - sha1.update(name.getBytes()); - sha1.update(props.getProperty(name).getBytes()); - } - } catch (Throwable t) { - sha1.update(stackDump(t)); - } - sha1.update((byte)System.currentTimeMillis()); - - try { - sha1.update(InetAddress.getLocalHost().toString().getBytes()); - } catch (Throwable t) { - sha1.update(stackDump(t)); - } - sha1.update((byte)System.currentTimeMillis()); - - Runtime.getRuntime().gc(); - sha1.update((byte)Runtime.getRuntime().freeMemory()); - sha1.update((byte)System.currentTimeMillis()); - - return sha1.digest(); - } - - public static int spin(long t) { - int counter = 0; - Sleeper s = new Sleeper(t); - do { - counter++; - Thread.yield(); - } while(s.isAlive()); - return counter; - } - - public void keyPressed(KeyEvent e) { - keyHash ^= e.getModifiers(); - keyHash += (e.getKeyCode() ^ evtHash); - eventTick(e); - } - - public void keyReleased(KeyEvent e) { - eventTick(e); - } - - public void keyTyped(KeyEvent e) { - keyHash ^= e.getKeyChar(); - keyHash ^= e.hashCode(); - if((evtCnt % 7) == 0) { - addEntropyBits((byte)keyHash, 4); - } - } - - public void componentHidden(ComponentEvent e) { - eventTick(e); - } - - public void componentMoved(ComponentEvent e) { - eventTick(e); - } - - public void componentResized(ComponentEvent e) { - eventTick(e); - } - - public void componentShown(ComponentEvent e) { - eventTick(e); - } - - public void focusGained(FocusEvent e) { - eventTick(e); - } - - public void focusLost(FocusEvent e) { - eventTick(e); - } - - public void mouseClicked(MouseEvent e) { - eventTick(e); - } - - public void mouseEntered(MouseEvent e) { - eventTick(e); - } - - public void mouseExited(MouseEvent e) { - eventTick(e); - } - - public void mousePressed(MouseEvent e) { - eventTick(e); - } - - public void mouseReleased(MouseEvent e) { - eventTick(e); - } - - public void mouseDragged(MouseEvent e) { - mouseMoved(e); - } - - public void mouseMoved(MouseEvent e) { - mouseCnt++; - int dX = lastX - e.getX(); - int dY = lastY - e.getY(); - lastX = e.getX(); - lastY = e.getY(); - - mouseHash ^= e.hashCode(); - mouseHash ^= e.getX(); - mouseHash ^= dY; - mouseHash ^= e.getY(); - mouseHash ^= dX; - - if((mouseCnt % 3) == 0) { - addEntropyBits((byte)mouseHash, 4); - } - } - - public static byte[] stackDump(Throwable t) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - PrintWriter pw = new PrintWriter(baos); - t.printStackTrace(pw); - return baos.toByteArray(); - } - - private void eventTick(Object o) { - evtCnt++; - evtHash ^= o.hashCode(); - if((evtCnt % 5) == 0) { - long now = System.currentTimeMillis(); - addEntropyBits((byte)(now - tickT), 4); - tickT = now; - evtHash ^= now; - } - if((evtCnt % 17) == 0) { - addEntropyBits((byte)evtHash, 4); - } - } - - /* !!! REMOVE DEBUG - public static void main(String[] argv) { - RandomSeed seed = new RandomSeed(); - java.awt.Frame frame = new java.awt.Frame(); - com.mindbright.terminal.TerminalWin terminal = - new com.mindbright.terminal.TerminalWin(frame, - new com.mindbright.terminal.TerminalXTerm()); - - seed.addEntropyGenerator(terminal); - - frame.add(terminal.getPanelWithScrollbar(), java.awt.BorderLayout.CENTER); - frame.pack(); - frame.show(); - } - */ - -} diff --git a/src/main/java/com/mindbright/util/SKEYDictionary.java b/src/main/java/com/mindbright/util/SKEYDictionary.java deleted file mode 100644 index 5534ae4..0000000 --- a/src/main/java/com/mindbright/util/SKEYDictionary.java +++ /dev/null @@ -1,389 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.util; - -import java.util.StringTokenizer; - -public final class SKEYDictionary { - public final static String[] dict = { - "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD", - "AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA", - "AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK", - "ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE", - "AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM", - "BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET", - "BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO", - "BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT", - "BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT", - "CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY", - "CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN", - "DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG", - "DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB", - "DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO", - "ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE", - "EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW", - "FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR", - "FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP", - "GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO", - "GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD", - "HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM", - "HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT", - "HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", "HOW", "HUB", "HUE", - "HUG", "HUH", "HUM", "HUT", "I", "ICY", "IDA", "IF", "IKE", "ILL", - "INK", "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT", "ITS", - "IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", "JAY", "JET", "JIG", - "JIM", "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", "JUT", "KAY", - "KEG", "KEN", "KEY", "KID", "KIM", "KIN", "KIT", "LA", "LAB", "LAC", - "LAD", "LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE", "LEG", - "LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", "LIP", "LIT", "LO", - "LOB", "LOG", "LOP", "LOS", "LOT", "LOU", "LOW", "LOY", "LUG", "LYE", - "MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", "MAT", "MAW", "MAY", - "ME", "MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT", "MOB", - "MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", "MUG", "MUM", - "MY", "NAB", "NAG", "NAN", "NAP", "NAT", "NAY", "NE", "NED", "NEE", - "NET", "NEW", "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD", "NON", - "NOR", "NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF", "OAK", - "OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", "OH", "OIL", "OK", - "OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", "OS", "OTT", "OUR", - "OUT", "OVA", "OW", "OWE", "OWL", "OWN", "OX", "PA", "PAD", "PAL", - "PAM", "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG", "PEN", - "PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", "PIN", "PIT", "PLY", - "PO", "POD", "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB", "PUG", - "PUN", "PUP", "PUT", "QUO", "RAG", "RAM", "RAN", "RAP", "RAT", "RAW", - "RAY", "REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM", "RIO", - "RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", "ROY", "RUB", "RUE", - "RUG", "RUM", "RUN", "RYE", "SAC", "SAD", "SAG", "SAL", "SAM", "SAN", - "SAP", "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", "SET", "SEW", - "SHE", "SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY", "SLY", - "SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY", "SUB", - "SUD", "SUE", "SUM", "SUN", "SUP", "TAB", "TAD", "TAG", "TAN", "TAP", - "TAR", "TEA", "TED", "TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM", - "TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP", "TOW", - "TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", "UN", "UP", "US", - "USE", "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", "WAS", "WAY", - "WE", "WEB", "WED", "WEE", "WET", "WHO", "WHY", "WIN", "WIT", "WOK", - "WON", "WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE", "YEA", - "YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", "ABUT", "ACHE", - "ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", "ADDS", "ADEN", "AFAR", - "AFRO", "AGEE", "AHEM", "AHOY", "AIDA", "AIDE", "AIDS", "AIRY", "AJAR", - "AKIN", "ALAN", "ALEC", "ALGA", "ALIA", "ALLY", "ALMA", "ALOE", "ALSO", - "ALTO", "ALUM", "ALVA", "AMEN", "AMES", "AMID", "AMMO", "AMOK", "AMOS", - "AMRA", "ANDY", "ANEW", "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB", - "ARCH", "AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS", - "ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", "AVOW", - "AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", "BAIL", "BAIT", - "BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", "BALM", "BAND", "BANE", - "BANG", "BANK", "BARB", "BARD", "BARE", "BARK", "BARN", "BARR", "BASE", - "BASH", "BASK", "BASS", "BATE", "BATH", "BAWD", "BAWL", "BEAD", "BEAK", - "BEAM", "BEAN", "BEAR", "BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER", - "BEET", "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN", "BERT", - "BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", "BIEN", "BILE", - "BILK", "BILL", "BIND", "BING", "BIRD", "BITE", "BITS", "BLAB", "BLAT", - "BLED", "BLEW", "BLOB", "BLOC", "BLOT", "BLOW", "BLUE", "BLUM", "BLUR", - "BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY", "BOGY", "BOHR", "BOIL", - "BOLD", "BOLO", "BOLT", "BOMB", "BONA", "BOND", "BONE", "BONG", "BONN", - "BONY", "BOOK", "BOOM", "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE", - "BOSS", "BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN", - "BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", "BUFF", - "BULB", "BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", "BURL", "BURN", - "BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE", "CADY", - "CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM", "CAME", "CANE", - "CANT", "CARD", "CARE", "CARL", "CARR", "CART", "CASE", "CASH", "CASK", - "CAST", "CAVE", "CEIL", "CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT", - "CHAW", "CHEF", "CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", "CHUB", - "CHUG", "CHUM", "CITE", "CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY", - "CLOD", "CLOG", "CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", "COCK", - "COCO", "CODA", "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA", - "COLD", "COLT", "COMA", "COMB", "COME", "COOK", "COOL", "COON", "COOT", - "CORD", "CORE", "CORK", "CORN", "COST", "COVE", "COWL", "CRAB", "CRAG", - "CRAM", "CRAY", "CREW", "CRIB", "CROW", "CRUD", "CUBA", "CUBE", "CUFF", - "CULL", "CULT", "CUNY", "CURB", "CURD", "CURE", "CURL", "CURT", "CUTS", - "DADE", "DALE", "DAME", "DANA", "DANE", "DANG", "DANK", "DARE", "DARK", - "DARN", "DART", "DASH", "DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS", - "DEAD", "DEAF", "DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", "DEEM", - "DEER", "DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", "DIAL", "DICE", - "DIED", "DIET", "DIME", "DINE", "DING", "DINT", "DIRE", "DIRT", "DISC", - "DISH", "DISK", "DIVE", "DOCK", "DOES", "DOLE", "DOLL", "DOLT", "DOME", - "DONE", "DOOM", "DOOR", "DORA", "DOSE", "DOTE", "DOUG", "DOUR", "DOVE", - "DOWN", "DRAB", "DRAG", "DRAM", "DRAW", "DREW", "DRUB", "DRUG", "DRUM", - "DUAL", "DUCK", "DUCT", "DUEL", "DUET", "DUKE", "DULL", "DUMB", "DUNE", - "DUNK", "DUSK", "DUST", "DUTY", "EACH", "EARL", "EARN", "EASE", "EAST", - "EASY", "EBEN", "ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT", "EDNA", - "EGAN", "ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT", "EMMA", "ENDS", - "ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED", "FACE", "FACT", "FADE", - "FAIL", "FAIN", "FAIR", "FAKE", "FALL", "FAME", "FANG", "FARM", "FAST", - "FATE", "FAWN", "FEAR", "FEAT", "FEED", "FEEL", "FEET", "FELL", "FELT", - "FEND", "FERN", "FEST", "FEUD", "FIEF", "FIGS", "FILE", "FILL", "FILM", - "FIND", "FINE", "FINK", "FIRE", "FIRM", "FISH", "FISK", "FIST", "FITS", - "FIVE", "FLAG", "FLAK", "FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW", - "FLIT", "FLOC", "FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM", "FOGY", - "FOIL", "FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL", "FOOT", "FORD", - "FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL", "FOUR", "FOWL", "FRAU", - "FRAY", "FRED", "FREE", "FRET", "FREY", "FROG", "FROM", "FUEL", "FULL", - "FUME", "FUND", "FUNK", "FURY", "FUSE", "FUSS", "GAFF", "GAGE", "GAIL", - "GAIN", "GAIT", "GALA", "GALE", "GALL", "GALT", "GAME", "GANG", "GARB", - "GARY", "GASH", "GATE", "GAUL", "GAUR", "GAVE", "GAWK", "GEAR", "GELD", - "GENE", "GENT", "GERM", "GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT", - "GINA", "GIRD", "GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN", "GLIB", - "GLOB", "GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", "GOAL", "GOAT", - "GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", "GOOD", "GOOF", "GORE", - "GORY", "GOSH", "GOUT", "GOWN", "GRAB", "GRAD", "GRAY", "GREG", "GREW", - "GREY", "GRID", "GRIM", "GRIN", "GRIT", "GROW", "GRUB", "GULF", "GULL", - "GUNK", "GURU", "GUSH", "GUST", "GWEN", "GWYN", "HAAG", "HAAS", "HACK", - "HAIL", "HAIR", "HALE", "HALF", "HALL", "HALO", "HALT", "HAND", "HANG", - "HANK", "HANS", "HARD", "HARK", "HARM", "HART", "HASH", "HAST", "HATE", - "HATH", "HAUL", "HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", "HEAT", - "HEBE", "HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL", "HELM", "HERB", - "HERD", "HERE", "HERO", "HERS", "HESS", "HEWN", "HICK", "HIDE", "HIGH", - "HIKE", "HILL", "HILT", "HIND", "HINT", "HIRE", "HISS", "HIVE", "HOBO", - "HOCK", "HOFF", "HOLD", "HOLE", "HOLM", "HOLT", "HOME", "HONE", "HONK", - "HOOD", "HOOF", "HOOK", "HOOT", "HORN", "HOSE", "HOST", "HOUR", "HOVE", - "HOWE", "HOWL", "HOYT", "HUCK", "HUED", "HUFF", "HUGE", "HUGH", "HUGO", - "HULK", "HULL", "HUNK", "HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE", - "HYMN", "IBIS", "ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH", "INTO", - "IONS", "IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE", "ITCH", "ITEM", - "IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE", "JAVA", "JEAN", "JEFF", - "JERK", "JESS", "JEST", "JIBE", "JILL", "JILT", "JIVE", "JOAN", "JOBS", - "JOCK", "JOEL", "JOEY", "JOHN", "JOIN", "JOKE", "JOLT", "JOVE", "JUDD", - "JUDE", "JUDO", "JUDY", "JUJU", "JUKE", "JULY", "JUNE", "JUNK", "JUNO", - "JURY", "JUST", "JUTE", "KAHN", "KALE", "KANE", "KANT", "KARL", "KATE", - "KEEL", "KEEN", "KENO", "KENT", "KERN", "KERR", "KEYS", "KICK", "KILL", - "KIND", "KING", "KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW", "KNIT", - "KNOB", "KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE", - "LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", "LAKE", "LAMB", - "LAME", "LAND", "LANE", "LANG", "LARD", "LARK", "LASS", "LAST", "LATE", - "LAUD", "LAVA", "LAWN", "LAWS", "LAYS", "LEAD", "LEAF", "LEAK", "LEAN", - "LEAR", "LEEK", "LEER", "LEFT", "LEND", "LENS", "LENT", "LEON", "LESK", - "LESS", "LEST", "LETS", "LIAR", "LICE", "LICK", "LIED", "LIEN", "LIES", - "LIEU", "LIFE", "LIFT", "LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB", - "LIME", "LIND", "LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE", - "LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", "LOIS", "LOLA", - "LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", "LORE", "LOSE", "LOSS", - "LOST", "LOUD", "LOVE", "LOWE", "LUCK", "LUCY", "LUGE", "LUKE", "LULU", - "LUND", "LUNG", "LURA", "LURE", "LURK", "LUSH", "LUST", "LYLE", "LYNN", - "LYON", "LYRA", "MACE", "MADE", "MAGI", "MAID", "MAIL", "MAIN", "MAKE", - "MALE", "MALI", "MALL", "MALT", "MANA", "MANN", "MANY", "MARC", "MARE", - "MARK", "MARS", "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE", - "MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", "MEET", - "MELD", "MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", "MESS", "MICE", - "MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", "MIMI", "MIND", "MINE", - "MINI", "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE", "MITT", "MOAN", - "MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL", "MOLT", "MONA", "MONK", - "MONT", "MOOD", "MOON", "MOOR", "MOOT", "MORE", "MORN", "MORT", "MOSS", - "MOST", "MOTH", "MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL", - "MURK", "MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL", - "NAIR", "NAME", "NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", "NEAT", - "NECK", "NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS", - "NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH", "NODE", - "NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", "NOSE", "NOTE", "NOUN", - "NOVA", "NUDE", "NULL", "NUMB", "OATH", "OBEY", "OBOE", "ODIN", "OHIO", - "OILY", "OINT", "OKAY", "OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN", - "OMIT", "ONCE", "ONES", "ONLY", "ONTO", "ONUS", "ORAL", "ORGY", "OSLO", - "OTIS", "OTTO", "OUCH", "OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY", - "OWNS", "QUAD", "QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT", "RAGE", - "RAID", "RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", "RASH", "RATE", - "RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", "RECK", "REED", "REEF", - "REEK", "REEL", "REID", "REIN", "RENA", "REND", "RENT", "REST", "RICE", - "RICH", "RICK", "RIDE", "RIFT", "RILL", "RIME", "RING", "RINK", "RISE", - "RISK", "RITE", "ROAD", "ROAM", "ROAR", "ROBE", "ROCK", "RODE", "ROIL", - "ROLL", "ROME", "ROOD", "ROOF", "ROOK", "ROOM", "ROOT", "ROSA", "ROSE", - "ROSS", "ROSY", "ROTH", "ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY", - "RUDE", "RUDY", "RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", "RUSH", - "RUSK", "RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE", "SAID", "SAIL", - "SALE", "SALK", "SALT", "SAME", "SAND", "SANE", "SANG", "SANK", "SARA", - "SAUL", "SAVE", "SAYS", "SCAN", "SCAR", "SCAT", "SCOT", "SEAL", "SEAM", - "SEAR", "SEAT", "SEED", "SEEK", "SEEM", "SEEN", "SEES", "SELF", "SELL", - "SEND", "SENT", "SETS", "SEWN", "SHAG", "SHAM", "SHAW", "SHAY", "SHED", - "SHIM", "SHIN", "SHOD", "SHOE", "SHOT", "SHOW", "SHUN", "SHUT", "SICK", - "SIDE", "SIFT", "SIGH", "SIGN", "SILK", "SILL", "SILO", "SILT", "SINE", - "SING", "SINK", "SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW", "SKID", - "SKIM", "SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY", "SLED", "SLEW", - "SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT", "SLOW", "SLUG", "SLUM", - "SLUR", "SMOG", "SMUG", "SNAG", "SNOB", "SNOW", "SNUB", "SNUG", "SOAK", - "SOAR", "SOCK", "SODA", "SOFA", "SOFT", "SOIL", "SOLD", "SOME", "SONG", - "SOON", "SOOT", "SORE", "SORT", "SOUL", "SOUR", "SOWN", "STAB", "STAG", - "STAN", "STAR", "STAY", "STEM", "STEW", "STIR", "STOW", "STUB", "STUN", - "SUCH", "SUDS", "SUIT", "SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF", - "SWAB", "SWAG", "SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM", "TACK", - "TACT", "TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK", "TASK", "TATE", - "TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", "TEEN", "TEET", "TELL", - "TEND", "TENT", "TERM", "TERN", "TESS", "TEST", "THAN", "THAT", "THEE", - "THEM", "THEN", "THEY", "THIN", "THIS", "THUD", "THUG", "TICK", "TIDE", - "TIDY", "TIED", "TIER", "TILE", "TILL", "TILT", "TIME", "TINA", "TINE", - "TINT", "TINY", "TIRE", "TOAD", "TOGO", "TOIL", "TOLD", "TOLL", "TONE", - "TONG", "TONY", "TOOK", "TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR", - "TOUT", "TOWN", "TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", "TRIM", - "TRIO", "TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", "TUCK", "TUFT", - "TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK", "TWIG", "TWIN", "TWIT", - "ULAN", "UNIT", "URGE", "USED", "USER", "USES", "UTAH", "VAIL", "VAIN", - "VALE", "VARY", "VASE", "VAST", "VEAL", "VEDA", "VEIL", "VEIN", "VEND", - "VENT", "VERB", "VERY", "VETO", "VICE", "VIEW", "VINE", "VISE", "VOID", - "VOLT", "VOTE", "WACK", "WADE", "WAGE", "WAIL", "WAIT", "WAKE", "WALE", - "WALK", "WALL", "WALT", "WAND", "WANE", "WANG", "WANT", "WARD", "WARM", - "WARN", "WART", "WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY", "WAYS", - "WEAK", "WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR", "WELD", "WELL", - "WELT", "WENT", "WERE", "WERT", "WEST", "WHAM", "WHAT", "WHEE", "WHEN", - "WHET", "WHOA", "WHOM", "WICK", "WIFE", "WILD", "WILL", "WIND", "WINE", - "WING", "WINK", "WINO", "WIRE", "WISE", "WISH", "WITH", "WOLF", "WONT", - "WOOD", "WOOL", "WORD", "WORE", "WORK", "WORM", "WORN", "WOVE", "WRIT", - "WYNN", "YALE", "YANG", "YANK", "YARD", "YARN", "YAWL", "YAWN", "YEAH", - "YEAR", "YELL", "YOGA", "YOKE" - }; - - public static String bitsToEnglish(byte[] bits, int offset) { - byte[] bits2 = new byte[9]; - int p,i; - - System.arraycopy(bits, 0, bits2, 0, 8); - - /* compute parity */ - for(p = 0,i = 0; i < 64; i += 2) - p += extractBits(bits2, i, 2); - - bits2[8] = (byte)(p << 6); - - StringBuffer buf = new StringBuffer(); - - for(i = 0; i < 66; i += 11) { - if(i > 0) { - buf.append(" "); - } - buf.append(dict[extractBits(bits2, i, 11)]); - } - - return buf.toString(); - } - - public static byte[] englishToBits(String english) { - StringTokenizer st = new StringTokenizer(english); - byte[] bits = new byte[9]; - int i, p, v, l, low, high; - String word; - - for(i = 0, p = 0; i < 6; i++, p += 11) { - if((word = st.nextToken()) == null) - return null; - l = word.length(); - if(l > 4 || l < 1) { - return null; - } else if(l < 4) { - low = 0; - high = 570; - } else { - low = 571; - high = 2047; - } - // !!! standard(word); - if((v = wsrch(word, low, high)) < 0) - return null; - insertBits(bits, v, p, 11); - } - - /* now check the parity of what we got */ - for(p = 0, i = 0; i < 64; i +=2) - p += extractBits(bits, i, 2); - - if((p & 3) != extractBits(bits, 64, 2)) - return null; - - byte[] out = new byte[8]; - System.arraycopy(bits, 0, out, 0, 8); - - return out; - } - - static int extractBits(byte[] bits, int offset, int length) { - int l = 0, c = 0, r = 0, x, byteOff = offset / 8; - - l = (bits[byteOff] & 0xff); - if(byteOff + 1 < bits.length) { - c = (bits[byteOff + 1] & 0xff); - } - if(byteOff + 2 < bits.length) { - r = (bits[byteOff + 2] & 0xff); - } - - x = ((l << 8 | c) << 8 | r); - x = x >>> (24 - (length + (offset % 8))); - x = (x & (0xffff >>> (16 - length))); - - return x; - } - - static void insertBits(byte[] bits, int x, int offset, int length) { - int l, c, r, y, shift; - - shift = ((8 - ((offset + length) & 0x07)) & 0x07); - y = x << shift; - l = (y >>> 16) & 0xff; - c = (y >>> 8) & 0xff; - r = y & 0xff; - if(shift + length > 16) { - bits[offset / 8] |= l; - bits[offset / 8 + 1] |= c; - bits[offset / 8 + 2] |= r; - } else if(shift +length > 8) { - bits[offset / 8] |= c; - bits[offset / 8 + 1] |= r; - } else { - bits[offset / 8] |= r; - } - } - - /* Dictionary binary search */ - private static int wsrch(String word, int low, int high) { - int i, j; - - word = word.toUpperCase(); - - for(;;) { - i = (low + high) / 2; - if((j = word.compareTo(dict[i])) == 0) { - return i; /* Found it */ - } else if(high == low + 1) { - /* Avoid effects of integer truncation in /2 */ - if(word.equalsIgnoreCase(dict[high])) - return high; - else - return -1; - } else if(low >= high) { - return -1; - } - /* I don't *think* this can happen...*/ - if(j < 0) - high = i; /* Search lower half */ - else - low = i; /* Search upper half */ - } - } - - /* !!! DEBUG - public static void main(String[] argv) { - String words1 = "RASH BUSH MILK LOOK BAD BRIM"; - String words2 = "TROD MUTE TAIL WARM CHAR KONG"; - byte[] bits1, bits2; - System.out.println("words1: "); - bits1 = SKEYDictionary.englishToBits(words1); - com.mindbright.util.HexDump.hexDump(bits1); - System.out.println("words2: "); - bits2 = SKEYDictionary.englishToBits(words2); - com.mindbright.util.HexDump.hexDump(bits2); - System.out.println(SKEYDictionary.bitsToEnglish(bits1, 0)); - System.out.println(SKEYDictionary.bitsToEnglish(bits2, 0)); - } - */ - -} diff --git a/src/main/java/com/mindbright/util/SecureRandomAndPad.java b/src/main/java/com/mindbright/util/SecureRandomAndPad.java deleted file mode 100644 index 9a0983d..0000000 --- a/src/main/java/com/mindbright/util/SecureRandomAndPad.java +++ /dev/null @@ -1,87 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.util; - -import com.mindbright.jca.security.SecureRandom; -import com.mindbright.jca.security.MessageDigest; - -public class SecureRandomAndPad extends SecureRandom { - - private SecureRandom random; - private byte[] state; - private int x; - private int y; - - private int arcfour_byte() { - int x, y, sx, sy; - x = (this.x + 1) & 0xff; - sx = (int)state[x]; - y = (sx + this.y) & 0xff; - sy = (int)state[y]; - this.x = x; - this.y = y; - state[y] = (byte)(sx & 0xff); - state[x] = (byte)(sy & 0xff); - return (int)state[((sx + sy) & 0xff)]; - } - - public SecureRandomAndPad() { - this(new SecureRandom()); - } - - public SecureRandomAndPad(SecureRandom random) { - this.random = random; - this.state = new byte[256]; - for(int i = 0; i < 256; i++) { - this.state[i] = (byte)i; - } - } - - public void setPadSeed(byte[] seed) { - int seedindex = 0; - int stateindex = 0; - int t, u; - for(int counter = 0; counter < 256; counter++) { - t = (int)state[counter]; - stateindex = (stateindex + seed[seedindex] + t) & 0xff; - u = (int)state[stateindex]; - state[stateindex] = (byte)(t & 0xff); - state[counter] = (byte)(u & 0xff); - if(++seedindex >= seed.length) - seedindex = 0; - } - } - - public void nextPadBytes(byte[] bytes, int off, int len) { - int end = off + len; - for(int i = off; i < end; i++) { - bytes[i] = (byte)(((int)bytes[i] ^ arcfour_byte()) & 0xff); - } - } - - public byte[] generateSeed(int numBytes) { - return random.generateSeed(numBytes); - } - - public void nextBytes(byte[] bytes) { - random.nextBytes(bytes); - } - - public void setSeed(byte[] seed) { - random.setSeed(seed); - } - -} diff --git a/src/main/java/com/mindbright/util/StringUtil.java b/src/main/java/com/mindbright/util/StringUtil.java deleted file mode 100644 index f6200a2..0000000 --- a/src/main/java/com/mindbright/util/StringUtil.java +++ /dev/null @@ -1,36 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package com.mindbright.util; - -public final class StringUtil { - public static String trimLeft(String str) { - char[] val = str.toCharArray(); - int st = 0; - while ((st < val.length) && (val[st] <= ' ')) { - st++; - } - return str.substring(st); - } - - public static String trimRight(String str) { - char[] val = str.toCharArray(); - int end = val.length; - while ((end > 0) && (val[end - 1] <= ' ')) { - end--; - } - return str.substring(0, end); - } -} diff --git a/src/main/java/javax/crypto/Cipher.java b/src/main/java/javax/crypto/Cipher.java deleted file mode 100644 index fad1b1d..0000000 --- a/src/main/java/javax/crypto/Cipher.java +++ /dev/null @@ -1,187 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto; - -import com.mindbright.jca.security.SecureRandom; -import com.mindbright.jca.security.InvalidKeyException; -import com.mindbright.jca.security.Key; -import com.mindbright.jca.security.Provider; -import com.mindbright.jca.security.ProviderLookup; -import com.mindbright.jca.security.spec.AlgorithmParameterSpec; -// import com.mindbright.jca.security.AlgorithmParameters; -import com.mindbright.jca.security.NoSuchAlgorithmException; -import com.mindbright.jca.security.NoSuchProviderException; - -public class Cipher { - - public final static int DECRYPT_MODE = 1; - public final static int ENCRYPT_MODE = 2; - - CipherSpi cipherSpi; - Provider provider; - String transformation; - String algorithm; - - protected Cipher(CipherSpi cipherSpi, Provider provider, - String transformation) { - this.cipherSpi = cipherSpi; - this.provider = provider; - this.transformation = transformation; - int i = transformation.indexOf('/'); - if(i != -1) { - this.algorithm = transformation.substring(0, i); - } else { - this.algorithm = transformation; - } - } - - /* - public final byte[] doFinal() { - } - */ - - /* - public final int doFinal(byte[] output, int outputOffset) { - } - */ - - public final byte[] doFinal(byte[] input) { - return doFinal(input, 0, input.length); - } - - public final byte[] doFinal(byte[] input, int inputOffset, int inputLen) { - byte[] output = new byte[getOutputSize(inputLen)]; - doFinal(input, inputOffset, inputLen, output, 0); - return output; - } - - public final int doFinal(byte[] input, int inputOffset, int inputLen, - byte[] output) { - return doFinal(input, inputOffset, inputLen, output, 0); - } - - public final int doFinal(byte[] input, int inputOffset, int inputLen, - byte[] output, int outputOffset) { - return cipherSpi.engineDoFinal(input, inputOffset, inputLen, - output, outputOffset); - } - - public final String getAlgorithm() { - return algorithm; - } - - public final int getBlockSize() { - return cipherSpi.engineGetBlockSize(); - } - - public static final Cipher getInstance(String transformation) - throws NoSuchAlgorithmException - { - try { - String provider = - ProviderLookup.findImplementingProvider("Cipher", - transformation); - return getInstance(transformation, provider); - } catch (NoSuchProviderException e) { - throw new Error("Error in Cipher: " + e); - } - } - - public static final Cipher getInstance(String transformation, - String provider) - throws NoSuchAlgorithmException, NoSuchProviderException - { - ProviderLookup pl = ProviderLookup.getImplementation("Cipher", - transformation, - provider); - - CipherSpi cipherSpi = (CipherSpi)pl.getImpl(); - - int i = transformation.indexOf('/'); - if(i != -1) { - int j = transformation.indexOf('/', i + 1); - if(j != -1) { - cipherSpi.engineSetPadding(transformation.substring(j + 1)); - } else { - j = transformation.length(); - } - cipherSpi.engineSetMode(transformation.substring(i + 1, j)); - } - - return new Cipher(cipherSpi, pl.getProvider(), transformation); - } - - public final byte[] getIV() { - return cipherSpi.engineGetIV(); - } - - public final int getOutputSize(int inputLen) { - return cipherSpi.engineGetOutputSize(inputLen); - } - - /* - public final AlgorithmParameters getParameters() { - return cipherSpi.engineGetParameters(); - } - */ - - public final Provider getProvider() { - return provider; - } - - public final void init(int opmode, Key key) throws InvalidKeyException { - init(opmode, key, null); - } - - public final void init(int opmode, Key key, AlgorithmParameterSpec params) - throws InvalidKeyException { - cipherSpi.engineInit(opmode, key, params, null); - } - - /* - public final void init(int opmode, Key key, AlgorithmParameters params) { - } - - public final void init(int opmode, Key key, AlgorithmParameters params, - SecureRandom random) { - } - */ - - /* - public final void init(int opmode, Key key, AlgorithmParameterSpec params, - SecureRandom random) { - } - - public final void init(int opmode, Key key, SecureRandom random) { - } - */ - - /* - public final byte[] update(byte[] input) { - } - - public final byte[] update(byte[] input, int inputOffset, int inputLen) { - } - - public final int update(byte[] input, int inputOffset, int inputLen, - byte[] output) { - } - - public final int update(byte[] input, int inputOffset, int inputLen, - byte[] output, int outputOffset) { - } - */ -} diff --git a/src/main/java/javax/crypto/CipherSpi.java b/src/main/java/javax/crypto/CipherSpi.java deleted file mode 100644 index 7d37998..0000000 --- a/src/main/java/javax/crypto/CipherSpi.java +++ /dev/null @@ -1,76 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto; - -import com.mindbright.jca.security.SecureRandom; -import com.mindbright.jca.security.InvalidKeyException; -import com.mindbright.jca.security.Key; -import com.mindbright.jca.security.spec.AlgorithmParameterSpec; -// import com.mindbright.jca.security.AlgorithmParameters; - -public abstract class CipherSpi { - - public CipherSpi() { - } - - /* - protected abstract byte[] engineDoFinal(byte[] input, int inputOffset, - int inputLen); - */ - - protected abstract int engineDoFinal(byte[] input, int inputOffset, - int inputLen, - byte[] output, int outputOffset); - - protected abstract int engineGetBlockSize(); - - protected abstract byte[] engineGetIV(); - - protected abstract int engineGetOutputSize(int inputLen); - - /* - protected abstract AlgorithmParameters engineGetParameters(); - */ - - /* - protected abstract void engineInit(int opmode, Key key, - AlgorithmParameters params, - SecureRandom random); - */ - - protected abstract void engineInit(int opmode, Key key, - AlgorithmParameterSpec params, - SecureRandom random) throws - InvalidKeyException; - - protected abstract void engineInit(int opmode, Key key, - SecureRandom random) throws - InvalidKeyException; - - protected abstract void engineSetMode(String mode); - - protected abstract void engineSetPadding(String padding); - - /* - protected abstract byte[] engineUpdate(byte[] input, int inputOffset, - int inputLen); - - protected abstract int engineUpdate(byte[] input, int inputOffset, - int inputLen, - byte[] output, int outputOffset); - */ - -} diff --git a/src/main/java/javax/crypto/KeyAgreement.java b/src/main/java/javax/crypto/KeyAgreement.java deleted file mode 100644 index 36247ba..0000000 --- a/src/main/java/javax/crypto/KeyAgreement.java +++ /dev/null @@ -1,122 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto; - -import java.math.BigInteger; - -import com.mindbright.jca.security.Provider; -import com.mindbright.jca.security.ProviderLookup; -import com.mindbright.jca.security.SecureRandom; -import com.mindbright.jca.security.Key; -import com.mindbright.jca.security.NoSuchAlgorithmException; -import com.mindbright.jca.security.NoSuchProviderException; -import com.mindbright.jca.security.InvalidKeyException; -import com.mindbright.jca.security.InvalidAlgorithmParameterException; -import com.mindbright.jca.security.spec.AlgorithmParameterSpec; - -public class KeyAgreement { - - protected KeyAgreementSpi keyAgreementSpi; - Provider provider; - String algorithm; - - protected KeyAgreement(KeyAgreementSpi keyAgreeSpi, Provider provider, - String algorithm) { - this.keyAgreementSpi = keyAgreeSpi; - this.provider = provider; - this.algorithm = algorithm; - } - - public final String getAlgorithm() { - return algorithm; - } - - public static final KeyAgreement getInstance(String algorithm) - throws NoSuchAlgorithmException - { - try { - String provider = - ProviderLookup.findImplementingProvider("KeyAgreement", - algorithm); - return getInstance(algorithm, provider); - } catch (NoSuchProviderException e) { - throw new Error("Error in Signature: " + e); - } - - } - - public static final KeyAgreement getInstance(String algorithm, - String provider) - throws NoSuchAlgorithmException, NoSuchProviderException - { - ProviderLookup pl = ProviderLookup.getImplementation("KeyAgreement", - algorithm, - provider); - return new KeyAgreement((KeyAgreementSpi)pl.getImpl(), - pl.getProvider(), algorithm); - } - - public final Provider getProvider() { - return provider; - } - - public final void init(Key key) throws InvalidKeyException { - init(key, (SecureRandom)null); - } - - public final void init(Key key, SecureRandom random) - throws InvalidKeyException - { - keyAgreementSpi.engineInit(key, random); - } - - public final void init(Key key, AlgorithmParameterSpec params) - throws InvalidKeyException, InvalidAlgorithmParameterException - { - init(key, params, null); - } - - public final void init(Key key, AlgorithmParameterSpec params, - SecureRandom random) - throws InvalidKeyException, InvalidAlgorithmParameterException - { - keyAgreementSpi.engineInit(key, params, random); - } - - public final Key doPhase(Key key, boolean lastPhase) - throws InvalidKeyException, IllegalStateException - { - return keyAgreementSpi.engineDoPhase(key, lastPhase); - } - - public final byte[] generateSecret() throws IllegalStateException { - return keyAgreementSpi.engineGenerateSecret(); - } - - public final int generateSecret(byte[] sharedSecret, int offset) - throws IllegalStateException, ShortBufferException - { - return keyAgreementSpi.engineGenerateSecret(sharedSecret, offset); - } - - public final SecretKey generateSecret(String algorithm) - throws IllegalStateException, NoSuchAlgorithmException, - InvalidKeyException - { - return keyAgreementSpi.engineGenerateSecret(algorithm); - } - -} diff --git a/src/main/java/javax/crypto/KeyAgreementSpi.java b/src/main/java/javax/crypto/KeyAgreementSpi.java deleted file mode 100644 index d84d519..0000000 --- a/src/main/java/javax/crypto/KeyAgreementSpi.java +++ /dev/null @@ -1,53 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto; - -import java.math.BigInteger; - -import com.mindbright.jca.security.Provider; -import com.mindbright.jca.security.SecureRandom; -import com.mindbright.jca.security.Key; -import com.mindbright.jca.security.NoSuchAlgorithmException; -import com.mindbright.jca.security.InvalidKeyException; -import com.mindbright.jca.security.InvalidAlgorithmParameterException; -import com.mindbright.jca.security.spec.AlgorithmParameterSpec; - -public abstract class KeyAgreementSpi { - - public KeyAgreementSpi() { - } - - protected abstract void engineInit(Key key, SecureRandom random) - throws InvalidKeyException; - - protected abstract void engineInit(Key key, AlgorithmParameterSpec params, - SecureRandom random) - throws InvalidKeyException, InvalidAlgorithmParameterException; - - protected abstract Key engineDoPhase(Key key, boolean lastPhase) - throws InvalidKeyException, IllegalStateException; - - protected abstract byte[] engineGenerateSecret() - throws IllegalStateException; - - protected abstract int engineGenerateSecret(byte[] sharedSecret, int offset) - throws IllegalStateException, ShortBufferException; - - protected abstract SecretKey engineGenerateSecret(String algorithm) - throws IllegalStateException, NoSuchAlgorithmException, - InvalidKeyException; - -} diff --git a/src/main/java/javax/crypto/Mac.java b/src/main/java/javax/crypto/Mac.java deleted file mode 100644 index 90dcf90..0000000 --- a/src/main/java/javax/crypto/Mac.java +++ /dev/null @@ -1,161 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto; - -import com.mindbright.jca.security.Provider; -import com.mindbright.jca.security.ProviderLookup; -import com.mindbright.jca.security.NoSuchAlgorithmException; -import com.mindbright.jca.security.NoSuchProviderException; -import com.mindbright.jca.security.InvalidKeyException; -import com.mindbright.jca.security.InvalidAlgorithmParameterException; -import com.mindbright.jca.security.Key; -import com.mindbright.jca.security.spec.AlgorithmParameterSpec; - -public class Mac implements Cloneable { - - private Provider provider; - private MacSpi engine; - private String algorithm; - private boolean initialized; - private int macLength; - - protected Mac(MacSpi macSpi, Provider provider, String algorithm) { - this.provider = provider; - this.engine = macSpi; - this.algorithm = algorithm; - this.initialized = false; - } - - public Object clone() throws CloneNotSupportedException { - Mac clone = new Mac((MacSpi)this.engine.clone(), this.provider, - this.algorithm); - clone.initialized = this.initialized; - return clone; - } - - public final byte[] doFinal() throws IllegalStateException { - if(initialized) { - byte[] mac = engine.engineDoFinal(); - engine.engineReset(); - return mac; - } else { - throw new IllegalStateException(algorithm + " not initialized"); - } - } - - public final byte[] doFinal(byte[] input) throws IllegalStateException { - if(initialized) { - engine.engineUpdate(input, 0, input.length); - return doFinal(); - } else { - throw new IllegalStateException(algorithm + " not initialized"); - } - } - - public final void doFinal(byte[] output, int outOffset) - throws ShortBufferException, IllegalStateException - { - if(initialized) { - if(output.length - outOffset < macLength) - throw new ShortBufferException("Output buffer is too small for " - + algorithm); - System.arraycopy(engine.engineDoFinal(), 0, output, outOffset, macLength); - } else { - throw new IllegalStateException(algorithm + " not initialized"); - } - } - - public final String getAlgorithm() { - return algorithm; - } - - public final static Mac getInstance(String algorithm) - throws NoSuchAlgorithmException - { - try { - String provider = - ProviderLookup.findImplementingProvider("Mac", algorithm); - return getInstance(algorithm, provider); - } catch (NoSuchProviderException e) { - throw new Error("Error in Mac: " + e); - } - } - - public final static Mac getInstance(String algorithm, String provider) - throws NoSuchProviderException, NoSuchAlgorithmException - { - ProviderLookup pl = ProviderLookup.getImplementation("Mac", - algorithm, - provider); - return new Mac((MacSpi)pl.getImpl(), pl.getProvider(), algorithm); - } - - public final int getMacLength() { - int len = macLength; - if(!initialized) { - len = engine.engineGetMacLength(); - } - return len; - } - - Provider getProvider() { - return provider; - } - - public final void init(Key key) throws InvalidKeyException { - try { - init(key, null); - } catch (InvalidAlgorithmParameterException e) { - throw new Error("Error in Mac: " + e); - } - } - - public final void init(Key key, AlgorithmParameterSpec params) - throws InvalidKeyException, InvalidAlgorithmParameterException - { - engine.engineInit(key, params); - macLength = engine.engineGetMacLength(); - initialized = true; - } - - public final void reset() { - engine.engineReset(); - } - - public final void update(byte input) throws IllegalStateException { - if(initialized) { - engine.engineUpdate(input); - } else { - throw new IllegalStateException(algorithm + " not initialized"); - } - } - - public final void update(byte[] input) throws IllegalStateException { - update(input, 0, input.length); - } - - public final void update(byte[] input, int offset, int len) - throws IllegalStateException - { - if(initialized) { - engine.engineUpdate(input, offset, len); - } else { - throw new IllegalStateException(algorithm + " not initialized"); - } - } - -} - diff --git a/src/main/java/javax/crypto/MacSpi.java b/src/main/java/javax/crypto/MacSpi.java deleted file mode 100644 index b94087d..0000000 --- a/src/main/java/javax/crypto/MacSpi.java +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto; - -import com.mindbright.jca.security.Key; -import com.mindbright.jca.security.InvalidKeyException; -import com.mindbright.jca.security.InvalidAlgorithmParameterException; -import com.mindbright.jca.security.spec.AlgorithmParameterSpec; - -public abstract class MacSpi { - - public MacSpi() { - } - - public Object clone() throws CloneNotSupportedException { - if(this instanceof Cloneable) { - return super.clone(); - } else { - throw new CloneNotSupportedException(); - } - } - - protected abstract byte[] engineDoFinal(); - - protected abstract int engineGetMacLength(); - - protected abstract void engineInit(Key key, AlgorithmParameterSpec params) - throws InvalidKeyException, InvalidAlgorithmParameterException; - - protected abstract void engineReset(); - - protected abstract void engineUpdate(byte input); - - protected abstract void engineUpdate(byte[] input, int offset, int len); - -} diff --git a/src/main/java/javax/crypto/SecretKey.java b/src/main/java/javax/crypto/SecretKey.java deleted file mode 100644 index d0a8940..0000000 --- a/src/main/java/javax/crypto/SecretKey.java +++ /dev/null @@ -1,21 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto; - -import com.mindbright.jca.security.Key; - -public interface SecretKey extends Key { -} diff --git a/src/main/java/javax/crypto/ShortBufferException.java b/src/main/java/javax/crypto/ShortBufferException.java deleted file mode 100644 index be434ab..0000000 --- a/src/main/java/javax/crypto/ShortBufferException.java +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto; - -import com.mindbright.jca.security.GeneralSecurityException; - -public class ShortBufferException extends GeneralSecurityException { - public ShortBufferException(String msg) { - super(msg); - } -} diff --git a/src/main/java/javax/crypto/interfaces/DHKey.java b/src/main/java/javax/crypto/interfaces/DHKey.java deleted file mode 100644 index 67438b1..0000000 --- a/src/main/java/javax/crypto/interfaces/DHKey.java +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto.interfaces; - -import javax.crypto.spec.DHParameterSpec; - -public interface DHKey { - public DHParameterSpec getParams(); -} diff --git a/src/main/java/javax/crypto/interfaces/DHPrivateKey.java b/src/main/java/javax/crypto/interfaces/DHPrivateKey.java deleted file mode 100644 index d3ecbaf..0000000 --- a/src/main/java/javax/crypto/interfaces/DHPrivateKey.java +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto.interfaces; - -import java.math.BigInteger; - -import com.mindbright.jca.security.PrivateKey; - -public interface DHPrivateKey extends DHKey, PrivateKey { - public BigInteger getX(); -} diff --git a/src/main/java/javax/crypto/interfaces/DHPublicKey.java b/src/main/java/javax/crypto/interfaces/DHPublicKey.java deleted file mode 100644 index fb73eae..0000000 --- a/src/main/java/javax/crypto/interfaces/DHPublicKey.java +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto.interfaces; - -import java.math.BigInteger; - -import com.mindbright.jca.security.PublicKey; - -public interface DHPublicKey extends DHKey, PublicKey { - public BigInteger getY(); -} diff --git a/src/main/java/javax/crypto/spec/DHGenParameterSpec.java b/src/main/java/javax/crypto/spec/DHGenParameterSpec.java deleted file mode 100644 index 2f61aaa..0000000 --- a/src/main/java/javax/crypto/spec/DHGenParameterSpec.java +++ /dev/null @@ -1,38 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto.spec; - -import com.mindbright.jca.security.spec.AlgorithmParameterSpec; - -public class DHGenParameterSpec implements AlgorithmParameterSpec { - - protected int primeSize; - protected int exponentSize; - - public DHGenParameterSpec(int primeSize, int exponentSize) { - this.primeSize = primeSize; - this.exponentSize = exponentSize; - } - - public int getPrimeSize() { - return primeSize; - } - - public int getExponentSize() { - return exponentSize; - } - -} diff --git a/src/main/java/javax/crypto/spec/DHParameterSpec.java b/src/main/java/javax/crypto/spec/DHParameterSpec.java deleted file mode 100644 index 1d05282..0000000 --- a/src/main/java/javax/crypto/spec/DHParameterSpec.java +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto.spec; - -import java.math.BigInteger; - -import com.mindbright.jca.security.spec.AlgorithmParameterSpec; - -public class DHParameterSpec extends DHParamsImpl - implements AlgorithmParameterSpec -{ - protected int l; - - public DHParameterSpec(BigInteger p, BigInteger g) { - this(p, g, 0); - } - - public DHParameterSpec(BigInteger p, BigInteger g, int l) { - super(p, g); - this.l = l; - } - - public int getL() { - return l; - } - -} diff --git a/src/main/java/javax/crypto/spec/DHParamsImpl.java b/src/main/java/javax/crypto/spec/DHParamsImpl.java deleted file mode 100644 index 603407d..0000000 --- a/src/main/java/javax/crypto/spec/DHParamsImpl.java +++ /dev/null @@ -1,39 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto.spec; - -import java.math.BigInteger; - -import com.mindbright.jca.security.spec.AlgorithmParameterSpec; - -public abstract class DHParamsImpl { - protected BigInteger p; - protected BigInteger g; - - protected DHParamsImpl(BigInteger p, BigInteger g) { - this.p = p; - this.g = g; - } - - public final BigInteger getP() { - return p; - } - - public final BigInteger getG() { - return g; - } - -} diff --git a/src/main/java/javax/crypto/spec/DHPrivateKeySpec.java b/src/main/java/javax/crypto/spec/DHPrivateKeySpec.java deleted file mode 100644 index 0d473a3..0000000 --- a/src/main/java/javax/crypto/spec/DHPrivateKeySpec.java +++ /dev/null @@ -1,35 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto.spec; - -import java.math.BigInteger; - -import com.mindbright.jca.security.spec.KeySpec; - -public class DHPrivateKeySpec extends DHParamsImpl implements KeySpec { - - protected BigInteger x; - - public DHPrivateKeySpec(BigInteger x, BigInteger p, BigInteger g) { - super(p, g); - this.x = x; - } - - public BigInteger getX() { - return x; - } - -} diff --git a/src/main/java/javax/crypto/spec/DHPublicKeySpec.java b/src/main/java/javax/crypto/spec/DHPublicKeySpec.java deleted file mode 100644 index 8640b81..0000000 --- a/src/main/java/javax/crypto/spec/DHPublicKeySpec.java +++ /dev/null @@ -1,35 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto.spec; - -import java.math.BigInteger; - -import com.mindbright.jca.security.spec.KeySpec; - -public class DHPublicKeySpec extends DHParamsImpl implements KeySpec { - - protected BigInteger y; - - public DHPublicKeySpec(BigInteger y, BigInteger p, BigInteger g) { - super(p, g); - this.y = y; - } - - public BigInteger getY() { - return y; - } - -} diff --git a/src/main/java/javax/crypto/spec/IvParameterSpec.java b/src/main/java/javax/crypto/spec/IvParameterSpec.java deleted file mode 100644 index 6857157..0000000 --- a/src/main/java/javax/crypto/spec/IvParameterSpec.java +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto.spec; - -import com.mindbright.jca.security.spec.AlgorithmParameterSpec; - -public class IvParameterSpec implements AlgorithmParameterSpec { - byte[] iv; - - public IvParameterSpec(byte[] iv) { - this(iv, 0, iv.length); - } - - public IvParameterSpec(byte[] iv, int offset, int len) { - this.iv = new byte[len]; - System.arraycopy(iv, offset, this.iv, 0, len); - } - - public byte[] getIV() { - byte[] ivc = new byte[iv.length]; - System.arraycopy(iv, 0, ivc, 0, iv.length); - return ivc; - } -} diff --git a/src/main/java/javax/crypto/spec/SecretKeySpec.java b/src/main/java/javax/crypto/spec/SecretKeySpec.java deleted file mode 100644 index 4172dc0..0000000 --- a/src/main/java/javax/crypto/spec/SecretKeySpec.java +++ /dev/null @@ -1,56 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 1999-2001 AppGate AB. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code as - * defined in and that are subject to the MindTerm Public Source License, - * Version 1.3, (the 'License'). You may not use this file except in compliance - * with the License. - * - * You should have received a copy of the MindTerm Public Source License - * along with this software; see the file LICENSE. If not, write to - * AppGate AB, Stora Badhusgatan 18-20, 41121 Goteborg, SWEDEN - * - *****************************************************************************/ - -package javax.crypto.spec; - -import com.mindbright.jca.security.spec.KeySpec; - -import javax.crypto.SecretKey; - -public class SecretKeySpec implements KeySpec, SecretKey { - - private byte[] key; - private String algorithm; - - public SecretKeySpec(byte[] key, int offset, int len, String algorithm) { - this.key = new byte[len]; - System.arraycopy(key, offset, this.key, 0, len); - this.algorithm = algorithm; - } - - public SecretKeySpec(byte[] key, java.lang.String algorithm) { - this(key, 0, key.length, algorithm); - } - - public boolean equals(java.lang.Object obj) { - return false; - } - - public String getAlgorithm() { - return algorithm; - } - - public byte[] getEncoded() { - return key; - } - - public String getFormat() { - return null; - } - - public int hashCode() { - return 0; - } -} diff --git a/src/main/java/netscape/security/ForbiddenTargetException.java b/src/main/java/netscape/security/ForbiddenTargetException.java deleted file mode 100644 index 44d60c7..0000000 --- a/src/main/java/netscape/security/ForbiddenTargetException.java +++ /dev/null @@ -1,7 +0,0 @@ -// -// DUMMY CLASS TO MAKE COMPILER HAPPY WHEN NOT USING NETSCAPE_SECURITY_MODEL -// -package netscape.security; - -public class ForbiddenTargetException extends Exception { -} diff --git a/src/main/java/netscape/security/PrivilegeManager.java b/src/main/java/netscape/security/PrivilegeManager.java deleted file mode 100644 index 4481366..0000000 --- a/src/main/java/netscape/security/PrivilegeManager.java +++ /dev/null @@ -1,9 +0,0 @@ -// -// DUMMY CLASS TO MAKE COMPILER HAPPY WHEN NOT USING NETSCAPE_SECURITY_MODEL -// -package netscape.security; - -public class PrivilegeManager { - public static void enablePrivilege(String target) throws ForbiddenTargetException { - } -} diff --git a/src/main/resources/META-INF/MANIFEST.MF b/src/main/resources/META-INF/MANIFEST.MF index adae808..a0a53f5 100644 --- a/src/main/resources/META-INF/MANIFEST.MF +++ b/src/main/resources/META-INF/MANIFEST.MF @@ -1,8 +1,13 @@ Manifest-Version: 1.0 Main-Class: com.ice.jcvsii.JCVS -Class-Path: jars/jh.jar jars/activation.jar jars/mindbright.jar +Class-Path: jars/jh.jar + jars/activation.jar + jars/j2ssh-core.jar + jars/j2ssh-common.jar + jars/commons-logging.jar + Name: "jCVS II" Created-By: "Tim Endres " Implementation-Vendor: "com.ice" -Implementation-Title: "jCVS II Release 5.3" -Implementation-Version: "5.3.1" +Implementation-Title: "jCVS II Release 5.4.2" +Implementation-Version: "5.4.2" diff --git a/src/main/resources/com/ice/jcvsii/defaults.properties b/src/main/resources/com/ice/jcvsii/defaults.properties index fb7c5de..b692366 100644 --- a/src/main/resources/com/ice/jcvsii/defaults.properties +++ b/src/main/resources/com/ice/jcvsii/defaults.properties @@ -1,6 +1,6 @@ # # Properties File for the jcvsii.Java CVS Client -# $Id: defaults.properties,v 1.8 2002/02/10 18:04:15 time Exp $ +# $Id: defaults.properties,v 1.9 2003/07/27 04:55:09 time Exp $ # # NOTE Any property may be overridden for a specific OS, by @@ -41,8 +41,8 @@ jcvsii.global.exec.cmd.c=E:\\\\bin\\\\vim\\\\gvim.exe $FILE # # These are "sorta" global variables # -jcvsii.global.RCS_ID=$Id: defaults.properties,v 1.8 2002/02/10 18:04:15 time Exp $ -jcvsii.global.RCS_REV=$Revision: 1.8 $ +jcvsii.global.RCS_ID=$Id: defaults.properties,v 1.9 2003/07/27 04:55:09 time Exp $ +jcvsii.global.RCS_REV=$Revision: 1.9 $ jcvsii.global.RCS_NAME=$Name: $