From 82c3b0546c08d218599e99642889fe826dea769c Mon Sep 17 00:00:00 2001 From: Philipp Crocoll Date: Tue, 29 Jul 2025 13:50:33 +0200 Subject: [PATCH] remove jsch source code and replace with mwiede jsch reference. --- .../JavaFileStorageBindings.csproj | 1 + src/JavaFileStorageBindings/jsch-2.27.2.jar | Bin 0 -> 561546 bytes .../java/com/jcraft/jsch/AgentConnector.java | 36 - .../java/com/jcraft/jsch/AgentIdentity.java | 80 - .../jcraft/jsch/AgentIdentityRepository.java | 75 - .../main/java/com/jcraft/jsch/AgentProxy.java | 256 -- .../com/jcraft/jsch/AgentProxyException.java | 40 - .../src/main/java/com/jcraft/jsch/Buffer.java | 297 -- .../main/java/com/jcraft/jsch/Channel.java | 782 ---- .../jcraft/jsch/ChannelAgentForwarding.java | 287 -- .../jcraft/jsch/ChannelDirectStreamLocal.java | 71 - .../com/jcraft/jsch/ChannelDirectTCPIP.java | 176 - .../java/com/jcraft/jsch/ChannelExec.java | 84 - .../jcraft/jsch/ChannelForwardedTCPIP.java | 335 -- .../java/com/jcraft/jsch/ChannelSession.java | 279 -- .../java/com/jcraft/jsch/ChannelSftp.java | 3009 --------------- .../java/com/jcraft/jsch/ChannelShell.java | 70 - .../com/jcraft/jsch/ChannelSubsystem.java | 81 - .../main/java/com/jcraft/jsch/ChannelX11.java | 277 -- .../src/main/java/com/jcraft/jsch/Cipher.java | 46 - .../main/java/com/jcraft/jsch/CipherNone.java | 47 - .../java/com/jcraft/jsch/Compression.java | 45 - .../com/jcraft/jsch/ConfigRepository.java | 61 - .../app/src/main/java/com/jcraft/jsch/DH.java | 43 - .../main/java/com/jcraft/jsch/DH25519.java | 38 - .../src/main/java/com/jcraft/jsch/DH448.java | 38 - .../main/java/com/jcraft/jsch/DHEC256.java | 37 - .../main/java/com/jcraft/jsch/DHEC384.java | 37 - .../main/java/com/jcraft/jsch/DHEC521.java | 37 - .../src/main/java/com/jcraft/jsch/DHECN.java | 187 - .../src/main/java/com/jcraft/jsch/DHG1.java | 61 - .../src/main/java/com/jcraft/jsch/DHG14.java | 36 - .../main/java/com/jcraft/jsch/DHG14224.java | 36 - .../main/java/com/jcraft/jsch/DHG14256.java | 36 - .../src/main/java/com/jcraft/jsch/DHG14N.java | 75 - .../src/main/java/com/jcraft/jsch/DHG15.java | 36 - .../main/java/com/jcraft/jsch/DHG15256.java | 36 - .../main/java/com/jcraft/jsch/DHG15384.java | 36 - .../src/main/java/com/jcraft/jsch/DHG15N.java | 91 - .../src/main/java/com/jcraft/jsch/DHG16.java | 36 - .../main/java/com/jcraft/jsch/DHG16384.java | 36 - .../src/main/java/com/jcraft/jsch/DHG16N.java | 107 - .../src/main/java/com/jcraft/jsch/DHG17.java | 141 - .../src/main/java/com/jcraft/jsch/DHG18.java | 173 - .../src/main/java/com/jcraft/jsch/DHGEX.java | 237 -- .../src/main/java/com/jcraft/jsch/DHGEX1.java | 36 - .../main/java/com/jcraft/jsch/DHGEX224.java | 36 - .../main/java/com/jcraft/jsch/DHGEX256.java | 36 - .../main/java/com/jcraft/jsch/DHGEX384.java | 36 - .../main/java/com/jcraft/jsch/DHGEX512.java | 36 - .../src/main/java/com/jcraft/jsch/DHGN.java | 184 - .../src/main/java/com/jcraft/jsch/DHXEC.java | 200 - .../src/main/java/com/jcraft/jsch/ECDH.java | 37 - .../com/jcraft/jsch/ForwardedTCPIPDaemon.java | 36 - .../main/java/com/jcraft/jsch/GSSContext.java | 38 - .../src/main/java/com/jcraft/jsch/HASH.java | 38 - .../main/java/com/jcraft/jsch/HostKey.java | 150 - .../com/jcraft/jsch/HostKeyRepository.java | 94 - .../app/src/main/java/com/jcraft/jsch/IO.java | 133 - .../main/java/com/jcraft/jsch/Identity.java | 117 - .../java/com/jcraft/jsch/IdentityFile.java | 151 - .../com/jcraft/jsch/IdentityRepository.java | 44 - .../jsch/IdentityRepositoryWrapper.java | 109 - .../src/main/java/com/jcraft/jsch/JSch.java | 716 ---- .../jsch/JSchAlgoNegoFailException.java | 69 - .../jcraft/jsch/JSchAuthCancelException.java | 45 - .../java/com/jcraft/jsch/JSchException.java | 43 - .../jcraft/jsch/JSchPartialAuthException.java | 45 - .../java/com/jcraft/jsch/JavaVersion.java | 8 - .../main/java/com/jcraft/jsch/JulLogger.java | 53 - .../java/com/jcraft/jsch/KeyExchange.java | 398 -- .../main/java/com/jcraft/jsch/KeyPair.java | 1371 ------- .../main/java/com/jcraft/jsch/KeyPairDSA.java | 378 -- .../java/com/jcraft/jsch/KeyPairDeferred.java | 163 - .../java/com/jcraft/jsch/KeyPairECDSA.java | 467 --- .../java/com/jcraft/jsch/KeyPairEd25519.java | 68 - .../java/com/jcraft/jsch/KeyPairEd448.java | 68 - .../java/com/jcraft/jsch/KeyPairEdDSA.java | 191 - .../java/com/jcraft/jsch/KeyPairGenDSA.java | 39 - .../java/com/jcraft/jsch/KeyPairGenECDSA.java | 37 - .../java/com/jcraft/jsch/KeyPairGenEdDSA.java | 36 - .../java/com/jcraft/jsch/KeyPairGenRSA.java | 43 - .../java/com/jcraft/jsch/KeyPairGenXEC.java | 34 - .../java/com/jcraft/jsch/KeyPairPKCS8.java | 386 -- .../main/java/com/jcraft/jsch/KeyPairRSA.java | 461 --- .../main/java/com/jcraft/jsch/KnownHosts.java | 622 ---- .../jcraft/jsch/LocalIdentityRepository.java | 157 - .../src/main/java/com/jcraft/jsch/Logger.java | 71 - .../src/main/java/com/jcraft/jsch/MAC.java | 40 - .../java/com/jcraft/jsch/OpenSSHConfig.java | 316 -- .../src/main/java/com/jcraft/jsch/PBKDF.java | 34 - .../src/main/java/com/jcraft/jsch/Packet.java | 121 - .../java/com/jcraft/jsch/PortWatcher.java | 248 -- .../src/main/java/com/jcraft/jsch/Proxy.java | 40 - .../main/java/com/jcraft/jsch/ProxyHTTP.java | 183 - .../java/com/jcraft/jsch/ProxySOCKS4.java | 217 -- .../java/com/jcraft/jsch/ProxySOCKS5.java | 352 -- .../src/main/java/com/jcraft/jsch/Random.java | 34 - .../main/java/com/jcraft/jsch/Request.java | 69 - .../jcraft/jsch/RequestAgentForwarding.java | 54 - .../main/java/com/jcraft/jsch/RequestEnv.java | 56 - .../java/com/jcraft/jsch/RequestExec.java | 59 - .../java/com/jcraft/jsch/RequestPtyReq.java | 79 - .../java/com/jcraft/jsch/RequestSftp.java | 50 - .../java/com/jcraft/jsch/RequestShell.java | 52 - .../java/com/jcraft/jsch/RequestSignal.java | 50 - .../com/jcraft/jsch/RequestSubsystem.java | 54 - .../com/jcraft/jsch/RequestWindowChange.java | 69 - .../main/java/com/jcraft/jsch/RequestX11.java | 64 - .../com/jcraft/jsch/ServerSocketFactory.java | 37 - .../main/java/com/jcraft/jsch/Session.java | 3290 ----------------- .../main/java/com/jcraft/jsch/SftpATTRS.java | 295 -- .../java/com/jcraft/jsch/SftpException.java | 47 - .../com/jcraft/jsch/SftpProgressMonitor.java | 39 - .../java/com/jcraft/jsch/SftpStatVFS.java | 122 - .../main/java/com/jcraft/jsch/Signature.java | 37 - .../java/com/jcraft/jsch/SignatureDSA.java | 35 - .../java/com/jcraft/jsch/SignatureECDSA.java | 35 - .../java/com/jcraft/jsch/SignatureEdDSA.java | 35 - .../java/com/jcraft/jsch/SignatureRSA.java | 35 - .../java/com/jcraft/jsch/SocketFactory.java | 40 - .../jcraft/jsch/UIKeyboardInteractive.java | 38 - .../java/com/jcraft/jsch/USocketFactory.java | 40 - .../jcraft/jsch/UnixDomainSocketFactory.java | 55 - .../main/java/com/jcraft/jsch/UserAuth.java | 53 - .../jcraft/jsch/UserAuthGSSAPIWithMIC.java | 228 -- .../jsch/UserAuthKeyboardInteractive.java | 204 - .../java/com/jcraft/jsch/UserAuthNone.java | 130 - .../com/jcraft/jsch/UserAuthPassword.java | 194 - .../com/jcraft/jsch/UserAuthPublicKey.java | 401 -- .../main/java/com/jcraft/jsch/UserInfo.java | 39 - .../src/main/java/com/jcraft/jsch/Util.java | 569 --- .../main/java/com/jcraft/jsch/Version.java | 10 - .../src/main/java/com/jcraft/jsch/XDH.java | 37 - .../java/com/jcraft/jsch/jbcrypt/BCrypt.java | 859 ----- .../java/com/jcraft/jsch/jce/AES128CBC.java | 77 - .../java/com/jcraft/jsch/jce/AES128CTR.java | 77 - .../java/com/jcraft/jsch/jce/AES128GCM.java | 37 - .../java/com/jcraft/jsch/jce/AES192CBC.java | 76 - .../java/com/jcraft/jsch/jce/AES192CTR.java | 76 - .../java/com/jcraft/jsch/jce/AES256CBC.java | 76 - .../java/com/jcraft/jsch/jce/AES256CTR.java | 76 - .../java/com/jcraft/jsch/jce/AES256GCM.java | 37 - .../main/java/com/jcraft/jsch/jce/AESGCM.java | 103 - .../java/com/jcraft/jsch/jce/ARCFOUR.java | 73 - .../java/com/jcraft/jsch/jce/ARCFOUR128.java | 76 - .../java/com/jcraft/jsch/jce/ARCFOUR256.java | 76 - .../java/com/jcraft/jsch/jce/BlowfishCBC.java | 76 - .../java/com/jcraft/jsch/jce/BlowfishCTR.java | 76 - .../src/main/java/com/jcraft/jsch/jce/DH.java | 108 - .../java/com/jcraft/jsch/jce/ECDH256.java | 36 - .../java/com/jcraft/jsch/jce/ECDH384.java | 36 - .../java/com/jcraft/jsch/jce/ECDH521.java | 36 - .../main/java/com/jcraft/jsch/jce/ECDHN.java | 150 - .../main/java/com/jcraft/jsch/jce/HMAC.java | 94 - .../java/com/jcraft/jsch/jce/HMACMD5.java | 42 - .../java/com/jcraft/jsch/jce/HMACMD596.java | 48 - .../com/jcraft/jsch/jce/HMACMD596ETM.java | 37 - .../java/com/jcraft/jsch/jce/HMACMD5ETM.java | 41 - .../java/com/jcraft/jsch/jce/HMACSHA1.java | 38 - .../java/com/jcraft/jsch/jce/HMACSHA196.java | 49 - .../com/jcraft/jsch/jce/HMACSHA196ETM.java | 38 - .../java/com/jcraft/jsch/jce/HMACSHA1ETM.java | 37 - .../com/jcraft/jsch/jce/HMACSHA224SSHCOM.java | 38 - .../java/com/jcraft/jsch/jce/HMACSHA256.java | 38 - .../jcraft/jsch/jce/HMACSHA2562SSHCOM.java | 38 - .../com/jcraft/jsch/jce/HMACSHA256ETM.java | 37 - .../com/jcraft/jsch/jce/HMACSHA256SSHCOM.java | 45 - .../com/jcraft/jsch/jce/HMACSHA384SSHCOM.java | 38 - .../java/com/jcraft/jsch/jce/HMACSHA512.java | 38 - .../com/jcraft/jsch/jce/HMACSHA512ETM.java | 37 - .../com/jcraft/jsch/jce/HMACSHA512SSHCOM.java | 38 - .../com/jcraft/jsch/jce/KeyPairGenDSA.java | 68 - .../com/jcraft/jsch/jce/KeyPairGenECDSA.java | 100 - .../com/jcraft/jsch/jce/KeyPairGenRSA.java | 81 - .../main/java/com/jcraft/jsch/jce/MD5.java | 57 - .../main/java/com/jcraft/jsch/jce/PBKDF.java | 60 - .../main/java/com/jcraft/jsch/jce/Random.java | 82 - .../main/java/com/jcraft/jsch/jce/SHA1.java | 57 - .../main/java/com/jcraft/jsch/jce/SHA224.java | 57 - .../main/java/com/jcraft/jsch/jce/SHA256.java | 57 - .../main/java/com/jcraft/jsch/jce/SHA384.java | 55 - .../main/java/com/jcraft/jsch/jce/SHA512.java | 55 - .../com/jcraft/jsch/jce/SignatureDSA.java | 164 - .../jcraft/jsch/jce/SignatureECDSA256.java | 37 - .../jcraft/jsch/jce/SignatureECDSA384.java | 37 - .../jcraft/jsch/jce/SignatureECDSA521.java | 37 - .../com/jcraft/jsch/jce/SignatureECDSAN.java | 214 -- .../com/jcraft/jsch/jce/SignatureRSA.java | 37 - .../com/jcraft/jsch/jce/SignatureRSAN.java | 101 - .../jsch/jce/SignatureRSASHA224SSHCOM.java | 37 - .../jcraft/jsch/jce/SignatureRSASHA256.java | 37 - .../jsch/jce/SignatureRSASHA256SSHCOM.java | 37 - .../jsch/jce/SignatureRSASHA384SSHCOM.java | 37 - .../jcraft/jsch/jce/SignatureRSASHA512.java | 37 - .../jsch/jce/SignatureRSASHA512SSHCOM.java | 37 - .../com/jcraft/jsch/jce/TripleDESCBC.java | 89 - .../com/jcraft/jsch/jce/TripleDESCTR.java | 89 - .../java/com/jcraft/jsch/juz/Compression.java | 141 - .../java/com/jcraft/jsch/jzlib/Adler32.java | 144 - .../java/com/jcraft/jsch/jzlib/CRC32.java | 184 - .../java/com/jcraft/jsch/jzlib/Checksum.java | 43 - .../com/jcraft/jsch/jzlib/Compression.java | 176 - .../java/com/jcraft/jsch/jzlib/Deflate.java | 1756 --------- .../java/com/jcraft/jsch/jzlib/Deflater.java | 174 - .../jsch/jzlib/DeflaterOutputStream.java | 186 - .../com/jcraft/jsch/jzlib/GZIPException.java | 47 - .../com/jcraft/jsch/jzlib/GZIPHeader.java | 194 - .../java/com/jcraft/jsch/jzlib/InfBlocks.java | 615 --- .../java/com/jcraft/jsch/jzlib/InfCodes.java | 611 --- .../java/com/jcraft/jsch/jzlib/InfTree.java | 518 --- .../java/com/jcraft/jsch/jzlib/Inflate.java | 756 ---- .../java/com/jcraft/jsch/jzlib/Inflater.java | 189 - .../jsch/jzlib/InflaterInputStream.java | 255 -- .../java/com/jcraft/jsch/jzlib/JZlib.java | 92 - .../com/jcraft/jsch/jzlib/StaticTree.java | 148 - .../main/java/com/jcraft/jsch/jzlib/Tree.java | 367 -- .../java/com/jcraft/jsch/jzlib/ZStream.java | 369 -- .../main/java/com/jcraft/jzlib/Adler32.java | 139 - .../src/main/java/com/jcraft/jzlib/CRC32.java | 179 - .../main/java/com/jcraft/jzlib/Checksum.java | 43 - .../main/java/com/jcraft/jzlib/Deflate.java | 1754 --------- .../main/java/com/jcraft/jzlib/Deflater.java | 171 - .../jcraft/jzlib/DeflaterOutputStream.java | 181 - .../java/com/jcraft/jzlib/GZIPException.java | 44 - .../java/com/jcraft/jzlib/GZIPHeader.java | 214 -- .../com/jcraft/jzlib/GZIPInputStream.java | 145 - .../com/jcraft/jzlib/GZIPOutputStream.java | 90 - .../main/java/com/jcraft/jzlib/InfBlocks.java | 614 --- .../main/java/com/jcraft/jzlib/InfCodes.java | 610 --- .../main/java/com/jcraft/jzlib/InfTree.java | 518 --- .../main/java/com/jcraft/jzlib/Inflate.java | 751 ---- .../main/java/com/jcraft/jzlib/Inflater.java | 168 - .../com/jcraft/jzlib/InflaterInputStream.java | 247 -- .../src/main/java/com/jcraft/jzlib/JZlib.java | 92 - .../java/com/jcraft/jzlib/StaticTree.java | 148 - .../src/main/java/com/jcraft/jzlib/Tree.java | 367 -- .../java/com/jcraft/jzlib/ZInputStream.java | 126 - .../java/com/jcraft/jzlib/ZOutputStream.java | 159 - .../main/java/com/jcraft/jzlib/ZStream.java | 377 -- .../com/jcraft/jzlib/ZStreamException.java | 44 - .../javafilestorage/SftpStorage.java | 2 +- src/java/JavaFileStorage/build.gradle | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- src/java/JavaFileStorageTest-AS/build.gradle | 5 +- .../JavaFileStorageTest-AS/gradle.properties | 3 + .../gradle/wrapper/gradle-wrapper.properties | 2 +- 247 files changed, 12 insertions(+), 42705 deletions(-) create mode 100644 src/JavaFileStorageBindings/jsch-2.27.2.jar delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentConnector.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentIdentity.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentIdentityRepository.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentProxy.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentProxyException.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Buffer.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Channel.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelAgentForwarding.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelDirectStreamLocal.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelDirectTCPIP.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelExec.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelForwardedTCPIP.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSession.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSftp.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelShell.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSubsystem.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelX11.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Cipher.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/CipherNone.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Compression.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ConfigRepository.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DH.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DH25519.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DH448.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHEC256.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHEC384.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHEC521.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHECN.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG1.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14224.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14256.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14N.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15256.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15384.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15N.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16384.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16N.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG17.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG18.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX1.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX224.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX256.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX384.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX512.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGN.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHXEC.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ECDH.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ForwardedTCPIPDaemon.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/GSSContext.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HASH.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HostKey.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HostKeyRepository.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IO.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Identity.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityFile.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityRepository.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityRepositoryWrapper.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSch.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchAlgoNegoFailException.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchAuthCancelException.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchException.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchPartialAuthException.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JavaVersion.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JulLogger.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyExchange.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPair.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairDSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairDeferred.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairECDSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEd25519.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEd448.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEdDSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenDSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenECDSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenEdDSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenRSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenXEC.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairPKCS8.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairRSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KnownHosts.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/LocalIdentityRepository.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Logger.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/MAC.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/OpenSSHConfig.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/PBKDF.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Packet.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/PortWatcher.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Proxy.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxyHTTP.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxySOCKS4.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxySOCKS5.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Random.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Request.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestAgentForwarding.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestEnv.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestExec.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestPtyReq.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSftp.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestShell.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSignal.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSubsystem.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestWindowChange.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestX11.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ServerSocketFactory.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Session.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpATTRS.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpException.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpProgressMonitor.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpStatVFS.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Signature.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SignatureDSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SignatureECDSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SignatureEdDSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SignatureRSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SocketFactory.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UIKeyboardInteractive.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/USocketFactory.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UnixDomainSocketFactory.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuth.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthGSSAPIWithMIC.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthKeyboardInteractive.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthNone.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthPassword.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthPublicKey.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserInfo.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Util.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Version.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/XDH.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jbcrypt/BCrypt.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128CBC.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128CTR.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128GCM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES192CBC.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES192CTR.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256CBC.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256CTR.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256GCM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AESGCM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR128.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR256.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/BlowfishCBC.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/BlowfishCTR.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/DH.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDH256.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDH384.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDH521.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDHN.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMAC.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD5.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD596.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD596ETM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD5ETM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA1.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA196.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA196ETM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA1ETM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA224SSHCOM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA2562SSHCOM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256ETM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256SSHCOM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA384SSHCOM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512ETM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512SSHCOM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenDSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenECDSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenRSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/MD5.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/PBKDF.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/Random.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA1.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA224.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA256.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA384.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA512.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureDSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA256.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA384.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA521.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSAN.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureRSA.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureRSAN.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA224SSHCOM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA256.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA256SSHCOM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA384SSHCOM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA512.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA512SSHCOM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/TripleDESCBC.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/TripleDESCTR.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/juz/Compression.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Adler32.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/CRC32.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Checksum.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Compression.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Deflate.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Deflater.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/DeflaterOutputStream.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/GZIPException.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/GZIPHeader.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfBlocks.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfCodes.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfTree.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Inflate.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Inflater.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InflaterInputStream.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/JZlib.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/StaticTree.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Tree.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/ZStream.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Adler32.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/CRC32.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Checksum.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Deflate.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Deflater.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/DeflaterOutputStream.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/GZIPException.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/GZIPHeader.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/GZIPInputStream.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/GZIPOutputStream.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/InfBlocks.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/InfCodes.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/InfTree.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Inflate.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Inflater.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/InflaterInputStream.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/JZlib.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/StaticTree.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Tree.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/ZInputStream.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/ZOutputStream.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/ZStream.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/ZStreamException.java diff --git a/src/JavaFileStorageBindings/JavaFileStorageBindings.csproj b/src/JavaFileStorageBindings/JavaFileStorageBindings.csproj index 7ffd0d17..0785877f 100644 --- a/src/JavaFileStorageBindings/JavaFileStorageBindings.csproj +++ b/src/JavaFileStorageBindings/JavaFileStorageBindings.csproj @@ -34,5 +34,6 @@ + \ No newline at end of file diff --git a/src/JavaFileStorageBindings/jsch-2.27.2.jar b/src/JavaFileStorageBindings/jsch-2.27.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..adb35a6d1a4ed0330ee61ded8e216985a1e4ed5b GIT binary patch literal 561546 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�k}dBcQU@%Id0e&GBM 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

H90z5>2q+T@uKrbO z7F_Cuzee>)>SCg+{3j>!-;n+#xdxAsu=F3CMgK7h{kOCsEdD=|Q<7CyRFP+6{m&IU z`2T?I&=2%Sd)*OoSCJlwDomaLo=$rq;`h%xrgpQ#*5N{XAS0qTz#njMsEBah{CpLL z!`1G2a2Jw|Yfe*H>Diy3$EO&5oEI=1GuZ(Iw}3oA`?i&*3!D6(P}!a%)f`^iQ_pU2 z&#@q$Ej-)MZXg|KsZ-KvK<yU<&W&q6E<}o=S0uJ|}3SpVtkl)TpfEBc*)4IdQsu zU2~HWwHcayl#7eej+lRYo&Or_yrycAHUO2&%2XpmTUpymz|=QNs3({j25EB2S!>Xf zGE4@ksoytQj{Rp_2}N(#LL?QzX3A4AWK~!ac?gZGL^Gkddw+vt8cd!;97tV98%4g+wifg)g5#3K zbfHw;1;qh>qtcz_en;+6Z`MGfIMc4j!nY(x#J5!YqX)LIU>hyqGG7^a7X{WyaAiiu zd*OSa9g!ayC}sr+B#z35Q=8IDo)BwH&$ckgVa54L=>zH|fT1FV7Nh+O@7i5)p{yUg zCI1m`tpBQQX6FAW+D2aIUjdeYN_zvKGf^#wQb`%cbX1>MOnHiZYf_wT_7ZXCm6}?;(w9%ma&m2 z+0tO!ZZk78Gcz+YGc&fC8QRRu%*@zkC^NI$>^3vg`p%oTpR~F&qn%$XtyCq|@2HH7 z$jEa}ioTJ$jwsvjZ*92QXTqdYV~##$5c+t}F&Z%ZnMdUB=J_?+KUe`b-jB7EinUXQKrjQgR?PS_FmSO{M$k zGm(J-e34Zs2-9S<2?3sYV$aVUkKgh}Lb0#7c#?~sL0UWs%Arcu#~H8yo3O@FWH+Vy z$?v?%rv*?hRQD9>xREDpF7m-lFVa)sX~w6}Cb-KtRT8VHh<96g}sw(6DTJ80sV!({x-u4>lga}-lYA#z=;Yov9kSB;1v4)$|kbF zlT$h(R1mN8+?A1RjTWGXp{*DQbr^KUl&Ckg){1D!Uexh^hJ*hVPxOe!bcC(?G%`2Z z|6YC^A@^rKTcgOc=ts~H3|F{KD983J_nz2fxCMUf@R~nHmP(~kdq&N7cV}rbK%Ah7 z8!0_PH(k+SCH%frCs+1~+RGF;6sky5%GY-sa--Q1A4PsaAg{_}d71_rK!u~m_e@_X z)7_A80U<{2v29#jYV?agGv@tHFQ!mbW_QejLb>>q)N(%n01>^#AKe7`K#*RX<5$_F zNArxliIgz|G8_4OiP&&szha!``l4w|kai@iaH9h0u&j$wyEmmLsIP6LZJJW{V;sn8 z;-@}&i=zJi1r1I#{$C&ye>-(>r@ZZbVKS2I}$XEQT)PMj==;y43F>Z79 z>(Y|$9ufk(g2)fSde1_4?UEl&<&spE)PLrmp!B}?LF4y^Ax($xhCm$d!rXoyeIA+| zzVF?`_ClE@S_nA-hl)UJfr4dK*sEtL=q{g2O;WDEii3NZlY^H6S8LmCFSUYZm>I*cQS{HjxvMa?Mc2y+Sv1b$rbMM`%_~a2yhN)*?_YEAuk-qH3$3KF!D8 zu*r~sB(XAWmLN1UC+WbnNkALXI7|K`{7Znm@dB$@`(5GAnSdbXD|yB+>I|~Qhx-gEKklbI5=a++Fd8kllu~hGaz0(|^KfV%5?s9*qDD09(?dbYM zi}qZthKxe}Xb+JM*!O5gr>SyIHJ zkx3VEPHoLSVn%peE*OZK7Qt{u>RfD;PuUN7xIAW{C?g~Q=lWIxu`zdnhKwOZazZ&f z5AN9oj8ggf`#huJ;Xl-BJKNXv=hxrL|8IA%f5jhW4wnDrkF5MZ`J*LT@zY(Qi!l6w z0310AeZgSPq0fO-y1H&9_KQEBH}oC^WO#2t9~67*Ut<^kF+ zTrAMm6o^)OI9yKji16vm^4;l9i@z>lA&Q|f$IcQIY;a>?FuwCoxOLwiGyD6+MrBbw3-gSr^M6Uw7F5t2ZgA5DHS>EW!C>RgFxEP_|^SIHwvH1SO z0Y-0Tp5XpR3jMt+5EcHy`5zQwWMKLy;34tSe*qpcO(E2$2=tp?z2Ez$)%tT2OS;iDV1;7r(LKVACoNsO#%g)%G60l?rH_O zV_=qwQA2{^gfP%|Os6%v-HY(3>R+OtcCHxC*y6Ra)Kh)2VrnjA#N^oIqgv@ub<86+ z+9eWz`@AR8yP~%jL3U2f-NR??rHZRlR)IaaRhR5l4jlIQ+o(#_DFb-u#&5ZfHjc}_ z2}B#83kT~6{tLL$@CVqe}YViWYR|eXHdKXQU3 zHetcAufJCKzoHN;(?5Nl%RePZohsy?6f#7%C2;I_7lb7Xh7P6Hvn{;h^Q0A4k$Lm-51N2R?4FJMw7MFlt03Pa{T@QlXdV z$(0D1zw}ue57&nyHokIeUp%L6{h`ww{56Z}e<V~G+@;7tz_mi+2Y7p+XHr!IK$*N=ex7! zqmRAiytgItcC9n9rzYEvv%L5>N;2oW*&mhOax(?;Wz(<5-}R2NE_ptVyi2FM-beSo z$tfoLwi%>3Si5hlrXfnhvsOi$7X0Wmv}I#knK87r!3~EMQwB*1bTcGMu0yBB==(am zJSiCV*D69*GuZMR&9yA0ppu-22cznAPYU_{9L^V-m_*aWFHtKtlwV9!)8al7 zw~!GR=u5?o5>uKbJW<$eXY1fwiz^a?HRMi|fMt1R1Ywq4u$t(%2_YV~MrvtT72zsY zU^G~zJyzji%wr(uP*m{YTovE3KpwHciQGeh!zH$m6l>H3WzLzZa$w=U_>^$Q$dJLQ zWpL?=u$At&byV#ZgK$E9o3-IsMyJ;MVdD^(6z&+})iVrfp-`5eElulaUgf)%+05LY zmi=|2!#U$ED~m#v*JA86qPY9x71IXvrej505RpItX)S3^Imsrc1&Lxsg7(|>m4!E=!r>!Jz-SM! z2^tinuf?D@@Zex?i0_VQYE;ZdI6?4m>qe0nqtQUel3FBgSgJ!LhkyEVSAsDg!_M{; zEvo!BE(mIgS}x#3kJZNHPZ>ZMSGUNDwA0#3jii>zHSmbfy5_8ns=BbS$sVGp9;8yd z^e%CAV1gXd=@HlysxnJ}=dL=iqk*zTD(}WZ4{zngq^5qP86m|&)ByxzOs!60+lH>< z+SFWL=f_$a550gNF$Y2)mLh3-t%&%glUUelu90O7vVt*4`0h}lI}tkf)~gxgCcw;d zSsRmNwq>POJV*`3Au$w*hCICBt+vS!gB&Jgme(sioJOKjmey~Tb5Il08V&s%7Sowh z5~O|*+d@7oCR8%5nQ24HY-=P;M1UTDYT7R(dRN7|99SIcpHIibs7r$qM-tylk1&Th zIAqGF!Bg9PZ&Ta*DpJ`+T3t#KDF0=#gN1LGx9!kIJBO-=c5KnjKtvbORBNHHn%b=pzE*_iWKZDPgCyW%ED2P<9PC%?D$`+o+%b*T-(&Cc=uVa# zWS8oZBO&?ql%y-anpGH5}My9kDwJVzj zR3)&a){x^yl6e)R2UkgF+IcYu;^Q(B{>WOY9J9nB8>fWqKz_p8!cpe15z-gf;~MA5 zlU0g?R|wTqSE69i8|`mD_Yp6hyZVVSQcVzxfU3a!~OV`H`Wf>mouix3hAy(8Dvc@W)c-`*X)uDD)^KRpD=PQK zb1SOzmiikMvZGvK#qN{=AO7H|_Xm|XlEX8PyNFVxQE9_g#_sN{GjZwF7Le}k1R2kP zIPbq%yB@gLH^~iovYEbF{(XB>=2`j%sm1wI)jGw6}!$Lhh7y6 zo#H&AYU9jN@YitApt1q|EA`OsND8m$COv?z#+sMqZ#-e$z<`M-185cwtUaxC-}W{)f#g`Kc{ug>xTdT(YSOPh?`Iwxb<=I6YL}{44vnQV8xn zlE5kXv07#n_N}8Lf6t)+G8{iSQwYBHwA^VF{$|z2)@>D}-~BW0(u~|@m!9Y?2zsrm zzx8@?n?W~}dwt~2qN)iU?I-sHF|js*9_4s8{vdXJ=NS(4AL%wg;f8Ht!b=Dh0>|UA zy4vxb)9qFE;5mo5f*L|8^tWft0Dkhf{5~-vevR7-BIGoeI6%%@o^iL|Cn&f) zkRz*(+HUQ(OCH^m-keGY1?oK&Q?ywtR|$bRk!y*n9bG+zOwZ}WjriTH-?>O5Z;k_N zfCDepkPrJsbadBf|0!$)f|70op~gRYvJGx|8_f4|=Mf0ZFG>@u z%!!WX6zJ5gu?ao^1v?dp!^f`;0Wc7yE_X2zYW|{K1uxYd5?9_;!t_`Mp+n|Pwk~^? zD**`0Bt!8dn_K!Z^f~J|q^}B*eDe$BFSmEChB8$Q`RyCyzwO4t``c9Q%k6!o<^RX< zB`%_V{w9%~yQ@sPiBo_|HpebgRXEb>omH}-4UwvYLKV*NwFR+6y75ne6*1-dARos2J;9qb&sh@lZ18#OLpj4{`mnrl)P9uZb@9p5L*CGV-U7Va zLJ^PK>-`!+6&AYJmU|Lh5%BfGgqFFWVua$K;IsWvgB2^d`*KE44E1)D#wIVdb5fyO6dA=(@mG=lM8+oO>D^bfwjJ1zAHP zY5%a5EJXOuTGcD%sl}3Bb|!_Pom?`7i`6gYjgXFnkMr|p6MV4##4|s}@@EiwV}h39 zp#N!nlthF<3bOT|ldqBeitODiI8o#UaL%R<8z&X*to^U2SUmwQDzb8>{pAQ){yi!K zV2mOcio$~)zj2&*9R(dSE$S2p*nf~li;CMxu!RKzg&MWHNh%jB_(~5fHrVfdJon#W z!TwI^wXD5aq$|@s>o?Om?RCNGiM+hO*0WdVA#9y~7%}>&5g=Jxgm1H4uAHn(@{PT; zZUf>cfbJ2mbuvL^R|VJs*)3cVZww~0*5`Gpf~^!An#}#K+8JpZikiG7wzcId9J1)p z`V>CIoBc?Hv0!I+a-gs+!IW9xL&@aw=q(>8)7{GNu0X`5Ni!hvf*eW6+t0Kn78UK!cW{1b634rGK-Yr{V-CeMwien<7c@7V% z{RV8fO4g@zJ;86`4qMBd-~0y!TRs#9sJA^Yim$jM@lRhE#P~}TcyBu*h5Shi<#5AF zHwFsHK1)7QOv0$OlPkRZ7+)Q|+!^;PMv%ZtY+}G43WfY=NgkfFDHiYzJy^WG#h&BK zP=!xe6Fd8~QI8fySN{DoK+VY}=`f-Y%c#g&dR)p(UDzIZ5j0UnGj3n6N-Q3CTi)}& zA53OtwDV-h27piv!wfna=f5*WMSGJCwr_pk^XTT!SOU1*Ww2D!R=JVMX?P)kQ;q(H z3S6-6Dcv7-sCB~>wD;G1k~EBdrs$PwHO>6<6QC|sH;Ha}zvz(9iez{SkNE1ELNSKW ztdL}STc6=5;8Ye4r@B-s#-o)NpNQxS^XTG1Jf4ci3}21e?M=_hspkg-kOP4ZEwL&GQPZVbz-&G%5xDW=Lf^E(sPP zt5y)@?kimJQ7e_1yz?D9S4pnK%X=*@#M66IC&P8+Ij@XNA+w!|N&K84yN;bBwyk`@ z%1UX&7fmQ7{83|@9GTAMj|L_EYB2Pzmwj2Jc3x1bcCU0w zHNQda*|9jSWDLt`I96%2r-py=grI4TVP^_;S|CVSBVft|NwBNM+o{4QKq=pd5!DV z!gyZ16G1^MO{tSR1~dOK(Bf3#aeyx;YZzG#-m0l#fr^p%#_d(N2<6nZiQ#oK?6P-} z{T(2&kQbB7!d?+#h3J)eJ=|&lwVv)hpy@rdI=VL{p;CaMdh=K=!#M5|$HU{CB=E*}q277ictgi&0j$}O~Q zQ-)<;g1cEXSr+uTrI0sldc zGbxYfQ5ob_PE3pi;Jc{wWZsBl)7gA}cY(`Fe1zmnm|~Mf#gHqtP%a)W6PkCkNu9rF zcW$MADsr=Df7@!9x}rB@`Ut(H^yAE&d^b~0W4}<#lHAqxHu8EoC%>C|G=TTn&wuNt z}SqfUj zhB;$Ahv2gAw#WJMT~Mwy?ZS1Xca3H54AY~K>lVJ2 zpKbDV;`8zacI0qs>PrTni1s_ zG@j~q3eR@&5^>@5V54mH-4)%idn=}4@RcvRe!ods#&q2v=~mx%9BHfmuD?lEU=>b%11 zvcW-G#S0|FG^&;9Rt<zqlaDx_WcWP)FBW&U7EUe(9!GbPk1 zQp44%pS_ zsT}1EDpjDrzjdXMt^+8lplJQBkSHQ5esj|hofg!^dS6h6`|W<;ph)a6sg)57xUme2 z=ato+fsu@i4$|JF$h%q9Fha(}?5vhlq9JkX=lErr!v}Wav+#v6*jM9aBo5UOH-ALW+uR zc|&hLETk)c>D0F-C0B{pZxOG-tK{`o&(hTD=dwebE-di`H-Wjdm8`g|ybpTyjf=|sxw}}g5#NwnHlZlFmfT& z?$7dY^(UE?d-Z`tvu}3E8`xiL8-yT>CHpECHwFE7Z2S8Q7;(mb-doznGRl9I69-?$ zvp^CmP=Jz=tY{S(sh)rt0Ragw6qivu3R~ci#v~QJ(WS*Q4-7HZ_fyn;owl|ivtwU9PLLJD8F~#d1ESEew zyAmSLp&^ZUcDhSR<}6&icTA-}co3vxa(35Gl(4Fk0@%==uR&HtjOlN-MgJb_=e@vm zWaGyGqx?)HN_MX_aiVlgO8%x=G+4Js^NE^gAtWFiopkR0QE}3Cg8@zr}Z#KfY8}G@^(zyuJDFuHQ7bAJ;Enz2d)zpkS~|!c;Yav+G7hkWy~)(Iioa zcW(|~26GXrn3F4CvJ7BCnZe=uYK%CsVtugb3?JoVI=|l*w8cVf3LMOuq)!&!s7)!m zdI}-}oXMn%e^*;B)mK1x_4$FwL&AM}r;bPMz4tLl>=&YxPoNuVrBdlT^k<`uGey-T z;jKQ4#kwGYYwTs;&jPfA>ZX#nGn<_5fIaQj@G2M6UjNj2>I2#2t;4JgszJwUt^8S) z|1~p!Up8CN<(;_p@%^uL`Lath{QV2d@c$Ce|GNh0@9;b?P@#`N7v&Asqv{5*4Vwvn z2qe6;-;uaqfjs38u3`v^JYKmzOukMsUE6POr4}!#Unj~NL5>3$xlC!5zSRPW2w_9B@OOYMqixVTomO78N;bDyqx&9U4dG6_ucAdTJeIoI z`dr`qSAK;;L62vy=4Z&i0F@xD_67Zqfc{-`s))qb0{!Pzt8Fs0dyFZ@$fet>YhCm^ zzS&_C=U^xs%aQV=Wg6!slas}3lr7slOni|@{!D-fA`v9#K0-mTBiu1T5>7;xr0Bw@ z@0PBvZjI0K{fF=6tM~MK*R&UZDeohjEowYRIR**eE;d09!Zos=cz@TkM?L3O;GJMd zJ?B8TX1y&k7YXO?Zz3-XS3_!X@4^CQDT%x!h`2li$P@(e{z%Aj{1F24I$}P{YprgT zpTSnT=4r$^Y|kLfxRA0Fcp2#|MD)as1f0CYsieiox829>l*gc}FFGoJC?^1T7ZM^y z*Y=iEY}|EfD$ZIw_MMzaEB%?;3#)lK&%{t&>F15j`3CF+WaK_39pni|T96Deg^xXB<#@UKD*SpM zUBK?3H-UTtxd!;s2JD!@3QQOyqX;x4(gjqSP?{zbEr|j+mUTfi(Yhv>CUJ&oQYl03 zOgJNBj%6ZZ+X$L?vnHVY1w;v>QV=B6#!%1Sz!FvKVxvR|HC3tAgc&q(wa2hDg!q0Q zn#d**S{u?~hFF=fbR;&2CzR>e}AfJ~6!i+M1?S&xOT z$g>GCH!!Zn$tuL#M0lDoFA!!D|Fj90B8k%jaK3-5a%I+u8h)corbiK)yR>l11*d zN>aSS#}g`TVh=;8Y)ka|hodx~eii+6%(o@|hnh;VJtTnH7v#W9|SpPBiSX(t3X!aQbJM7Sd8IO#Cu$v_{qGV-_|hAjpcN zSqWCfqoR1pKgFIv;wtn;F;+|ss>%p884*hrsdXy%Ocxa;$48jyF+mlWTsLBRecu-= zM^(B*eJhp~by=0w1LHL{iabH6RT>$k?@QKGIk^C0hr6LCv_)lGVntRtQ;@{Bv%>dq zY?WvRIaY)*6==r*rW-n7l}JXJ=0TqUubPyTF6NsaI%eW=gn}0V@{;(24y@>^nPy`X z(v~tlXXZ8lTRYaWinX&LmS&{RqIg}oUKnr1{Z9qknaTc9Fr+$39$ycZSq*7#`$t>(>lz%-*&Gl+{S_a^$e5al9zTG7j#e!KP~2(g!f zbn`N9qEAOS=4vhT_$Uy&IQV9NErYI$1p3#zKP%;2yD?kKZ53P*-iz!Vb5Y)>G5u~G zs#wo>I^p^4;3+cDJQ{pv|@4vttaA1%J2IR?mZFyWr zACJ(ED!+ECPIv$nblY_&>7H=56uE^CkJ8+=lDZ#;I=`y%JFa8#4nRVrr^X~247 zRsXNQwoWj6G=%G~-fLfof2ZyL$|JG<&z*&BZ1-O+S0U4+gkK&>3ra?!u34g5RfHS? z8Uo|%MNQp!Y@t00ex-yP9R@!dQN*@zC_A<^;Et2Yw|J8Dyuzi&)pDx3>et!S1(IXW7IOa1qO z&|^bPG(+l9Wkm20?=le`u=uvFc0QbF$fb0Eii;eB=X*Iwm_ceh4ozr`Gdt0VPsHK%tNDgy>fBOty`h41EhAxpz92yxIo85)N-<4E%YqbAFcj zm}$DjulM^~)XcvIlm`#_%XpTbWPPnq<^Nfq99)>I4v_19jvJ(D=+8b97Ozy$BazN% zXswPZb@SJ^0%XdX6z_I2jS(u6E7zac?otj|6_yXNDneOXAe_u>Dl(f%bD#eb9f}?YyegY%dCiPJBS?LS1b`QL>e{qn?uZf;zxZvRm`8#0f+^Pd6zS3ZgLe|=I4xQePeTIh7BIQVlcfzb#Y zTHRxUfqEdU;^2dO0nc|ufoRqexiyk>$;<9k$z2k&C}U4%+XNZ1?$mUXxl@^!k4HmO zQ`0f6$JedyET{1;^Gh%IkETn1C%fR&gbO4cqlie84w6(FI`*Xn4JCZ*m>Nska{KVb zWSMNvLLHr(;HMY&Q<5LyA)?8abc@BsZFe%MJ4{0dxJH1PcrMAM2v4A0r3E&15o@eFiPwe_ji!92HJl^g^*#w}-7Zlb-_`tDCcSA+ zVR2M6)zp(|k6k75L98`9HXp#vNaS@CCkdB=4drr zQ8txaK-_wHSM0FxluL-U(*shI)7ym7LvjGFWy)rIzN8F7$Jcocym)Gdd1C32%1O9& z+Ua5H$+)ws>9OWX*$PExSw(*W9Zl7Xs5*B{Ox>zfA9|4iz)e(Mjt2B56kdD&4e&LJ z4@2&z{QDHIdqSp!o|KUc`kdbylR?f0gX&Z{F-j>T&ts&OP=v2C94Yuz;RaR#JAaCB z0(b%O?n<0cdr5_iqMTs5NydyKoNyq?d+{|{{$d9r-uYR<$$+s@RlLwyzyPDVW<+a} zGJ_K5;;=lkTx({w;a7*GB|!7*C0pzf>Z5HqQ%pAM*t*^n;}AzWSIQ&J-lIM01K=b| z^a2&l0QjUx8i{0A_{i&eN6010N}4$7^dl=8Wx9cEz=3N9s)Sn2pxyyhCdv>w04qvy z`0RV-b$0`rbh5QWf+H=R>e7ytDNZZJ>G>$vog!N=HFmvlJDyXL?4SG%|Hou(M(Nck zAyeoj3T;}F%&U0EMo?quiez!40>{b_tIQe`n^xtEUR^+Tn@&44fvwVM+ zBbF<4e5KQvF_8n>IPDeuW!KSK2e$6o0Nrpp+bx_S-$L)n@O1c|6L1ITd z^n7QgM)cO^#M<=*+F9ub5|Mjl_6?i2+~!pOogF+@*{^;fA89|Ax^$HH}{Y|g?!Bm-e3y3VPElW z`bz@rY-g>;*p|=a#pxz{Tfj>S?PlkvA;bM=oyxBPhm+SU2!4Xdm)ZU&V%<4h@i zVH^sh10qN@{R9hWA)>Z;seWvg23jx4K0Yec%5s+RxT3~c_pv%t`t+_C6HSz2T)q5; z)y{5z+m*;x^0)^y_OU)OD)h*5xD=@|W53(ES+(wcWAerD_bqAjENPb=>uKp_hef-y z0=5Z$+OmU>j zu3P9#gnkZ+bcx79k?p7_N|A3Kdy4 zq(D6y@lSn;+i~$`_pt1RS1}&l_4E>yNL0)Zkupue_QeV8?97e!+0Ta>0aWx{;mt+f(yR2K7}(rqzA}?*y24Zj6tZ`xE#t z>#G&)fiwvA?c3{DApfspt$$^G|JjH2udJ`801bh`&kht9Q9Fp}!Z!&?fKy-aU@yp( z!q3w4&7L&S$59@HNSqeoJMrU>Dgubs2c!3Me& zGOFs|3zu^_9UxpW$NJoztp-TXs`nudT|Q8dw0Z#jV@%m$LqS>OXU=atabq%QQoph1 ztB6#Q;NFtI62h=g?+FvYs$K2n$c<=(h#53vHB>S!$Bx{sDPnM|)MGm<`vN15VUYNu zG&MYQKUwbg%cAT=w;ApCvwE#&kDs(^m+bzwO(%i4P1x=;y<#K2?_qeKg3(|H^`{FL z|0s1Q;;oGO@2xM}e{yPQi2r|cYLaroWBXsHmI|2`V~Rd<$vixP!Te_b+Edgp zR8%B{5)zkGFHNzBbNNz3=cIdi z`PehfGkv=?&3VN4_-^;%HTi-dw5PzyN)k*oM#xBu0xO9G*x!dA!$?z(+pJ|U-oDBL z!c=duUY8V7y6wvM2%#lGDOYaQu8%{CAPrk+Qs60)q;LzB#$ug~Ecz83oKx-Y8Q!Fj za0Fn046nX@J(QwYWwf`jD@7E3*+(-md&H~~mvWhy9>d$9?IeiJmB*K%!HHwn5ekVh z|41?OoNn<{%kJRSK3<Mm14BU?#m&f$E%X!LtAT2op^KO%;8tNtQO>^wD{v)2zENWXvU}Qgjw6v% z!}g0m+g(RLbu*uSS&!!)uibs>X*+~kE8hXh!E^ak@QO&#%jl#gs1{iqM#SMD2VX{- zn30m1n4vDJC-fxTCl}CvMX-<$^%z^qB?Uzd9DHgehBZvMtjVMd0-8vfNdm^EgP8y& zcWq59pCnTTQBAbHq=T#S2A&EEYJ<`Sq7y1=R8J+MC*{) zKnkFs9~lBrJ5)EI!cl7P5gjDEey9$AHHfsJO}Ms6d9e1Vw2X+Df_GJ&{fq}#)6`|p zXnW9JD7d!x>xbzlFBcXzKx7<7Lv`OQ7lhEvVCa9a4cGm2A`czX5U0I{pljBq8&I_3BsYVhW=PY5guWkN zk?9VETA*T!#86|FWbBH7E@MrTsy0O(se`jETb_y2x|Ce?KVLY_+GMmDL|-8D1F$nh zcp@Ju+CQUrM^Tiz3|#$ zHVY_7uOL+uy1AiNLJLK_fGJIXB+j*kPz7D6Xi66+8T&;lZB^(|8PKT4zw=3v@<^#3 zHlP}>OHTFMtI)FbP?+!ep5Wkbw^N8MKDaOR=~d8G zDBizKyrcw$C`yN7Ft!B2p>JzHJZLtSQnN z{)%xdpVYLBfT>7d3}Jbc&&7*Asjn50O1`7YGV_{jQUkZm@|~$A|TN-$%SclD`U5_hF<(_uY6|% zQk3!zA*$Egsz^Rwk*`4;d2F4hvCwu3aBd+NEl6oaqgQm%+r5yjqfi)iOVv3J!njr1 z_g#B&-wuCPq)TjbZ?=6I-!MUa&SawGVgP#qt+LHQ$b2@v2@kpnL*IF!+Bfxtic~+9s zFhwoDr+tDM`>9i#Vct&r^Ck=5d&_eOdMW8Z6#kPZEAMdKh#2~9TS$IgdZSiUbDy*` zEpviG+8ai?8-!*LjuhZ{I@tiMxggb4tk+_ytap9f0+6{b_uzU1S)!Qhx#(?{iL@G9ya1$azMq%+LMT(pHzIWceYvW?Hb<(z19W1oop^wa zKi;|`;d4az#24@ufW1h;zt$rK=Yyzcfl*jaK{RuuD0qHJGjmwWX;$2O;89!}tk@ZeO^c7b9SpP2r zUizleocWbIyTkuC2Aut$*>f6blG-BL$n57fk8Y}#N6g)Ueo2<<6-xG3iQ&;$FFC)$BoO4&BqI`X46i_lHf5sv(fLt zX}u1}CV|!AKhL*l8>DTNWJb2)bv=h%W2zKOU4^X!sRzl2A8Slx1-85=6VeqDX$FHs zGWW?gGMel)l$x4YTM}6pI zLVY@#W2GZvEOWPGi(*djuoGu!$SCoC>*K?mZF2UcvK|+1Jw+b8-&?;X-W*!%PJXVg zWGH-cpCcJ}JQpK++={w{A7dk@BP6a+Hb`C;Jq^nF3R;A$1TVXxEfsm?7Ok{tT|X5w zv>O>#F>t=Y#<8QN!?YQGs)KDro5y(vM*pt)q@J7KmH3byu89Y=>;fC_t0L>SZp$&4 z%Www!oO_i%-tDhN2d`lzto&?to%^hYefzx@Wv`XF``fzo*AH8=#OM1pq1t7zqC-FW z>{~x+5IuTWR?QEuUx)pNd|C17cvdJ{+7x+#-=qL0Z zb{%pZePGSBb;=s0>>)cv-W7UFR7?3pTT9vAxUBLPq<)B`hx@tD%6fT|5xVXby*=Gk za*(e#e@$6?%o({1^VYc>l{IZ$LO`G1p1(|kbHYj;dz}%@?J+s^%YCx1ySpa@`S;85XvXah}wPnpkGmQCzR!XEh?FeXB$`L~?YFp-V#9Oa5 zsohaClel|ze{r|kftX(9wMXq@d(kqMqp$3&R>SI=(FB*yytQu6eluR|omMWpd-QIP z9`;W|?3-6T>}!MC=%MY)8{*o_A4$t(I+NBc`j2ZWQ42B;Gg5rT%*4$hB_aK@m18!X{M@)Lg2f(;b?aLf?2hGH>4{PB^Ugs0~9??h1 zdYz+RS=_iaFn8^yd)~50&1EyU`Qutpt^4_yOE=jMz1r@!!sRWa1U~O^YkfvBe!KH~ z;hI0qztT>K@yB=s=s4rpy>JJiyWtKsYK7g!ou$n~LxuPcF?$(;>zN1I;TQs?frt?k zr@Z@R0~FuDuPCR1#hiE;Lg#^Uf0!E3&;t!$OB?XmO{Y&k6EFbfxS0{bgOmNhVMt#G zR^}jQKuzDCVEF(}o1*r|KHF5Ol588#QF?#DS z>W%RPoPIEoiUaID#Oq&skB&y2LU56#8NuRYh8YGjj+i#(9c1Hd2I@GHp4YrUFgYDhxU2EiF1o%hh)S>VlPYTOH`97-*37 zMN00cZ*|D4=M#_Kh);r-H{uuIZ-bx#x%XkNKco!U{eaIPLoY;m9nA25ft;!5z6BB; zPSpOSF^4OQhCAu|{p7UmMv}!G_GG>df4`OM4bL&L89+SBVjfe09+R)a<&-u3ja&gW zi*xKXK=}>b0jqc@op}S8WBfS4spIih2dyoyR7Zr4!%0%sHQoN3`rT)ZBleSr*krk)&hv*aSd^ARe3ugXRGSkY3pR z+Wra`-$;<*R~b;S%oC+o)*aqrWC_)pD4$8H?Tx0 zs~S#aw=<+@6_cizGXo8Axthv_h00fj9O!GHHFM3* zYL`{%v&hfCw7=-x>n|TQsMZ?lv0Z<|kv>j3Cs@{JF3e`OlEFpm^{mpI?N*&gO_AI{ z=A^sR%V7ju(x{nuh-R&3op?==+|uQslHi+ol!L$B$mdiSiSll)2K&x@ovlU_nOy#= z`UQ2c(1WK91$89X1IMIj5^SE}RS|?%WJagimWG|ni7~qUJG;b5_>|hSES4$F1i;`$ zWQVad$GM`-CWFJB%NW>%S7lskhFWUDOM1>WD*}IZl{}>>BQp%Xf7MLh`@&HYZ)z$g z$)kaEfDHa+0fq@->Hw&M9m4N$~SP}Lw);@P#w zObgTZhC2Y&pfu)_T||}R+DCRh$fu)EWmkt7KCqf9h#Pn(Qcz`6TXC&pTgseUa>1KQ ztQ+&;8^<6$fRP))3|A{6a~+ok&~x1dJ)e_=e@VH(T`3qty^5;bstWG|uU-q6)>JUy zzeDUsL=j>WClSPU~*oXZsFhlEd)+c4Koo+&Atkd^)m-OxBMLVlYp-VoYoDCU|h z`~iGyOv%^Mb;B+JyD`LGG&;X|Aorn35pb+Dd4l*>q;(KHL4@G%RxAp?TcN!?Pw8ob z4hA*yi~_{jAVjE6X$=s#&|Yhw96ULvq9O$_a(t1%pi?vP3yG|JkqregAZ}ukU=c%G za-Ak18L6JkVWE~RaHEb8x2hPoqFNc4QtU}_*&F1dE10ZSwVHr^rnz`*p}H%NlcGi# z>SFAiv{T`v0(a@DqE1~x9ujl`th|62hdGg$NaStD(TP?n)hV|apE&`&_z!%(=%8N^|yoKrs_*I`{A-ava+_8gm|d@&UIC(lvpY^wS%4#Stc3^_mo5h3s6 z9Mfqf{gQ}(cXa{xV?6s`o&}u~+I%)IB1R(U9g3bm&;@)LhW>@IGjOGXOp1gb290BM zrD05(h~@!p_63U0Z-Pgx7{rkQJc%aM7}UVYL!xeZ(}p`awXQSHOwwb&B2|igXfhK? zP6kQFIz;0al;dxqu1&*`NYW@?*`$n>)2ed01+u73i`tBnhPEx;&~n+;@sG?aCg!0s zre}Kq&?n4tuk>OQnBVwuj!q;tk5n*FbtHU?1{p+W5u|zxF$TvSU+o`v3SDi3O&W*YXpj{7lP4kboNKz%t>Y2pfl*^}4%rqO6{B<$4 zA=%%gE99d>>4z#ouh;9wW&ehZ$O4; zy*np$T%m8uxoqcucTm_n%0Ay=YJ0Q2Y59D{aGA~HV$k@Q7hxr-`9_^s;UsQJ4Kvw9 zS=4gn`Z~!AoF*6#nn?vSGN8?>*Xa`6UV_0I0p*FTDdSjNd=wVFX&_#N zcFgA#BeYBlW`}pdd6B<~Kj51F%{_4<0p2Q8cN0P0a%0vrGk{vR@cxr8Fe z7z(8}f==?z=RC(m7;y!~w7-5f$Cz83*RB)n-_M8Ltsd7`2{y*8B05%^=slf@8j}2u$6c|TZv&2z7255}0*FL3xTv_x&3WKtHeE+zel>Vv zrf@j$M9>71F-JNr9u|W#%QqWNA zfl9fBPoVkI@T~B7Pe1Y$oeBiNn_50@~mRyA>46;V>5|V!w%= zvSq))?{Sl8skYH{;&0%icQg77b~#+$GT+@N z@L7)z3UIb}GI1Pk8KQ0M*`r(86NkCDh7Gi*PU&%3pHi~V-KqY9b`Jt_qa1|dKAloyHgD=awQ!};*8tsMH{vL9k$21s^xmV zQT4@juNb-HR^D5{p>!aRR(i3DR(fq4HrMPkaN5uTR7H%h1U6VY!oWGdp^kQPOBiV zMd)okX~osFJBhQtM}NsyJN(o!XaEWob_9yUX>S%y@A`-IYu^=b{#p_GTq9 z**#)^5vP53tUY7gz{MHI<3>07R&&}wX6mRG_4}Zfb@?`>$Bp}GcM9jdkLdHoB>Gb? z;<=@9__t>7{+|@{m}o<9+-R(yjtHwS+YM`s9w+#=szjLv4Tt3A_cX$rY~KnnVN27D zC=EH2xc(e)erxIs8V}(Eybr|#{V;gsVFUkuOWcgBHa?TD4un*~VXH1eHbNRzmP;=Z z4n9+&K_Jg=6aV}Rbna;!I891#c%bneMXnl`fN9gzp~7t)}Q=1prsDrDCVSZ*Rh3eAgr z-7Ii9k&9+cS~Fy&9AwoX;qvV@|2Z+eR*i2vq?KWcJ0dRf+QeyKQ;2HI4y9cjWYq!w~Q%oH?iX%9mkk>NbJ2? z{$NB%9C&WqUb!hkM@cVxO~DCZQldIdTX`!-aa!;G_<*j&0Eb>P9y~|kPM0JfM2=zZ zz$uBM)*V0h-8|7k$gX`#{_SvzmK{(Y635VN2rU#dyIy2#a>vAZaIN`Ponr=m)`z6@ zI7ph7LX!8`Yw*tkpZ3YkfUBEmei!!08EzhG$7~14&x+{}q0h&^I$)m=%O68j5A84> zBjEhef^b?lstl{ZGJ;-OHwoQvZvsS{z|$=`GY-&;sG5=|GFp8)8ImW&6E9(y;GdKJ zT&cfUG5j6rQC^L}e(UkO7RnNIQ6!-0+3>rS%c8j;hy%c;+QMU)#1ULb1#}D(`6El& zfANt8nl>|1Fx z=YF`G{LUhIK+!>@2w7kZe38l(jY6TAxDN=!W0aID2p|X9PT#xfB=1EJ6h9l3Cs>I-dpmq0Vg4ZNd zRa!Z>dI_Tjzn3Ish@YE?)Mgqlf_Z;?;7^y+IIq+cyp;muDL|%c+)PQo^d+m1O6yWJCy$?C2NFZ9@5R&UEKl`6gC)ZkS8MlSv0gTA(h~YnCU@32>ValzLWrFHo~?Vv zlZUe5*O&#$9d_>Y!oM0F6bX%;353oTB=uUTJj2~>Bx!nR9^)8!1c zLi~31w4YhS3D!~>Kt(*vVCv(HalNkwxYdC=f4VHoq_I>pHHN#6S&Vn((Z<+$U{fwg z`Xz=XC)0{^9$A`}`Ryi|s4=WMNIk02%tiduQ0ixi-O*o1(J3s&ZtT5v{@_9_hog|H z-4f$5`Uk)xHjLj6{J;kVZDRg5MD%+5y@MPKaD-c0vlxaou&TN92U*8}V-|MfQhvZL14J;YrnP> zL%9ypzc#isv+B%I{RC#b{@W@sQkc_%Gmo&DeuQfse9qE9F458i33ENL9?VGyYw)z8 zE!T6^#R+?JF^ro{n+!*3{^>x4zjNkmZ42&q`roAOr&*@ca{471|8Cy7t*&669+(+c zC_zeV(A?mLYX_s;UJOwIrjek$m=!%)0!~fB55UH;U|Atfenj(vHhZLm%_!k-Lk@rPb1;mBQ6d4JB*XHnVor zckp%@)J~nk>tAh(9&p4{ICG0QOSU|D_O^=Bwi(<-<6Kkc0n)ntRx)F9vGv7{G}|M) z!S&l`>oNw#R@0^}8Ho9%SPINE}Kx9ZMqa{KePeQL7@vJ(vXvxv8!_E>r{5v zEKEZ#oIG1|#hn#0T_vKpGd|%>pq@w{x2!4=To&eBX0KO0+78}V5?8b3zAtIhfMJ}$Y7k9|^f0n-8CXX#hWR6o# z-gV3Ill4r6KvnRgP_x5}69(qI=L?Qdi9@~1kv;h!f#~HEfyqM*Ym$+(WFz@5`Nipt z^Nqe*?1G8uQ-7s$5hO&%g>R88R0$@ESbZEV;c*U4%!lY7HM@0mBq<`meX!Yx*H|W%l}vr zk^RkHX#apRjZ6Wimcwt}BO1VqEZiUq??|GEG$%MX<05O9=?NYJlsIq{C5~@f$^;8X zkqpgnd;~G|?(TKZcZ*E0~w?ndkB5shbzB zt*FXjv%5Mes+8i)1)WKhC;&E!2*?4tYXIiKFGOJw;+BFlB&X>Yi^$D*m zR1-yj#0>l)E9nd~sZ=dFA8QU`0p|@%=x^8Gi+S;jzo!xplMUk6nvur7OS zeV4C{%`+$1wnbemN0m8mvKgQ#nQQ)3tMl;W5qbQMP%;hX(As6&mV6G7&#)6BniK5Z{VMpm>4J^L4a7PeZ#wWC>TaPV}Rd@`dVRY z=2~USl@jObX7I#-u@KI=)=t~colez@O*ADB9nYjdaiL=j*FRg+_G_BsEthYB?X7yi z9y$5_z~9N>&4E;gkitRwl;X+3d%Z`7r+0!SjgC#7MP-Bw7!ge?ei!7srfh07w#dlK z$36a7h}w{Vy5K>NJZfqRT8$wUkI+s424;bKxQ2Q)`adD+Lb$s4GV{Jc973>-bW~F3 zpYSL!f?YkE7?KSTcjn2UD!>wi3q=hy=&&LhV;yLrawHH`A7J^wgzgq{CZq_vs){l5 z`lKcUd6T;+y)AiNeqoHGGy`aepc-sI2EhIvXvTtmp#eRXQG>@IDl?1*-6DBBvc`L| zy)#=BOOn;)aw^CgH~E4)&?IMTm;zJC!AOs>b1GFF+*^G>2@pZ^Q{w5x`_71$QbhZg zxrS6UY;~rmE@5Holkl7gRGY_e$UK@c>-`S=`}TFNc0^GO^rL;VY{IfPnG8UHc~57* zPIZ|CWw6__F`{}tA4F+OZ*WcY7{J)tm^(=4~0?05N3C7V=j)6s=mdLpw!o4sK_+%#nSKh9i z=^6~sP*$hs@u10y#L(&+%YC@9g;!xXI+Mr;q4BH21-lk^rEp_OgFr~|J zz(XduL#8eXeTv!My%0f$*Q9`N6-67j&BCi6^~xJND3piBr$&1@Z25y6sVi87Z_d^b zNcw=xni3f1fyw1G|<|J>`taXEvM)9Y$`ApPOR;RF!6GvU=iWCFH?2SFjfwFzye-=Z)7! zfdZo>4+-Gq)V2In8TIRZ>&W3F=UO(ua-iHEvh5jZPbqeYZh zNqIw>jBT=ymP*r4LhX5NEgsn-4yvTRB(Fu=O3QjTxrHCUguB$>vIu@)sV)<4Ck6PDdW(ifAV;BP(qujPGK6z}kKGMbE% zuree|dq<7EUTVdns;VMAX)UMzi!veTL}us+tNxENL{#NPYO=c>7JjQR(C&P-!L9&o zDGFaq>JJf?K20~MABkdPkjE1epiL`o6W_+W-jAvh>3KK}H!(%(k{_8fbJA+? zl67+d8grvpgZ-|Gx%c#I%1EkZwfA&cH8%xy6vgxz6^;4SqsoE3#nfE>CT_UB!{RAQ z1uKg~_bA#YTP4bnv}&$uQ+iFBUZUclA`EhM3wY3ADLFb%q?>|P`J+Z;56RmkS(87N!U~b6w)fnJhz63|Wv)j+ zi&zBWm5MMLKNIwv3y|-gQ5Xt|9As3a$-OYPp(YYx&U@O3bYj?hS-hf4Z4Wlf;kb9A z*04vfFZ|Ff)ue@$@$MkYYiq9Wi2A6ZYmb63ii{nohPHJBn0eD-^*sUr0*5!C+l1~< z0+!r%D#IIx1)e5q7*@-@xcO4|p6G$0LF~a`;`jsb8G;hy@k@9^AJ7)_bF~qq?!A@?yC)ym*tm}hhxOc<6q8Funta?lcssvj-94qEtsl{g zL`tp&&G(KgkQ{y0Z*2lCm&y`vST$&)lKNjP*r6D-NoF5Iqulif0u_U?- z+UbOBDTAb^wxUkM@9Py(VzWDu7db!I=`C)R7o7EBib-im?lUS&&IP^1w&EHdjG`Xm zIusuIN;6GKYCFB+bwHv;w(DAr>S9?S2P zi))1K3T%zH+)Z%g?z7qM6Eli!r<60=8T}K-Icj|+G23kQc$KaBydZcLh7O~|cJ-O< ztlO!$wN@DqJChUHNUNyCb}?K~t(jJG7tQlDcGI8bUY2l(+mF>>*V&7gv|9Rsz1VEx zv)&yC$x+%MJaore-T|?S3Og6vK-S3p|#$mf)Enhtb8CFLE)47n{?8 z{_e7CG~KmC)^o@4m>Z|VWzC7gUIE~mrcLKl9dJ~Wbfn&gmN*dg&Qjb#0>5E277_fRola_y5Lq#)U%D1;(omG(Ci-4=kM$Hgz1+@ z=8LQvFS`VM1ql;AZ#m?*z2$jdvFFE!+4vXb#Z|X$@r_flsRd}8{9c-6nRt>-+ubC# zR@~(hr*Su@z}x2NrOR=@w@aGB-egN{U3a9Y4`#b26V?6{;OA9GoEs@G<^3Cq(&H;y zc{UFIu=6OMzA%iflv5(5g-E8sNNg*pGgNHux%-LcT>nz#wc3rX-U|;TsP1&zW7J#f7xJ6?^^A9br^U?Jx9>qcGY6ywiN9Usxb37 zPY#h*5x*=f{+-s09Ox=*v8qTed=VU5sc13%PGksVWStH&qA&@<(of)Qk4uOy)Lfo! zysMJjr_x{<-L&U2A+bRtpI=RLbqyAwFa)tzJUp+O%}}~KgwxW2+)N+1o!+G$v>-raiYiL8f^^C*}6|3`PeQ)OF&8dq=xpPpLC)Gl5mr zU{kZV4UsIlYK3=(8@|y!0%-b>T7A0vFDW}kb>iT18KbP^_G%M@1uShT*$&rjo?>8~ zs;Hy;_Vf}H@fnAqO3C6!3T6$1-vt`QZ3Gv?=`y!GKJqk?;#UocpcZcnTZ3>E;~S(G5Ui`9nA4TKC+h>r^j zp|UO~KL@;pPB}RV+rq#ULoKq|X0P$^R3MB-1Ya6E>9*DV4z{4G@GU_?sMGo(=prbaar3 z-Yk$%L-Kyew7uo1^9wCRfMD+r)j6c|7j{L12Wx$O{aW;Nv&%0~)n_^X{a)yr0FK<^ zyHrs{d|b-d1PYXYD>*9pqolL*@V}HqAK(4jl|$rF$MO4RPy>EX=!R%5b`C(V%k5sfU| z+l+;;jB0EF>2&=MUX~BfDd}IiUH?NV|L;}ae&D_=I#MG2IFVFVY?}(bye2`&(OkH3ne%h&Hf>6j;)zE^7#+H`W zt`5=#8A;!&#iey;TuG;b{~=`qIr#dl&-ltL?r}JQ@_$GP`rk@< z_%A6zX`FwgWd29WrDS7FiT^F7UEFc%{|_md>Hjxz-044)lFc_~Z}x_YDlI4E$sX%g zEsA;-=3B@&hV11R4@50$j(?)_wXw6a^83I3?;W^v9&=l+mfuOTqz{Tbh@lh*2E=jl zgL`{NZ+BU;y!5H1Q(#k5S1rCEy_5#*Tx-0heInxma5<4MdiyefOYj@2N%Z&;2(Ls! z6!oQON`a$A!yBB_xJe03Nnso-TBUyg~?r#nKKZHMXCY=^6Q8y;_@9?8SUJTMs642(fr@(5T`_p;^S_}mb+ zP9Ef|Dr<%})Th99fm<4ZUS?8^=(Kwztgf;p1XtO;AQc0&hQ5+sPD~6`+CoDM582$3 zO6dXG88rO5jEdyjKn$ZLwi%p+Te8U6R=dvR{cxtCJk8$tGnk*Ihg(rEp}Ne?%haHR zLpZU_-IqC8Fn zT#C`6=++8~<@DAr0IZ0duF+xHu{)HsuH0Jg8m5{$2BQI~)mQk)=sg2Nd8%F{)*)1~m{@i07a)P2lXIgGyP`YI z4rIt==4zCDZ~1-e4FN(r^Fc5Qyr(vqeTA0ngIy&v>T(oSNKPi_F~4+3eFI-t*?oM^ zG>1|J^cJpZlGX#se9s^k%nEBQ4vg~z*;U|RP!D91)Xz>~DI*yUBjumU$*~$~SA^+F zk9QI3@d?9j&1UU8@ycO%5n>=8;FdiQyy3$Q81vvwXNHX|0|{bu%q@KTwn)Fof6 zyQION0WVT!4#K>(&6`(^sgo{XC95kMqZ!?vc_~6>N7-p+?jq!* zVQcK~3N>85Hur>`M&#XGH=E^?1@J9XR`ZnGf6q%TXIwKXko@f}wjYdQo4-$#jRBL9 z0Nbto0mSRHj~to3dkjpmOTmbd@5>>YTdvBRl6m0|k!TF-U3yFTkw$966gMl{9iY{P z_dHJ~X=L=8D{!wGNP)zvAyC`EhiykMA@W;)6d@aR$~`TJ*7wMCLpAN{lrD~vSU7Ym z11wm-GS^UXs8y_Z6T`AcpypE<_hcD%*xfnWaET!S|jBI3;EE7+Xvq5 zR;YaqG1eJHLxd=HhZX4@0rL1YsmdfxW*Dp*Y|paUykt0xKfHKLmmm`gGdwR(DOA;~ z?JpbUXcmFHBihg|YYQku_hAWG_x{VXN#u7A?mgZ?bl{Zv>t5p;d}|Zca@15~(ISeN zQnPxJMw9i|%NWTW?rOPlx#5rx+Sy;?CsJ>%B}3q^iRvccpJ^kqEx&o*Vvqwh?y#nc z=hH`IJGgp7>O7b52g{9wzltQreDq)z0x&Xqk^ zs6<`L*pZc*<|7k{iEZRJTorl`Rv>$Pec(^+NxGl zTHj=FErGw1!kF^$%z6;N&A2W$YXxRcq(F{Cta%WKE)qU#2n^nkZ)ddS2;S&d8P%M< z^XZ`4gII94ALa{}--g#u^A7LQ)3HD-b`?0|H8G*wyVkLbh)*09SvSjO zj{&`dFQ}}Mxd~oN<;5~DtRB^NR!ExFd83i9h1Gd#Y0I^y6kmXPg?U0q+Q(j&;#ox6 z;I%R{_%4_AeFB}jvq`IpH76k+$G7#HUy2FR8=-1Q-hW~254l`UOK;&X2p*l2FGu%w z!>D-D2al;?IiB8I-~WIFuV7W#jpY=nf+Rd@GB`+6%>GdIOT4xI<^!KnHrrw37zzyV z85lekm+gq-Xw(kTno^!oeE2CbbH(0Rbxq~zE~(OFD66XuHZG?)^mel&@Op{UmK5;N`obuWThfQu|J^nNb~4$HH~!Wc!9JK`NLncj zbU~1-GBG8Ls(q)^Et1Rm7_6Z86WS^}>djS6tVUwD# z0fjgrdqha#g0)&uTXf`gwl zR@>^^s|)wQTNzj*YJA>YDQFUtaR`x;+!SJ>FH*6bTWS)MitM~DdNx}lsr`1dK@J>5 z@xJCXIZC%V;=P~bc^-;2_*JFA-a6tZ<*y~ef(60&8GCg{;2W6Gdto>EQcRuJ|`$@OTjSPFwWhGg$WFOxTEgKeiYN=BZ42=UC1 zy_}<|M{%uY5yNTTaNkwy%Cs9Tk_Qnku1-ryVGhI}#H;NMkBIDD&;La?nbt%Tcc2en zHE-J)g=w45KWk(}b`ThOX+7no$4kxpjlfLhn|ujuSAC6u$Z@dVcaL?rhGObj>xe>q#2=(s5KY7SrPV@aAt6%gl&^aHbdl zA}HU_)Dyz~Gt{(Nj|5N+=JW(aKx5tf!9xH49 zioY_bSqq>a5-lddsX5By#(8WF2Rf{kfsM@SX3jX*CpgMwPfHoaBEr!TEutJ9=uniz zBD%#@21HXe-OZJCt9bwO<<}svfs@{Bsg~sq&E~;CFxkp}=`)L)^%Kj2)x*-_!ji{k z`6gzVfiN4*1n%su+=c{ZAOW_%p-a$$$g+=Q?#juz9+g9(Yr@E*lLe;6z`^tRON%Rg zIy!-M$SiN}e!S~n(*vW;-Imvb7NdOy4jyVu4Avi*+m{;lzlfJ8oY|+4B5K5+U^7&( zx1ngIR!#(H=E*DTpy`Ow45`EK9uZ-CSAta98^#g2?zJLn8PuRjpQ+wULa&_Bf zei{2Y$6Mme-!erN3!#0L1hfk{Ym_^XpG$CbSy~4Z&RW-9(-}UNb94onAP=GI`4nub z!ds|YxC;~R7dc*dY7IN&1)9S}*_^x-*+%eA>y=Wjz7<5->~nH4&l-@E%5NAOPW3}_ zXeVHDtodULQ_=XzoVt!8Y1(iOj|~Pn%+*W|!rll#^UmEGd=T}IyGwAPSP1(2dV|-@1{|OYFlZP-A*hddzI*Pv*3%}?m5@~F#uyI8 zT-2G$#nD=r5-p)g5)PdSx}?Kz;@Oci%M4sYGQa2Xr52-J-cI3#`2k~tya_7DJtQWvi0Ay>wCRO#TUOK5To;$326}q(vpvVgsI4lmGqGS)^dUK zb50?ecw62*7Ql{m=8#fb6AJllfVp#YI7NdKUI6H913NF}GK&7dtJar3K>CuuD)Sc{rr}*j+Kn3d9B?am@ ze5L<9<>4?8*z5kf!IRsmH-8(g=(EDyC#7*VF|*(5{Vj_}SN_GNJX^Y#O4~Kd;reUs z-0^7leo01W9P%>W0$=>+vnBSCKKxgYax>VC$VX`BUiq7ed@Ospe;*Ugq!YC$zXP?T zen$CBmS9&o9cQSRQI$YST3Af<#L@r@q8vih!wfCA6Qn@FUa@VUC^1{0VJ!Xy@Rag7+tUA3s5gqkm{ zSDH`7{D&A?L2`Bc_7c9JrS0e#Tnc*J39{LTyTVDgV0yFq8kH-`lfTi@s7qpD%{ouO z^Uv~of{7Fu7ppJWs%FSzqL$Lf8Q~e*@FySHovEf_BT|9QE4Mpd7%BdG#|BlG9@-00 zK^^!`PArNdA;um(DZV*qgK{Ro97Wsd;a2>?{!zMxycFJ}#o<@EU4*G?*5fLnx(R{rQBNcvYmgCMP%|Yc>wk)6x34dQY~!gya{r;=8p-S#+N!n6|O+;bH{^4Noes-4 z8>=cecS84}Y|ReIgIbPgCKL^7Ld~>J$mU1ldd?8MoxP`Z^twfCpq79~oV2~SzmDoJ zb;ThWDTU}jxiwdV0z>r4^;i6Wd^{dv^+D%1w5XP^jdd@EI;m2g5whN2vJKtYqk`=a zqIZnA#uD1Ib#Y`_uw?hux{-J3mHdVmBdG?G_Q4xLf)z32DE#;up@Ws61SVoc7UQXY zGNDsAMgdNRxbn62ONo9rptBc1?l7OF1QIv_{jlf+n$P+$jo~hoBvh+K;Vu+D#3p0? z=ZqZ?M%r)FPRuB8JR$Y z3my?u=i251#M!_9sp!i56njE{DmwK40j=_6x>@?!!3NN131 zznu3Bs(`Vm2a}q>K*sa+Md!P%)|f)w{){8paU9$7JSjWotz+@5kVFAdKyVaGdrBW? zOqCi;l{&ya*;`Y*Pkk3BG?62wy|X=UI83)bdmd+e_Y6N@1KI|q?FT_SL&IRZ*-}V? z3wuzs`Q85UsLP{-zo;;!do%a&&-4`y&fUpC4GV~aM7l6KoP4##*YVd7`Ry1e*6%`7 zrlF)UFS{;yW!x>(yChGo5j9UQ{32En`>KjPc+|0V9slZzjacX4@ac*jzawW$%mMf% zniFh}#Oe&Z1WM7TSk{*u5ln!sWG&gN2u;jUq}SGW+n;!g9x6zNAvbbO7sos+>QN$~ zC%h`kci3u}{TGorqhQ}KBahBFCYJpuHrmBYezwWL^3xe1mZFr$+DI%I;7BR$W&$Pt~O3D zG#L3*123tJ)fftqT_npi;-GDTsJw5mue|acAICIO!CkPth>zFuFSP$Xp}~~$ z13pgVP}XC%!(nVb;+REHCzjW6)Ff-pL}f(~mVeSI=#O@S7 zNh~IfadQwDyT%X_bD4(Ru8IWIu956Uos0f;ULCEZ(+hAi%qJA0-wuR6II}umm`N7c zC=+rbxN_iN*@@Hi8_{jMBEe1$b-&W3=-Q$~rusumgDUdLwM`Y=J!34lD~_$xqXfa> z+d;L60RxO4Hh6QFWDalF7)3kU=6^nZSYqMmxeApr{>f~u8GO#Xk+V3*ntQ zj&T=Om6a0(l6Cx_2e=EGkAzg}Ra8a_2@m;DL$h-Fu(QIx@06(FTSjw?kiiHrTDvJy z@%mN7a>0S$@V5nhirU}w=%}O6T>1NIe10#!g9I)&4%pM_wx%^_VLB(Sa#ano0DX2Kw`9~FUZ=)U~0Hv!D|3}?nRu{@MvG^!{sl~2FmHZ)S-$inl58)JGLO&%eNrj z67m$rmy0dNe1|Ts3jNnk9mJ;SvDdVsL491MPWkZBVHh^&t|HP5lXQM|gyehQCHvg; zQ>!RvbO;egG#_fiKgeleHFbC^Midf|KV+oUb0(<~D1 z_zXg2={RwhUmiy_lT_t=-MpgBC%xVA-j6v6F%^0EC#NLL0_uZ`0vkM&d*d&lrWQIM|{Q{ z^y@H;?s20P>_-^X{n|-s^$#8j7Dfx8sVMb9`Usk5V>xL)5JB88^UmIwpl9E9`D-95QO`mHFP` z6YGh7j~xXk@^*}L!tXSj=^ld3*zxD#b>Dzx>gh`x#qo4rDVjzzQp0B&!Zq%q7{+&r z^{)o&8}?Zz@mHpI{gzPg1_fqxG1R<0!Mp2_4U3A5*%b>Usie$mTgEb=AEf{q`QXES z(|2nqqR@_MZf@9VZt`fs+R=E?_|?SJkv5GTowT(6LtYBnoOl6^;>8Px4g4WU%qi2C za+qVjAWVxanV!aXMmYoS5jCzC!#&Gb=0L1iC-#}`o9#%_O1DDBXfn9eS~90a+t&s2 z<1)@bRzdrEjm{VueH}0xLCTC2fl_mX8A}9QnLu+a^u(Ke-y#%K)Y{qm7pUIjC-cF- zUW;quzJGP7$e)cGaZ`R%qfm(?M}NK&h5pr5m|QvsRKwEZq2ngkD$?i#U-i77J_CTK zENF{kdfkYtY#Z;0SdSg7cShd?hkA}LaiPyq%I;}mEYP_CebE8J*4S^MyKd7VZ+|G&CC!c`wd zukkQ=wBx(sFgZ-0eLaJd+j6CMSwF=7SR?$_F8z*UwnK;XMsV$94?%;QM~=%J9*0@< zAq89}0!OfI=fY64?*-A(JyVgaxo=*NPxoOkCr37igZbyD16FXJ4LqE!m;uRD&il4! zc!<}*`nCt!>yJ;}T2z7^6YrT_ISU-7X!{?jL0Kq&GN${h9B-+RD)YjcC~TKv^QGhy zQJwV!uVD1F#GXkQx6nf>cvz_VDyakf=fBUOj$2FAHs_B865Yc$c34?xPiWs>i^u)# zm94LVg~vt??u({YZsT|#r3<{x#@pVtqc(~>H86a9m3>xbJZbWEgFS&gZLzvuaeS@_ zb{U^u6C%n2sO5%d2JA+Ion^+EhMw&pq{1KJYeDJKOip#_^ZSlf!>H1%YK&ys(RjXE zx&gF@Z7E3?hgL}J2Vh%+5c6_k+mTxC=hf~=o9@q7?%8^V;Oo7EU%b9>K7Dqy=q<>D zZi<0d!YkQB(>j)Hzlx9d5m|F{QKH?ItA~s#aAPYY|Mu5m%9UB!^V^sl`GMyscHTB^ z#F{NJyQ_8woh)g&>-zjgx0dZPcbYfbb{|&_O|{|Ux{&O$v>LT)vF);rtiwuGZ$#w! zyP*QPSPVieD&Z zkxs@3t$~AnLe(!y)RtrLV$P{K%gK9v@v%F@*|4nHxJD!O89!>Z8MQ{~n)UC0o6{E- z`0N$_$XtJ;{!;_@zrDGO2nmb-r+=#xBV#+jfDrtLzYp>V9}W<^>kLwn{|ZV)oMvnS z12|@(2#W4}y<-;ur{cUVId33=^?`5JD`)a$6|;}{4G48W9^H;EFEBHA^m?|3D3e$rjUe2TBx!>wg376{S6o>^NDVt%Ksc)r-ch(mIp z1dp82jKTLwp_huMe9AVN8RU+=@%Y2!PQjA774u;1hV|~(5@Zn72c-Kn)_GO1nzj%b zEYDUvnWkG&^o-v?>!c58H~zm6TZbex7?VHX82o?48BzWG!^qBt-qOg?z|@)E(#go2 zUewOf&A`#v2(M9U{4cv5A5a z2ARuS=;|6O%2E*nt2tPPJBb?V>RQ4P3zdbyci_r%Dpywd^og1rUw9p(CZ&L+q7;)I z6M=k6Ng)(u7(~HX^Go4GE?{B~u@v~sZG)-yqh{%8CS{$cKsqLpu*IJFKLYynkM+R} zRrT2$0KFw;`v(FZ8p(puga2@jz#(EN>J%4$0>SlDRZKn9MhLTz6f){|Wk(kE=(Aip4K|%d7h#2R_U1atthE%NO{jh<5?Eiw> z805>{IWBr$irj84-Vc!bP-Q_qgP5;$O^UUikc^L9DD57+k2Cby1PF+vsh(<#t1|@o z=%@>U30JBW`Vr_7-m5c0SJ;N1{1W&OLmr~pF7$N{K%XH`I?LVK>Arb_;-8%Gml|4n zSf~ed6ZnvcHq~eFNg^#$iX$m=71M6xrXdVXJ~uobtge8ZURHi)-%9krrgZYUE3J>u zxpo%yJ+V=0DugT=&$7*4v&Cv%Q*(iC))V2 zyZJCi+XlOPQ`0|_Gw-7p*uR-^mK6+s14rhQ-?yiR1^lt1ryQQb)(Ij8XA|Pyi`|m) zK=W!{6o#7CFPBDC-tJG!cX%Q>6s+W-#q$2iqe>}W--9C)3W%B=pK}85_p~j8P98of(mh5jujV(oH|5No*pHD@GUO7V zbLTn^X8L5eI7_F(eCzk~E4GMc&_ff{r8e4OI4ob6z*JTUHbtuaSf{GW<|40WgeS?RlUsyktCAHd`-*3hL2v6>rL+N ziP~G|iwxP|p^qwGn%6Ani*>Kpj7Mtg*ZYJ90PJflSZILM!1&&V&t4K^TKRS=oR}4N z!kKib#~L(f1swVo)Yf#pFioRKfALq1&j?^4n=MI*rBJ#u4dW8ZrCs?sYANr&b9}(> z&;0hO3SIaJRDOzCv{#rNqXpg-DP``Ya>r2AP|q*MV4`@a!mMN)3q;px#QbZG{u5YH?_j1rqsPf@u($_#gvm3B|<5T`70twfZu zw&5}%G1s_on_t6#)CMrv7L`wL?CuKSp0Kc-SquXMM1mErXNLB>TKxwx8|ktMp&~!K zrrPt}>*8lzU!0#W+ww;vWy}}ms*IRhv_TqNGV(H7W3cX=1vFPsSyZ0F%WCH9QE4Bu zC0Z~noP+`ch~D79-Yed;c+8dR^s#Ny%MmlCoH5SI&^PU?L*Q@)tXs!L2xN(cOiNhP zF`^iwSY7irbezyTSRYT<{4Y%JF-e)4b;j!uPe?1d-7eRXspEMR68j8GV-P6lW=J{{ zz^9d|AJScN{5D3~(YxCO2E|-11@IGdc;~R#7lP!mrAs{B3!zlMbDfKT=#NFQ?YUY) zxPmG(UA6+cp}Iu5Shx^cw5#rC>zP(-=J4haMT1lX<2I!&OQ#_EO^>2Nm?cu=x_iHY zWs0ZzIjr*7a$;i~S5A90^jvH9&X3%FEoT@1+ zsPc)!5kZTktwx;H9L>d}f=RzBY6KZ*F>NA3>e0~-RE?dZ_5q}rQf%cgfE^OY%D?ng zazli0I)mNTnXn?orjpRX70&x@XoN$Ip88x0z}aZg3%H$sIt6QnBV%FddBYj-Du)^e zAYQ-tY7X#l3}EMcThnE+g+LtR|Fm$x?;~^ZQOY(d(AJ1w{X8i}&)Sa+C0;gK`rQJX zJ=d61dB_70kUQgEuigRhRqB5YLplciJ<+FyYAx?AuAOD$0nJ^!^WYgWHaycO!oiP* zNU|xl$UR*abLNQ{h0xoQhA}C)_d-Ak7R)V1krlHdI%^tx)4z0YeZbKv%cNEU<(-Oc*65e{3O22i0>E~ zc~bMZ1)5wmWMQ!%noX=WC1L6o^yR$rQ#Qx&)) z-LtT>fwnO*4{)8CixQtZhneOFxiXBnvSES|xR2knv@=2om|MeRn+tOT(<)=dBy@%D zFobM0b9V2OzCvmy9cfH!=oY0SJEc*Y7BBB`vc z7adlxYL)VRh#W$1nR)x#Owo+H3Bd3nKiqOvs#o&v0(P3z@@~51gZ^0fgH(e0MV-y8 zFpi$nX+45zQo%5_(eOg5%k+`9F>X=`*)PJtG)aTvKfs?+d1Yg5(GVh4`NUDrH?h6$ zhE|%t%zvr0N~-`_Jf5}L_K0^yq6>jg)YgbBA!piqcI+@h$mO9Z~7y($0O!K?eTnVJYS|* zuk2ei&zn|JZ?>2pc!j%jgegL-WcxiWrCQJ3VTbDdiPC8BjpB({QA;BI#sG4eYfW~* z1E|H-I|95JxLX%v{1@w zD-=p|P&zF0{Eg0tb#TYpC`Z~T^gfKMz`vb#yc5|A-cjw7@&oH4^&9v4#QBk4lnT2QelP}oKCi30*s=23-Fog#{j z9Qu^D^hwLm>BX%z@+%a^c$5#>{SCZ5s7h@gPkoAxKu1wtGI?3`U?3T?;m6YrS(@P@ z*mrj1NSnKZ&1J&is&|ClF~iM(*&kQ?#4XrDr~MFr`o$b@uScISMrC>A#w*u`9WRGB zy-U7;K3{Qdhq&7$cIMEa7q?)uQ$=dVvfHRbf6f8N9}g^QmFpp$cKeujREmzi-&%8r!N|%g>BQ;bb1if3x`}z@9TGA;eX?vZ>9zt((b@7YnYzOYc`0%~36N zBa5LP4F$X5B6GS$n&b|x{~E;MhTO*;J@T&TrZgEig!)j1BhDC^HP*>W{5y?&=8d(Y&|I1TI+&!RXWER ze&J==mOWyt_f2BEQIt|SvpUBO87MVQGQ~dk#|OxTcR3NmwKu9MaJEq;fg>=`tHgfo zrCwr7mpQz%U3%Yqda^BbQE8~0tJL9-1ee<_w)`x3Emfe-AXwd8ceI-mx7IG)#LZqf zH>dISzMt65u{l=)_1O=sUJr?kT#jy__SR~{LVxfBtT&mRJB#|&pk?r;xcBoF_-pJ* z?#G^J`j^r}mJ2NU=?rD0cjgG&eup3KY`2lttiNE_0hL(4=YRPs%u0@znTXv0Ki zgUbn=vfN&OIM5ZiQ!oh!^M-8~wbnKv-ro9!u0#!4#%#OBqcQx==^m_Q^Q((WO8IPF zVTrNL5lK&7zs|91RAJYYN{OoI$gZR8Qd#oy4AUw}P8z|g&bY^A<`Hh7R5pcEr5Af{ z8^cu=?I-QWJ}^9UgxKj{g{eU!^{~-(uu=EWQBM1uK2IKr)7<@a#+Y7*n8s4hnVh5F z-m<1E0@KMfZ@mp7TaM0Chi&Ys2h$DyI6Up(eu>G9v4wXxhvko}(SG)3(abgIV-qpV zKh}jku_h5O2`^%)H)&VCRcc3ThH^}1H{PCPbuEKN1W%LC zF{W*9Y7-pcSv_Me)4*SR+=BQ#VJ&KLA6%5-88PiauBy6L#6ilQ^>TD7KN8zLW;sBcag1B5Y9tuKxx1fT#8?B4{U8D~SPU{A7| zLOAvKhMoPKFXwXx&5U3=0poKa^eg|*f<@;`d;y2(k6>DQeT&aCpH;OFC;8iFt=fUq6oaQzw)rg zWVI^RNJ6HTjjF1nrv!iVWvI%iD>ZAW1yq>G&QfVXuG=FQt=r^ejsPmuSofM6d@uFb5J*rl zWt?HgiI&C=_UH+tL@h;ITH172K`Pe}lp^xnK8GxMhH-Inp*Sc${zG4XA-PJ9z(ydQ z6dl&pax+h)6MJ0&-Cycfe62iI_>lNgl@gLr#sLc*6MvByyBW-&C2!!VZc-r zZB@odYM@R*B=oTO@(IAjcKcQ3Q|SttOxwM5E2a@K7VX?1~;Sh);F?_rM?t0_QTIv6RXQ>m`|) zZX6``N@r1`gYKd&)^rb;;j7YK>pJ<@%iThvbmxWAzhBQ;7g@`{yC3M{r!if6>Bc=u zm&?-BXuk4Ki;bql$s04TX$WNTxk7e-br2QdCbJEsCN_Qc$VhC;;ddMn+*0~<%3cIq z+Fqdsq4_`t<9B~xxYN1$h|Z!IKJtjq4vG^*@ zp34Df0!Kx{jc3ePT+CLKL%vVBl!Ic;N=h%T3u#mofnxKCl)T3HdpyRKKXvw-6L-KnGR+S8;p5wI#bMYirwBFX zhO7q|JMAy$Zsg=sa7*CE)q}NI#k)AO?+P zzws*_92zMUkxrk|))ddYo_a>tx)qO5t-iRJ5xgB7Tqu>Y(OAN&0Gf!wlcZ6*Z@0AT))ZjArU>{-It#Maru`G3-+i;|8UvH%M2VlC}w zojM?8#6G!}{M$bENDvi?C2)`>@=?EZsS)?IuZi2rn%_~T0`j>6}23kYSI#vR^5J%*x2+u^tJ+g=yqV zT04)=Df!MNSsd!7>c4KTMbx5Z7=&feVi$W#hom?yybN*)PZA_Dpc!@N;wg`ELVy>l zT$Bmmm3rw9)VgjIN_HSYUp#qKk9nkyAH_*wtg^phJyRKgYdD2Q>de~NS(LxcnK^(d z_a%hC8f#qMrA6yevP>uDI3&VnQhAdpkanQW&!3IrUMKXdAKb#~g}+|9_6T3f7fD+^ z@~I3;em6)y18@2xPC?7vuRSjim)NF_2;xy3w7-pR#_Sbpr3kj%(R+^}VwaI@j0o5v6PMg9gUn}** zn+gfX3z28R{7Q8u|EZrHE~(>Hcqiwv`Dtb15Fj)q8!P95~i6A3MkJpJDJ;;TY(hVaSb*$1PG=ODc{X?-<3j z#jURLY}UoK=8lAvwoFUtDZz~CW^$^npQOz-pwL^JihDxllHErU(hOo{l*W6eWB#+? zfMtfE2+wVa?f9La)5nQxXA~k}ReZfw*$7zh$_ z=Do)tZAf?476p$X8q|77@z7O{RWjvQc0jzYR883>yLo`cM+hHC7Nm~zHQ4JlO0W-h zFkOhm4jAgz>qkSqG&$^=NHVGxJheECUP__wC zP(?7#AG0?QuZ?JaCKl=DJ@3i`+lnzW((lO$^OTk{cJ`HvF=^`SnC;4-1^Hs`gd!Xd|Za%`7q#9ksj4N|`?uybOltzl4^1QZ#iR#8>{gmu}M zz=%hn#{G9=?+Zu>YFUA}9Eb$(0!)v5a`*krVK=sCue4majMM^f*8|5udlAPI0r{cv zy)4|Ff)aWG$OW);HKkHQ1%~2wiS3xLF{;WLKrqFsn~%=qb6W#pYSgvDxAE#q`C>h2 zNE*QZ zp;>1^U%~{v_c2i~V^-@S<%CGpdo5{FNbhQ2_Pc0Hy1~{qxy-o#DE4V2EVaRd007kd zz$^c6#XgFEI9~qWm7j~kq--ER3NJC5^+lm&bB}7xMs%CKnvq~M7Ls71p~k6Ykx{Tb z0|U!hZTr7VKU`~~@Qx0r>ntby6JPJ1Zs4}QaDUX0MS|>fg}6I23sH|-!yj_rm^_{6 zKI^nlx+yepB}{eLY&+(Iu_atC5u$j=@mjO@q-&MG(_o)9zv$+o5UWM)UWU{3v|^_Uem_DpMPf&IUc4~KAE?j-!O!?5YpLD&s zMmSD}6I4ScXeLn(kTHgF{K6Vb{e*(r86~(_rj4Zvqg}^xBr4;9 z^gXW#l|(5L$tJoF)QTPxdg2w*_uHFS{J$w_E7BKVvL3RJxL>9|o@Zxk0keiy4L}f< z5Ec|dJ^j-(rpVQ#N83)w)FzG{9Sz5++FG>QZIdHRHfgz%IY%jyX~gorvUKXU4gAfW z?>}wJ|EiNkfw5RZOzI>0Z&Qx|6Q?sntshS9N0@W~^_$Za=AUKTPB%M^!?22w!{A0o zPr0_npfy1)rH8azLpI6UvdTy_vf+Bo)6F$mY7}$3?#0;A9T&Ui#(bWlK&;Um?uHiO z3$S~#Jf5Ep0{Z*EbV8VGOlGs)M{S@*%h)Psy5e@msl)+u@eK(0i)NJQ4C+uWk^VAR%&R*bB>v`*s&)_UFQfO`L<3=Ak8gWw3Mold2wZ+61 zx71f8^W~o60EECLUyVW?HpMW%CYh$3a0?1Pi;}aMUEd`w*sJR6RilYlIWfIFEckV{ zsttqU<{AWn)I0uJY?;W^Y)+qt2w|u=aEgKyzPwlOccvm;)l{6$SiKGAcdK?Dxx$&m z9u10_Y$HN2?W0ybsvvB?F>I=i>0v@0K`CLKI&F)v0>WjzOq=g6NR-vX8fPMS$Bd@c zUW!9IT|al=w4saTWvWiFLWgdUVRtrW7|jx|pH+{}F)8{hgZrSqtKUA1ILb)1z}8Z? zt+}zY;Go4ccNl+NIQj0Y=4iywz44NA#{q8f)8G^5!rAS&$;zs{;>kkdxEGKT2!V`7 zOU20dSfEp1wE8PDna+ylbZ&|+L!8Qpqt){sO6azJoJ7J0u>D6_x}^U(x$6!Z9kL;f znhwf&h0Z^6;FvkzR>Omq+$}Ma9K4i z7A7Lm-ILeH9=a{@6|E>1sS8j+KVT1pXFFeA5v)6Q!FiIDhO(Zk zmuh}TYR~Sotyzp#)T$_UtX$0aEvOmlo^ltS1Cw*}TqnmPkebx7>TnJlQi43X5})x- zMv(LM-ie;lOI;E$$Sam?h+0buCb_Q920KAM-q_3SBN)T zV|kofS+!$MD~R=U-wvirWGIpAGxGTU*Gui6$D1Q~2Hz6(=bRe`aisRVp27T~T8wYB z?ua#Z4874}7wHOzbgzix^3sTh;~_57T;z&CA;z$apaj@6Qh`1oIlH?LI@VSXv+I2j zC5}lJb}}NB?64%uPyo8xWzR+L#bBR4kLu9(Y1ndglgNl^! z66b4=_doo^=HEhbi0C^3_X8EvJert%$(c{h9y!RF#$S|32rJED@4Qpxl(0==OH`4b z0pOR{vY#L5D+PYOB{M{9pWfwwx?(%_KL{pteycV8pYrhPr=|LTXVw3vQ6;HlWKQzG z8dZw_5e1qC7GkIcAmkAdh?mz#fPg|kQHYCzK@p%lrJLDX`%witxm96N7Dw?0zz<$? zqKP9I-oCz?xtzJ$K3RPS|BZa9EYCmBKQ4@^6g14w15J$*Z?^pcbXF2n4*lzXQA)6W z{t_#VY-!8g9MqO5N0D0oy07D`EwGyyI2n?Y{Fx^mL9)7y9uhhRf4pbQO>RO*_6VVr*If|4&F7(A9WBTn@9`wkBlDZG)iXJcR3r^(qs(mO6#&S9L-(~JNQ>iUzjLB(0# z6D@h1!>PZf4x%)$&74Y}E7WJOYV=ua9g?NqRzGN{>$zpWlJdHOo-NfE@gbg~+GAi_ zNUiUCrYi>^h!1wL|CN7R!i;r2esZtlKek*c|4aV;_Y_LlIyoEI8ktDjnVJ1>=58Amo)E#6oc^zvQ->#-@{!MNEkezNxUb#Xur;8uU+U$~!lUKqkPSRxHSP(C#jNtAW$h{T68 zHol^pfKC)&ksC8gWmNVjHlb|Ipv<{L2p&44-vpv$KN-R(K5DSEusk7H>JS#64-FDo z>sIpnF$(jlB@zt_4k+Y^2^D5}`?1~7{Haiwmy-vh{4yP5SXtw|RB=csUc}QTa@i2+ z2!{O&Tg}iSvmdu|Kel&S_Jt-MCNfZP>~nO#IQ!t(X;<@vM%zuj!>VbEvGe2Us$sAm z7iNcmcdEz}Aw9ptTPl}5us4;2YBO3Shni{YV>KgCCd8GKx@I1fc1|eo>@9_&Qc;xN zpX$UMRnZv5svF*ZM}DAQ*smM*3-pBY#SB(`1oX5vIuh+;EFf@)+kMo2r@*6Vk+?zy zM(&4ypvLim0sD0YqNo2?Rhr&PzAZ>as!NEeEoHv*FW!!Jitps^FZqLCuqs|FPimUm z?#BKpou=*Am^aL!mraASfx4HSr}d}5mumulXQ#Tkz1&`G$G$&%<(%A1XE>eS zvKqNxenhkfV*&frpXI>h^=<9l`ylCnc)jzF6{x)p?1Y?`BEo7dma?$)ko~tjyZbk> z!e(k#0~P$5Z2WhSB3=vg?XmsylgByAfy2{zH8*j}-# zwO}OH3uqus9m$LZTCh932*5dzH1>3ka8Yl;u*Ie;wesH!K(v)U1pJ(-0ND%=4cQ+_ z?8~z2gv`K+73}6p)k3hapX|vVfA0jC;{$z)7Tppuj!5IRtBcRA0)OWH@|XUVz%U01 z(>N-zWzv8RHj-u={RUi!Mm$NlGN0;uQU{e2ctirD^pVK-5ISy z(7Zm4ziz;0|8(^$IYtCr%_2Cs7O;PTGzRcNFdZ4fsl{NVeR?>EXX!d0vZQ_kf3Bc@ zMK_hrP(8AJJ;R$aJPzcdyvWYm+x_pIs1zx~$=maBuvcgJq<$FZySg15&Eir(o%4`% zkTnjn!=F$&WuUWHM%b3Ha4Yi|~ugAh_Yb*M>e#bu%>U?5Er zEV>%2$O1Ia^>u~IpPx_s5AsufH(m?#;tZTX7=hC-wfCR+d-8vLogr;X`vIhOf;=tP z-xBQJBmuk8jV+ie*Vjkoi{^7mPX#JYqXcH-B$@{!n34LMw0P>UeSX8sO(Qr9jRDiz z3ktqfTSN*!nF3+%*spCKLpSFIKUi-$wM?Uk3ZaMbFTqyhse@L|S1&jiyzYD3kt{5r zJc~Ln7DcBh>gHtxWbZY>Y^;eqj`x5tR+`OAns~ zXNGYGow(^;`->(fL>V+avMjT4*P1=+z~5<)CljS0%-I4W*vgVh65FJWTQslM)gO9S zkX@UEg#RuS=cCMJa2P}s59j){uC-Vs%kE-V5%D2)uRUIuIR%9-D`Ef@uT63HQMh_D zo8}@<=GHeFye9Z!jw2dss`fx*9{4HQ(LG$*H4xl3C{z9|>|0oe%BLkw_r_mqSM`x- zdn}}w34aDJ{hVdscdOSfTwCIAY`5xXwu_X{s+n9!xBhM0wo%}hh|BbBnBR~pzw(!{ z!yw2z^bXgW1KxUh>l84Uu*+xds-a(f%=^#$<+Bl91pr$#y*CcP2A^!*c7f|65H2mEMewU8vMZuOT^#SBA)3>B?3%cX951sfxSW$}&I~MA z;ko1P@N3*U6UrMBOO+Nm4QhdOkXx2dY$ib33AU^q>%ez`-yF0DYz1vv2JLi^i^nQa zJcZuIV}Bj^$L=9NJ_o4`J&6S$=GSo~R<$)wdyw2>dS8do^V}B8YspeUcru??VW|-7 z_dfUe1=rvRs@cBk1?0zn<{t%Y(%r&(pZMQ^7EOw)8J>&5e~^^0WNBW)Hl6F}({~+* z=pk{WO1{GSx((vvy&``}GMH*mAn;%1)6QczXa-K_d-?_HaiA97&b^9C);6E&A_%m5Y`L^LBXiL-C zO4VggL!b@Fb*z5Xpz5Vn^CI>QVR_nwLT#Y;OknD#W5@%k6_i+Pc2h%xqH!%ATW|kb z)-K5#cT>$iJ@jxE)Zl?=(2m+330ZWo&v^65-*OpTUB=e;OKtm%pyrEUy}D~f;6T$m z`af{?r47Zh+B?>K7*A^}?mWhW;qx}e;pa+H+?p6xN~3JiHxF??CIBJXN2rE`G<>+d zdQ!NL1X&erHV-}Gz&Q(It_m8O%v8-OODs;1#ONj82`E=xb#)fh^C!h&K@~*13Q^=^ z>147g$m|d!W<2-p9B87aSUnP> zRP(=y={n*sbzwtJ!jZ%)XnG3b3x^1iq0X_&B?J?a>bw?(tuaYrMuw;)!YHF@2m!D( z(17D1MhV4zlnQ%FTGnF^>%lL`7-^hzw;J3Z*N~!L_xp66S$HAUrwkyEC`Fm%)??;M?LfN(iTqr_&Lc2tVaNJ!OU{N<`;eq?AJIn#-Y!4tGNESQ-aln-C* z0CV5=Y7&yl(p;fS$!Y5 zdfp@!Mjg>n|EtVy!8}9;m1HebA%C8Z;_u#*XVIM6$)dR$HZa6kuz{Zxf3AYA5?i-) zp#}(#i~rm?*so_(q}tBt7l^JivLs>TKjXvDMjOo0Dby8`lRsG-5opsKEBy;$Lr{#{EYT@s9YT8K-vnk0z#Tl^LTHRr~^rfBqE7xW3+o zQg~2BcoJy zEVHj|GjQ@nGowD@>ki!S;f`4lG&7v#Mc~ONQDpUFFh5WI_84BKM2o`plDN2&P;pGc zyTYicv^9)QnA|z@p${4kYgRrfFjeeaQlGyE+Ex726|urB9ccypVq?6fX5b@nPso4jQZ05?-9RLTL?Vkx7I5Z6&AlQ#I!>>GtcL z6p&c0UbVL*EbkaPSmHGWNpyBNEmOien106cI@>?v-GP#pP08-+;R|^7a{*_BrspRM z#hSlHXEeMNyoV#g%4Zbp_$Vr#P%Vw?Xv*uh=8tR#n)2Xd4TE#1xceQ!?CSKwJ8@)v zXlWN~#jc5v5R>TL?Y>j5^H|-hBiZ%VNabezmw%5`m`PAtihYn7k!J(_uv>k&ikRRL z<(ILBSDf{U>X(2`8>2tQL5?sRheeN>{_2=FzqZ5~%56-3y{kss$|+eVrK}QsR56kC z4)VAD)m1HwEfEuQ5ARXh%4Y2CMGf9Nz`dsU@hTyUc+FAE<5>rs7%~jMZ}KPVg-4^9 zbsb9+?gwksTk9oKzgY$bve3+&hI-YCBr0n~2aP79|I*^=s3S!&$98%>bqK%j zwYDp4AhS#F%djJ|K*64))D!>w6WBlx z@~wyT4)oCZGi2}+H`LSra+ZGvJ=UGlLe!~E-6{0mSIe|V(NXvK3q$#MlkywE>vP?K zKP>uL14uBh=z?zgHv$DX4WK_olrs)O*g%@)2S~s}Ui1%Yik!t4i2gu7I+uSCZ}AHD z9ZRq}Y@SsnQn@3~`nXF3BAe8hF;9UQ>msMbmmQG=CiWoAGvMhGLu^3bZM~VbAawXf zUF1F$EyZdvfle?^5hQ*+*}!RChp^e5IDR?bzIz00t&Bc|Lr=gUl9QkC08t(NKI8)W zQ@~-d5B;fD@NLcUxRjV>btuh7r06|Eh2fn;6k9 zve&-(*M{=i<%@-Nk<20zF;itpiSyTGA!3WAYx+o?#8rHdUK5ixyR1>LD>-)n8ewn) z!bAfZm)g%6c+SDNTl=F6dy{!hlB3=ZI~1TZPrzRasRj_rI}*ROg$* zAv9_$pB?u!UY0MVaT_j9`1#X5s1hog;l--CDSt0F1mnF7@%$R7cx-f;GX&7kv%G08OcQg zJnC74e2%5AXd$G@n(m#zUN({()U7j%{s7(SGSpcqdRKi5jK)H4?d*zA#u`Mc%WRuM z>CLTV>}}&fdxumOj%|xSNpx$lM}6<}PauDyF8^@g1q9O?f|R&Z$s6eIqf18_T2vC> zvQFqN1N#tfZV}lrSj1pU@|n_mj;3t4yMnCt#89gr#v!O*2-H8}m9#uOg(>D{)VYY9Hk!;JB&_V>!!hj5FafkmNnA@a zl}u}Y!@?a!FVlM?os%>|!=A~0eu-Z2*3yf+=6(fwuN_{LCf_oB?d{q~`sf55oZ*m) zs0e@}?PM`!7upFkIdgOfUUqCAO(6SGjmrpUEDmLS3s69m!s_G_tsv}C+$2e@i+)n} zSPiQia1=r4)zzLv?wj6W4QUjP2DR4m(BOXwkplKl&%d>V!6ZR^AWDp3QO=&iue=>%RO$)R$07c8Yb6r-_>tWlT6!j(yG;RlK(6*je z+Ql6-hRA(rQ2qj>WG_Z1DznjT7N?q8hV5VkEu`3;77)SJkeIr@ptLOfiIUWsjZ2%) zU`s%U8=gtkj;kNeF1;kh@u>tFBLKy@eY`1V`)q#MQ*LZ)pv2L%!C<6z(BM=`K{u=j z`;>E^5Z9HK6_xx(6~8;S+{6^cOyM2)D-V01ljvRr*`<-|3>Jmmi)+MtKY{|srXADt zK&bpO%#ywfY8KHWwuiYz_={PKhMvZ`yg7!Y*RwI-?hPFcBI zO#p@=G+%rLLvY%anFh;mR&c9v;!*4R{zWqCyCp>(j^bQ6L?IyzC6QBTbOG23_O3_d zIzUz1Vg>!3*q1~N3nrvMms!(OV=eYTn(g{6%ews2yz*JdR75W_MT(Y1a1_HSN~=0N0yefOgF;HbU`!(9v@o8vQs zMNo!irxUpxYJaX%a+~50+g(@tZG_b$obRp}+(k==f{3PO(yVw_rX}#^QG%Tgv2)QK zIf3+)rKGJU>lFxfMnv(XiBcUB+pgGjB}j9SZ`-|@Mkp&mB!FcFr7=)|R~xNwi(so= ziwU+=84L#qr2&8d*>QN<>7yu|UFLV4)-AJ1>;J>qJ4RQwHBrMcPi)(^-LY-kHafO# z+v=cW+g8Wwj+2h@rtkCe`R=_xzA?_(W1M~VuQgZAs#?2hmT-#)kE##)Wn$&ihQk?H zTJ{WM9{ve+-jjm=4F6tccRt0%_Wmv6>voC*mQov@_%|r=>ot}S%ahc!2gG=~ogYA2 zdi?wxyCBByJKMMpK=FP%gl|MqfM9$R#txKYZ>&)p&<@x^0X{O6;H{WEJi#Vh2dIv) zEo(b=nA!8|(?Q=&9I}tVHffne5i+4TU;|{*Gk&)oI43ja8^e}Sg!->pqsp>Oy27=S zvM}16u;8Qw*~PuYanfV^iQ}j^$3PsGIRS|gzOkblk<=T&e5vs@v(~T&d&j`iE&cg) zjFFWE1@;1X=iwqH*<}bt8AD`R zpxnR6aAFRz6NC57A_*@&PL7g1t#z#zFlzER(>9t?t}%bgJhS%WC$|tYiXm^=Am@ZQ z%OFoN)RTQzLB_KI(hTP(4X3_gP2i1YAIl3-$$rGuxMFqL0ya)P!0kpGKHmf;lXe&Y z);63c6|XfmP6Vy}LI<9Y16`OZ?DWw9f%fe~@bhE*^~n;}TAcrdsHVmShqKt5nQ)7C zl55rNzTR@z840d6sN15YPrA}AO5BeJSFs+Fr0BbW{O+_Y)Nbg-ENFq3p#4)bGd3_s zgi&#`5ocYaMNgekGs8weHDlC7y(; z`9Qu0$y}LKCsGu?!v%wita>C%kyN>0+{Wd8Ir||wdsrU609?U4Qa1-j4DU_)Tru*I zg*8n1(Ey%X)R& z;9|Fui&xV86Vv)c^#bS**iPj1!g3Gb0NWgg7oHGo(vSS+M;YB`;2GwWkuS|1nnzdq&+ zI~SAhuAMBy!GCFtX&+DOC?9g2Grjg?4bp2(F62$g8k6s-}rA7k)1Ly8tv8->B&fC%WX zd<{HDEOlV@nrp!6Wf>#lKj3zYWIl4l^rCaY$aCvch(2J$*?D{&>GP(;&FsOGBX-E) z72AC3=-q%X`!m%{{Df`BZykD? zhFy#F33_dJA0-rnF(uaqCH{jU}jZx&WX@l3n$yZn-8fgx4D0*QRL|{UlML?u2;V4+1 zF)mht$s0wO) z0OPvnA5Dz%1tR?RZ8^GN?FfrDhhdx8LU+!lFfHi5*%-%pU`V3M?Z^{OO0H>S35!rs(<~CrEVTK612^RG&M|be(y1G#3zO>x zD7@C_2b&Phw4%^ge#mybSRZ%e{|$=sXdE;Cr%^j$0>uvAQmF z9j>^^p^Q#94;zfllpb?q)%RQw#lCh0)gVMa#Cz}{71{@6xBPEAg%dSagqG}Z*&ydXJ;X}1cC^wi_G0vn}Cb*`WdA1Kq@p8-iH}3%f)&-aXof1H674)p_ zi%$4!K(YOj@L)5p2WZ%vEdy2J_MBHf-3j?OqJitATnu3_#kv7Y3L(s$XLc4WPWXdB zu!jCQ{(WenmaHJAtT4A0RpYdvbKLp`sDPK?3nhF=d{VMA>wEpv*4s6Xlihq7yXrTF zmQcP%q7OocH@fK`v>d!01Q5ns>~J41C|;SLD&DWHN^CP(p<0Hi#6ia7<6;HQ_+x4F zf#R6besVt}PN`1d%Y+%88CXZLQVDTvFu(Xc%Pl3P?|NCz3w3kIIze5~$RMu*+Z)Aq z@vShzz1xPlw+ujH+E}E^hlG&tht&m#bXU-C!f#7yN7z^}pG|uXa*nkQAUN6byiQ)_ zbJcHHRd(85(XhvQG~+`~h_(cJJvAQ<+%n3|gxTGJP!?kdLw7-yF1Ru#>4A*QN*iKz z0kBUGE8l3COkD+u4w?v7<2cKN_+BF3Y?x9TTGVUajIe(pI=qAWZq=)=|7z+X+J@WC zZ-4j4k2rcpqY;WRNk6J&-EX%3v9R+A=hV~&05Z|mnFQaDqkxtpD6F;>Oj>=vDqcgj zl4xq1ksUBTL~bg(NOm4f{=4hW4wgvPcj>BQuX<5t0t-Z-C#NkDWz_88gy;j z?%9UKHw0s%A|M-ZWD@RbMM*Khg=LsCzF$meSs9)*myN1jHtfXA4_z6YBq^z^%$YGh z#`LgY zj(+!mnXN4_scLZtTdr0)2#2#>5^mYqsS113j?96A!o8x8FMG2L0>PnC5e~mO(GMz% zhi%o2?2VBkuDs7U`%EclE1S0fLf-Kv8k=`y4A$xjnWC<|&pNxa0K(q!CKkKX9M7kB zOx)^O710z%*UCI;JQV(h`{s)%b<%y0U_85WS5)Z=&)7Wf#I^frveNZ9fi zXPO{vBS=*S&*tD*Ss_GThR=2~Y}tZ+;IJ+N=jFIA4)^S|uKzhmlUoBW)PY+CF4UP@ z819CXP9ca`PP|HpsmyrEfVYgyiZNn=%8D^%!P1H`X93HKF=+vYEq%bU1Y52@cb7pBI8^q>`At^92t2pDUXhjQSM_mZ`&B_~J3kj;zfPVq zSY6?iQA1FLuKBS&hOwYIM>~}o#kO-QGmS8FeO|she*Qdk_`LkylNrMOHIWg?#UB6p zoDGyY_0g)sw8~@y@1G0tpNr8i16uR_rTpL~Nh`*XrV1;@DeiPTyvZFKGg@WWcJQ|B z>K&WdgzQG+{c%i%WjX~)iYhK;;Bj<^Qjlc2qccoUJ_d;PMHtU&v>OjL4Lk6veVHK~ z>)uL1xJ*v%zKp}RNzdRW1Ean^ElyYpbZFY~waVfOw(OjAR##;6GE&)`;kDC~(d7yj zE*_riYV%_!H-2*rt+HiDH)!)T&9d5^GwMm&K`^E@(>0BZAnc;fLp3X8S%viT+UD?uDNi2O&RYxKpDPtpbz&^J@VoaE%$-7 zq2{R@dHQ0=1mZD*>jhR^LCXZ`=O?!nMBjyA6(gD@S~5m03W8hua}~o;kF6<)(uY|! z;vXfv81j2!#uCd9fZRYV#>*QJJ>jD#_|~UeIk28bki8*l2#fbAaf3_0tU1u?0!9qK zdh*%^Xn8Tyj;QrY*Fg|;;r%=%pFK6!co#tMdxo#h*YA~jW&t|^wlKqoYSe*h*q!Z% z4`a*%AgKW>x&f+BNY(tgT=s9D$pgxQ)`%cejI6<|8 zSn$B6om_&N@ZNTCN1!-YnBb?KWx{UpZg)UN8XO7+5HPsZ`nX5192)kK+Xfv;bbhu$ z(mUIPOyJ4)qQ$E3N{xs+r0jon__mMGHhdavox|mjvbo2LWapX-+R9buzme10i#H8v5abNGdFTUi;nofPz%3B+k|WRyI{j8Zmjaxn z)3qbCQc%CfhTYN@>+iOLyZVzGyQTf7VaG2pk5yNgGY4IuxVG8=ab5Rb<620=GHVLn z3ol@|jvpa>wG6w^D|#ODa97D4G`!~*urqB4LC2fMyPob;ojbLm7+VuNWbP=R9yUaM zt8BpfB5D`z0q&~w#m-}53*Nrtp_k`EeMk2p?5g_(_ObVk#-~{E@ykT8{I?%h8SJS1 zE5rS1T2wwIssk(Q%#UK$f%f0j9_4uO{AO!|^P1u6)i(e=1{a%Ee1IM+`9Aygrbizn zzZL#afoA(%`Ey90ixA&+;MF`KL;XtM`f`QeH#M)7bDPRQ1O?Bly>OouiXJ%XZGsDAAb!Y zE1n8PBOnC=I@0>La>Bo>1^-iKBxGZ5FK23QFJ@?IBkEyn>fmDeza+q7RBe?v#1Q@9 zaW*i4g`k5o<2hL^V>}&&=YtLM+lu96aI=Z8qA3WN!-#DHY&}W2L_U-RDsq@jxflFS zM&8R?yeY64%UR|opYQK~w|8ybZhySKQ}~yy${PVCa2CQqAQ`7G)TmuZv_2JN@i^Uy z*=aA}gqUruGyPOc$eOy8cPZM>RLdgrl<=PVHszMHD_W|;znAAxJGSvVn_)^nZBiG5 zETLBcR}y?c0n@A>QD+=mn`NW4qmMBG8d@Li7)zBg6bF!$?Y~jFVR3$ys@PnkR`E8+ ziBwyHNGNhpN!=Eq4IuHY1z5E`6$ftg>mW&Nuc?hVc_>qME5sv5Dvs0(VBLrOgg4u3 ztJ=Yz2XL6o)>^YWn@S(cN}+DmsN7HA>M9+gq?@kN+&PqNxRBJ2iK@=;k*h8ErmvV2 za5tS!wE0L15K=|$3n4`D8XWG7&Tf%*_pdmbpiUBPlwEFlp3OFDZ<=}}wZlJn_5Dbz zD}}NS14G9o9vPMdkp>v^Zz8}=I11q62#{ZeW6N{!zzyilr{#d9GTcu$=JqOwdPM!| zzR|2t$V7t?pIT~w8!0G!La$N}o_C5NB4T_Z$LY#hv}N|M6l#6wt?8giX5>{Dxe+Es#PW)U3hdP3^R@O5 z=y-CrD(hcjbEsJzAF%e4q=UYh1z=qYir7UU-9?f1b9O)s1(CpHdT2=$E6F;>Uj`@> z4{7$kA7GWZlJj)cdqCXd?5&-$L}wfEb~r>vob6GS`lS--FIC4{J-2Z~_|&I)Qu%F6Jo*Lv(6}sp>nc!+e-l9x7%e6QSuALd@LN zEx#R9J@zh`76|5+*LC$n+{;Fd`?}*Js1v-*(_^63MeqWuzf4S3nXMKzZT+ne{2YM5 zU=%C00T`Mvic~}5Ie(d87IG?-k#VBZtS|P+3-b92ZeU%JSNxm*)js@$YmR!3dyYKe zB!D@d45cyM)`v2j8#5Jh_LDbNXQ>%p~-zr#`b@0iMA5?*h;L^WK z*Iz8T*{Ljv$5ec1!9}n7A+HJ+lPt>v(EtYrlNldA$L8dh1a^hDtXuE{i}ti4eHghz=c!jdO8R*O zEcM(XEl1ql2eCGe-h_L3y90<-?Rb6h_8PHmxOW@<9ecLgU@j|!@D$iJ14c5LsWS?8 zuM2coM#b{3A)QdVGs)xoKGw4CJ6L;*FvF-Hz2{&t8f8gQvuL9A!64*9dP`QB#5rU` zlwB_7%`DPu^uC%36`lTk)Tg+jvO?^L1LQ|k697?-UgG>l6(~*;(|lR=N(KqF%9+`2 zCN4JHsDq7QTB^lO1%Ba@F-yI64Kb$RpCsz?v-o0d!PIIaoP`1k6>2?yi56OLq%H=0 z7LpeJYqc@cKVU0jVQ6P=YVtp|;Qou_Qxc}+K$uWN!17(`5^La|tsqxn;5kTLlE5lVi*4~Af)bXZ*SaXoajo^QNN(D)mxI7tv@1SE*V zScd9SU}lj}9Jr6;eiq@mdB=JqefcTHo5RPwr#IGXE|DjpU&$`gsMgA6B(!3VHO^)| zNYHlb_|@WGh4Rg?%FeugboLc)%W;enLV$->oH%*2NfcAj&)ajn_d6g&Zbv-wW&G&J zmty{-sJ@d=4pL|?W~imu?}oDX*d{440f%?woTJQ(3Ux9abTD``E=89`wEPhV%Y5L~ zN9r=zzIb&mKp6HNQ}u)c6q9GR2>&@ELFboa84? zO#g}#$v@!qU�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�}F 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 `A&1IXe*9%yY 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 z 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%0An1#J4Qx^Qw&C^8S*rqZ7pGGV=_CI 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 b!n^_7)?(lwO19{J(f#H`!o(MaC57jISiipG literal 0 HcmV?d00001 diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentConnector.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentConnector.java deleted file mode 100644 index 41c8ca80..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentConnector.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -public interface AgentConnector { - String getName(); - boolean isAvailable(); - void query(Buffer buffer) throws AgentProxyException; -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentIdentity.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentIdentity.java deleted file mode 100644 index 0433ce24..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentIdentity.java +++ /dev/null @@ -1,80 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class AgentIdentity implements Identity { - - private AgentProxy agent; - private byte[] blob; - private String comment; - private String algname; - AgentIdentity(AgentProxy agent, byte[] blob, String comment) { - this.agent = agent; - this.blob = blob; - this.comment = comment; - algname = Util.byte2str((new Buffer(blob)).getString()); - } - - @Override - public boolean setPassphrase(byte[] passphrase) throws JSchException{ - return true; - } - - @Override - public byte[] getPublicKeyBlob() { return blob; } - - @Override - public byte[] getSignature(byte[] data){ - return agent.sign(blob, data, null); - } - - @Override - public byte[] getSignature(byte[] data, String alg){ - return agent.sign(blob, data, alg); - } - - @Override - @Deprecated - public boolean decrypt() { - throw new RuntimeException("not implemented"); - } - - @Override - public String getAlgName() { return algname; } - - @Override - public String getName() { return comment; } - - @Override - public boolean isEncrypted() { return false; } - - @Override - public void clear() { } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentIdentityRepository.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentIdentityRepository.java deleted file mode 100644 index acda110b..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentIdentityRepository.java +++ /dev/null @@ -1,75 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.util.Vector; - -public class AgentIdentityRepository implements IdentityRepository { - - private AgentProxy agent; - public AgentIdentityRepository(AgentConnector connector) { - this.agent = new AgentProxy(connector); - } - - @Override - public Vector getIdentities() { - return agent.getIdentities(); - } - - @Override - public boolean add(byte[] identity) { - return agent.addIdentity(identity); - } - - @Override - public boolean remove(byte[] blob) { - return agent.removeIdentity(blob); - } - - @Override - public void removeAll() { - agent.removeAllIdentities(); - } - - @Override - public String getName() { - return agent.getConnector().getName(); - } - - @Override - public int getStatus() { - if(agent.getConnector().isAvailable()){ - return RUNNING; - } - else { - return NOTRUNNING; - } - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentProxy.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentProxy.java deleted file mode 100644 index 9d83b2a4..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentProxy.java +++ /dev/null @@ -1,256 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2012 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.util.Vector; - -class AgentProxy { - - private static final byte SSH_AGENTC_REQUEST_RSA_IDENTITIES = 1; - private static final byte SSH_AGENT_RSA_IDENTITIES_ANSWER = 2; - private static final byte SSH_AGENTC_RSA_CHALLENGE = 3; - private static final byte SSH_AGENT_RSA_RESPONSE = 4; - private static final byte SSH_AGENT_FAILURE = 5; - private static final byte SSH_AGENT_SUCCESS = 6; - private static final byte SSH_AGENTC_ADD_RSA_IDENTITY = 7; - private static final byte SSH_AGENTC_REMOVE_RSA_IDENTITY = 8; - private static final byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9; - - private static final byte SSH2_AGENTC_REQUEST_IDENTITIES = 11; - private static final byte SSH2_AGENT_IDENTITIES_ANSWER = 12; - private static final byte SSH2_AGENTC_SIGN_REQUEST = 13; - private static final byte SSH2_AGENT_SIGN_RESPONSE = 14; - private static final byte SSH2_AGENTC_ADD_IDENTITY = 17; - private static final byte SSH2_AGENTC_REMOVE_IDENTITY = 18; - private static final byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES = 19; - - private static final byte SSH_AGENTC_ADD_SMARTCARD_KEY = 20; - private static final byte SSH_AGENTC_REMOVE_SMARTCARD_KEY = 21; - - private static final byte SSH_AGENTC_LOCK = 22; - private static final byte SSH_AGENTC_UNLOCK = 23; - - private static final byte SSH_AGENTC_ADD_RSA_ID_CONSTRAINED = 24; - private static final byte SSH2_AGENTC_ADD_ID_CONSTRAINED = 25; - private static final byte SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED = 26; - - private static final byte SSH_AGENT_CONSTRAIN_LIFETIME = 1; - private static final byte SSH_AGENT_CONSTRAIN_CONFIRM = 2; - - private static final byte SSH2_AGENT_FAILURE = 30; - - private static final byte SSH_COM_AGENT2_FAILURE = 102; - - //private static final byte SSH_AGENT_OLD_SIGNATURE = 0x1; - private static final int SSH_AGENT_RSA_SHA2_256 = 0x2; - private static final int SSH_AGENT_RSA_SHA2_512 = 0x4; - - private static final int MAX_AGENT_IDENTITIES = 2048; - - private final byte[] buf = new byte[1024]; - private final Buffer buffer = new Buffer(buf); - - private AgentConnector connector; - - AgentProxy(AgentConnector connector){ - this.connector = connector; - } - - synchronized Vector getIdentities() { - Vector identities = new Vector<>(); - - int required_size = 1 + 4; - buffer.reset(); - buffer.checkFreeSize(required_size); - buffer.putInt(required_size - 4); - buffer.putByte(SSH2_AGENTC_REQUEST_IDENTITIES); - - try { - connector.query(buffer); - } - catch(AgentProxyException e){ - buffer.rewind(); - buffer.putByte(SSH_AGENT_FAILURE); - return identities; - } - - int rcode = buffer.getByte(); - - //System.out.println(rcode == SSH2_AGENT_IDENTITIES_ANSWER); - - if(rcode != SSH2_AGENT_IDENTITIES_ANSWER) { - return identities; - } - - int count = buffer.getInt(); - //System.out.println(count); - if(count <= 0 || count > MAX_AGENT_IDENTITIES) { - return identities; - } - - for(int i=0; i>> 24); - tmp[1]=(byte)(val >>> 16); - tmp[2]=(byte)(val >>> 8); - tmp[3]=(byte)(val); - System.arraycopy(tmp, 0, buffer, index, 4); - index+=4; - } - public void putLong(long val) { - tmp[0]=(byte)(val >>> 56); - tmp[1]=(byte)(val >>> 48); - tmp[2]=(byte)(val >>> 40); - tmp[3]=(byte)(val >>> 32); - System.arraycopy(tmp, 0, buffer, index, 4); - tmp[0]=(byte)(val >>> 24); - tmp[1]=(byte)(val >>> 16); - tmp[2]=(byte)(val >>> 8); - tmp[3]=(byte)(val); - System.arraycopy(tmp, 0, buffer, index+4, 4); - index+=8; - } - void skip(int n) { - index+=n; - } - void putPad(int n) { - while(n>0){ - buffer[index++]=(byte)0; - n--; - } - } - public void putMPInt(byte[] foo){ - int i=foo.length; - if((foo[0]&0x80)!=0){ - i++; - putInt(i); - putByte((byte)0); - } - else{ - putInt(i); - } - putByte(foo); - } - public int getLength(){ - return index-s; - } - public int getOffSet(){ - return s; - } - public void setOffSet(int s){ - this.s=s; - } - public long getLong(){ - long foo = getInt()&0xffffffffL; - foo = ((foo<<32)) | (getInt()&0xffffffffL); - return foo; - } - public int getInt(){ - int foo = getShort(); - foo = ((foo<<16)&0xffff0000) | (getShort()&0xffff); - return foo; - } - public long getUInt(){ - long foo = 0L; - long bar = 0L; - foo = getByte(); - foo = ((foo<<8)&0xff00)|(getByte()&0xff); - bar = getByte(); - bar = ((bar<<8)&0xff00)|(getByte()&0xff); - foo = ((foo<<16)&0xffff0000) | (bar&0xffff); - return foo; - } - int getShort() { - int foo = getByte(); - foo = ((foo<<8)&0xff00)|(getByte()&0xff); - return foo; - } - public int getByte() { - return (buffer[s++]&0xff); - } - public void getByte(byte[] foo) { - getByte(foo, 0, foo.length); - } - void getByte(byte[] foo, int start, int len) { - System.arraycopy(buffer, s, foo, start, len); - s+=len; - } - public int getByte(int len) { - int foo=s; - s+=len; - return foo; - } - public byte[] getMPInt() { - int i=getInt(); // uint32 - if(i<0 || // bigger than 0x7fffffff - i>8*1024){ - // TODO: an exception should be thrown. - i = 8*1024; // the session will be broken, but working around OOME. - } - byte[] foo=new byte[i]; - getByte(foo, 0, i); - return foo; - } - public byte[] getMPIntBits() { - int bits=getInt(); - int bytes=(bits+7)/8; - byte[] foo=new byte[bytes]; - getByte(foo, 0, bytes); - if((foo[0]&0x80)!=0){ - byte[] bar=new byte[foo.length+1]; - bar[0]=0; // ?? - System.arraycopy(foo, 0, bar, 1, foo.length); - foo=bar; - } - return foo; - } - public byte[] getString() { - int i = getInt(); // uint32 - if(i<0 || // bigger than 0x7fffffff - i>256*1024){ - // TODO: an exception should be thrown. - i = 256*1024; // the session will be broken, but working around OOME. - } - byte[] foo=new byte[i]; - getByte(foo, 0, i); - return foo; - } - byte[] getString(int[]start, int[]len) { - int i=getInt(); - start[0]=getByte(i); - len[0]=i; - return buffer; - } - public void reset(){ - index=0; - s=0; - } - public void shift(){ - if(s==0)return; - System.arraycopy(buffer, s, buffer, 0, index-s); - index=index-s; - s=0; - } - void rewind(){ - s=0; - } - - byte getCommand(){ - return buffer[5]; - } - - void checkFreeSize(int n){ - int size = index+n+Session.buffer_margin; - if(buffer.length>>4)&0xf]); - System.err.print(chars[foo&0xf]); - if(i%16==15){ - System.err.println(""); - continue; - } - if(i>0 && i%2==1){ - System.err.print(" "); - } - } - System.err.println(""); - } - static void dump(byte[] b){ - dump(b, 0, b.length); - } - static void dump(byte[] b, int s, int l){ - for(int i=s; i pool=new Vector<>(); - static Channel getChannel(String type, Session session){ - Channel ret = null; - if(type.equals("session")){ - ret = new ChannelSession(); - } - if(type.equals("shell")){ - ret = new ChannelShell(); - } - if(type.equals("exec")){ - ret = new ChannelExec(); - } - if(type.equals("x11")){ - ret = new ChannelX11(); - } - if(type.equals("auth-agent@openssh.com")){ - ret = new ChannelAgentForwarding(); - } - if(type.equals("direct-tcpip")){ - ret = new ChannelDirectTCPIP(); - } - if(type.equals("forwarded-tcpip")){ - ret = new ChannelForwardedTCPIP(); - } - if(type.equals("sftp")){ - ret = new ChannelSftp(); - } - if(type.equals("subsystem")){ - ret = new ChannelSubsystem(); - } - if(type.equals("direct-streamlocal@openssh.com")){ - ret = new ChannelDirectStreamLocal(); - } - if (ret == null) { - return null; - } - ret.setSession(session); - return ret; - } - static Channel getChannel(int id, Session session){ - synchronized(pool){ - for(int i=0; i0) - notifyAll(); - } - int getRecipient(){ - return recipient; - } - - void init() throws JSchException { - } - - public void connect() throws JSchException{ - connect(0); - } - - public void connect(int connectTimeout) throws JSchException{ - this.connectTimeout=connectTimeout; - try{ - sendChannelOpen(); - start(); - } - catch(Exception e){ - connected=false; - disconnect(); - if(e instanceof JSchException) - throw (JSchException)e; - throw new JSchException(e.toString(), e); - } - } - - public void setXForwarding(boolean foo){ - } - - public void start() throws JSchException{} - - public boolean isEOF() {return eof_remote;} - - void getData(Buffer buf){ - setRecipient(buf.getInt()); - setRemoteWindowSize(buf.getUInt()); - setRemotePacketSize(buf.getInt()); - } - - public void setInputStream(InputStream in){ - io.setInputStream(in, false); - } - public void setInputStream(InputStream in, boolean dontclose){ - io.setInputStream(in, dontclose); - } - public void setOutputStream(OutputStream out){ - io.setOutputStream(out, false); - } - public void setOutputStream(OutputStream out, boolean dontclose){ - io.setOutputStream(out, dontclose); - } - public void setExtOutputStream(OutputStream out){ - io.setExtOutputStream(out, false); - } - public void setExtOutputStream(OutputStream out, boolean dontclose){ - io.setExtOutputStream(out, dontclose); - } - public InputStream getInputStream() throws IOException { - int max_input_buffer_size = 32*1024; - try { - max_input_buffer_size = - Integer.parseInt(getSession().getConfig("max_input_buffer_size")); - } - catch(Exception e){} - PipedInputStream in = - new MyPipedInputStream( - 32*1024, // this value should be customizable. - max_input_buffer_size - ); - boolean resizable = 32*10240){ - int _l=l; - if(l>_bufl-(14+dataLen)-Session.buffer_margin){ - _l=_bufl-(14+dataLen)-Session.buffer_margin; - } - - if(_l<=0){ - flush(); - continue; - } - - System.arraycopy(buf, s, _buf, 14+dataLen, _l); - dataLen+=_l; - s+=_l; - l-=_l; - } - } - - @Override - public void flush() throws IOException{ - if(closed){ - throw new IOException("Already closed"); - } - if(dataLen==0) - return; - packet.reset(); - buffer.putByte((byte)Session.SSH_MSG_CHANNEL_DATA); - buffer.putInt(recipient); - buffer.putInt(dataLen); - buffer.skip(dataLen); - try{ - int foo=dataLen; - dataLen=0; - synchronized(channel){ - if(!channel.close) - getSession().write(packet, channel, foo); - } - } - catch(Exception e){ - close(); - throw new IOException(e.toString(), e); - } - - } - @Override - public void close() throws IOException{ - if(packet==null){ - try{ - init(); - } - catch(IOException e){ - // close should be finished silently. - return; - } - } - if(closed){ - return; - } - if(dataLen>0){ - flush(); - } - channel.eof(); - closed=true; - } - }; - return out; - } - - static class MyPipedInputStream extends PipedInputStream{ - private int BUFFER_SIZE = 1024; - private int max_buffer_size = BUFFER_SIZE; - MyPipedInputStream() throws IOException{ super(); } - MyPipedInputStream(int size) throws IOException{ - super(); - buffer=new byte[size]; - BUFFER_SIZE = size; - max_buffer_size = size; - } - MyPipedInputStream(int size, int max_buffer_size) throws IOException{ - this(size); - this.max_buffer_size = max_buffer_size; - } - MyPipedInputStream(PipedOutputStream out) throws IOException{ super(out); } - MyPipedInputStream(PipedOutputStream out, int size) throws IOException{ - super(out); - buffer=new byte[size]; - BUFFER_SIZE=size; - } - - /* - * TODO: We should have our own Piped[I/O]Stream implementation. - * Before accepting data, JDK's PipedInputStream will check the existence of - * reader thread, and if it is not alive, the stream will be closed. - * That behavior may cause the problem if multiple threads make access to it. - */ - public synchronized void updateReadSide() throws IOException { - if(available() != 0){ // not empty - return; - } - in = 0; - out = 0; - buffer[in++] = 0; - read(); - } - - private int freeSpace(){ - int size = 0; - if(out < in) { - size = buffer.length-in; - } - else if(in < out){ - if(in == -1) size = buffer.length; - else size = out - in; - } - return size; - } - synchronized void checkSpace(int len) throws IOException { - int size = freeSpace(); - if(size max_buffer_size){ - foo = max_buffer_size; - } - if((foo - datasize) < len) return; - - byte[] tmp = new byte[foo]; - if(out < in) { - System.arraycopy(buffer, 0, tmp, 0, buffer.length); - } - else if(in < out){ - if(in == -1) { - } - else { - System.arraycopy(buffer, 0, tmp, 0, in); - System.arraycopy(buffer, out, - tmp, tmp.length-(buffer.length-out), - (buffer.length-out)); - out = tmp.length-(buffer.length-out); - } - } - else if(in == out){ - System.arraycopy(buffer, 0, tmp, 0, buffer.length); - in=buffer.length; - } - buffer=tmp; - } - else if(buffer.length == size && size > BUFFER_SIZE) { - int i = size/2; - if(i0) - notifyAll(); - } - void setRemotePacketSize(int foo){ this.rmpsize=foo; } - - abstract void run(); - - void write(byte[] foo) throws IOException { - write(foo, 0, foo.length); - } - void write(byte[] foo, int s, int l) throws IOException { - try{ - io.put(foo, s, l); - }catch(NullPointerException e){} - } - void write_ext(byte[] foo, int s, int l) throws IOException { - try{ - io.put_ext(foo, s, l); - }catch(NullPointerException e){} - } - - void eof_remote(){ - eof_remote=true; - try{ - io.out_close(); - } - catch(NullPointerException e){} - } - - void eof(){ - if(eof_local)return; - eof_local=true; - - int i = getRecipient(); - if(i == -1) return; - - try{ - Buffer buf=new Buffer(100); - Packet packet=new Packet(buf); - packet.reset(); - buf.putByte((byte)Session.SSH_MSG_CHANNEL_EOF); - buf.putInt(i); - synchronized(this){ - if(!close) - getSession().write(packet); - } - } - catch(Exception e){ - //System.err.println("Channel.eof"); - //e.printStackTrace(); - } - /* - if(!isConnected()){ disconnect(); } - */ - } - - /* - http://www1.ietf.org/internet-drafts/draft-ietf-secsh-connect-24.txt - -5.3 Closing a Channel - When a party will no longer send more data to a channel, it SHOULD - send SSH_MSG_CHANNEL_EOF. - - byte SSH_MSG_CHANNEL_EOF - uint32 recipient_channel - - No explicit response is sent to this message. However, the - application may send EOF to whatever is at the other end of the - channel. Note that the channel remains open after this message, and - more data may still be sent in the other direction. This message - does not consume window space and can be sent even if no window space - is available. - - When either party wishes to terminate the channel, it sends - SSH_MSG_CHANNEL_CLOSE. Upon receiving this message, a party MUST - send back a SSH_MSG_CHANNEL_CLOSE unless it has already sent this - message for the channel. The channel is considered closed for a - party when it has both sent and received SSH_MSG_CHANNEL_CLOSE, and - the party may then reuse the channel number. A party MAY send - SSH_MSG_CHANNEL_CLOSE without having sent or received - SSH_MSG_CHANNEL_EOF. - - byte SSH_MSG_CHANNEL_CLOSE - uint32 recipient_channel - - This message does not consume window space and can be sent even if no - window space is available. - - It is recommended that any data sent before this message is delivered - to the actual destination, if possible. - */ - - void close(){ - if(close)return; - close=true; - eof_local=eof_remote=true; - - int i = getRecipient(); - if(i == -1) return; - - try{ - Buffer buf=new Buffer(100); - Packet packet=new Packet(buf); - packet.reset(); - buf.putByte((byte)Session.SSH_MSG_CHANNEL_CLOSE); - buf.putInt(i); - synchronized(this){ - getSession().write(packet); - } - } - catch(Exception e){ - //e.printStackTrace(); - } - } - public boolean isClosed(){ - return close; - } - static void disconnect(Session session){ - Channel[] channels=null; - int count=0; - synchronized(pool){ - channels=new Channel[pool.size()]; - for(int i=0; i0){ - if(timeout>0L){ - if((System.currentTimeMillis()-start)>timeout){ - retry=0; - continue; - } - } - try{ - long t = timeout==0L ? 10L : timeout; - this.notifyme=1; - wait(t); - } - catch(InterruptedException e){ - } - finally{ - this.notifyme=0; - } - retry--; - } - } - if(!_session.isConnected()){ - throw new JSchException("session is down"); - } - if(this.getRecipient()==-1){ // timeout - throw new JSchException("channel is not opened."); - } - if(this.open_confirmation==false){ // SSH_MSG_CHANNEL_OPEN_FAILURE - throw new JSchException("channel is not opened."); - } - connected=true; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelAgentForwarding.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelAgentForwarding.java deleted file mode 100644 index 6fa2d705..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelAgentForwarding.java +++ /dev/null @@ -1,287 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2006-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.io.IOException; -import java.net.*; -import java.util.Vector; - -class ChannelAgentForwarding extends Channel{ - - static private final int LOCAL_WINDOW_SIZE_MAX=0x20000; - static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000; - - static private final byte SSH_AGENTC_REQUEST_RSA_IDENTITIES = 1; - static private final byte SSH_AGENT_RSA_IDENTITIES_ANSWER = 2; - static private final byte SSH_AGENTC_RSA_CHALLENGE = 3; - static private final byte SSH_AGENT_RSA_RESPONSE = 4; - static private final byte SSH_AGENT_FAILURE = 5; - static private final byte SSH_AGENT_SUCCESS = 6; - static private final byte SSH_AGENTC_ADD_RSA_IDENTITY = 7; - static private final byte SSH_AGENTC_REMOVE_RSA_IDENTITY = 8; - static private final byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9; - - static private final byte SSH2_AGENTC_REQUEST_IDENTITIES=11; - static private final byte SSH2_AGENT_IDENTITIES_ANSWER=12; - static private final byte SSH2_AGENTC_SIGN_REQUEST=13; - static private final byte SSH2_AGENT_SIGN_RESPONSE=14; - static private final byte SSH2_AGENTC_ADD_IDENTITY=17; - static private final byte SSH2_AGENTC_REMOVE_IDENTITY=18; - static private final byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES=19; - static private final byte SSH2_AGENT_FAILURE=30; - - //static private final int SSH_AGENT_OLD_SIGNATURE=0x1; - static private final int SSH_AGENT_RSA_SHA2_256=0x2; - static private final int SSH_AGENT_RSA_SHA2_512=0x4; - - private Buffer rbuf=null; - private Buffer wbuf=null; - private Packet packet=null; - private Buffer mbuf=null; - - ChannelAgentForwarding(){ - super(); - - setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX); - setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX); - setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE); - - type=Util.str2byte("auth-agent@openssh.com"); - rbuf=new Buffer(); - rbuf.reset(); - //wbuf=new Buffer(rmpsize); - //packet=new Packet(wbuf); - mbuf=new Buffer(); - connected=true; - } - - @Override - void run(){ - try{ - sendOpenConfirmation(); - } - catch(Exception e){ - close=true; - disconnect(); - } - } - - @Override - void write(byte[] foo, int s, int l) throws IOException { - - if(packet==null){ - wbuf=new Buffer(rmpsize); - packet=new Packet(wbuf); - } - - rbuf.shift(); - if(rbuf.buffer.lengthrbuf.getLength()){ - rbuf.s-=4; - return; - } - - int typ=rbuf.getByte(); - - Session _session=null; - try{ - _session=getSession(); - } - catch(JSchException e){ - throw new IOException(e.toString(), e); - } - - IdentityRepository irepo = _session.getIdentityRepository(); - UserInfo userinfo=_session.getUserInfo(); - - mbuf.reset(); - - if(typ==SSH2_AGENTC_REQUEST_IDENTITIES){ - mbuf.putByte(SSH2_AGENT_IDENTITIES_ANSWER); - Vector identities = irepo.getIdentities(); - synchronized(identities){ - int count=0; - for(int i=0; i identities = irepo.getIdentities(); - Identity identity = null; - synchronized(identities){ - for(int i=0; i - * https://raw.githubusercontent.com/openssh/openssh-portable/master/PROTOCOL - */ -public class ChannelDirectStreamLocal extends ChannelDirectTCPIP { - - static private final int LOCAL_WINDOW_SIZE_MAX = 0x20000; - static private final int LOCAL_MAXIMUM_PACKET_SIZE = 0x4000; - static private final byte[] _type = Util.str2byte("direct-streamlocal@openssh.com"); - - private String socketPath; - - ChannelDirectStreamLocal() { - super(); - type = _type; - setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX); - setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX); - setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE); - } - - @Override - protected Packet genChannelOpenPacket() { - - if (socketPath == null) { - session.getLogger().log(Logger.FATAL, "socketPath must be set"); - throw new RuntimeException("socketPath must be set"); - } - - /* - Similar to direct-tcpip, direct-streamlocal is sent by the client - to request that the server make a connection to a Unix domain socket. - - byte SSH_MSG_CHANNEL_OPEN - string "direct-streamlocal@openssh.com" - uint32 sender channel - uint32 initial window size - uint32 maximum packet size - string socket path - string reserved - uint32 reserved - */ - - Buffer buf = new Buffer(50 + - socketPath.length() + - Session.buffer_margin); - Packet packet = new Packet(buf); - packet.reset(); - buf.putByte((byte) SSH_MSG_CHANNEL_OPEN); - buf.putString(this.type); - buf.putInt(id); - buf.putInt(lwsize); - buf.putInt(lmpsize); - buf.putString(Util.str2byte(socketPath)); - buf.putString(Util.str2byte(originator_IP_address)); - buf.putInt(originator_port); - return packet; - } - - public String getSocketPath() { - return socketPath; - } - - public void setSocketPath(String socketPath) { - this.socketPath = socketPath; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelDirectTCPIP.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelDirectTCPIP.java deleted file mode 100644 index f4c127be..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelDirectTCPIP.java +++ /dev/null @@ -1,176 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.io.*; - -public class ChannelDirectTCPIP extends Channel{ - - static private final int LOCAL_WINDOW_SIZE_MAX=0x20000; - static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000; - static private final byte[] _type = Util.str2byte("direct-tcpip"); - String host; - int port; - - String originator_IP_address="127.0.0.1"; - int originator_port=0; - - ChannelDirectTCPIP(){ - super(); - type = _type; - setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX); - setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX); - setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE); - } - - @Override - void init (){ - io=new IO(); - } - - @Override - public void connect(int connectTimeout) throws JSchException{ - this.connectTimeout=connectTimeout; - try{ - Session _session=getSession(); - if(!_session.isConnected()){ - throw new JSchException("session is down"); - } - - if(io.in!=null){ - thread=new Thread(this::run); - thread.setName("DirectTCPIP thread "+_session.getHost()); - if(_session.daemon_thread){ - thread.setDaemon(_session.daemon_thread); - } - thread.start(); - } - else { - sendChannelOpen(); - } - } - catch(Exception e){ - io.close(); - io=null; - Channel.del(this); - if (e instanceof JSchException) { - throw (JSchException) e; - } - } - } - - @Override - void run(){ - - try{ - sendChannelOpen(); - - Buffer buf=new Buffer(rmpsize); - Packet packet=new Packet(buf); - Session _session=getSession(); - int i=0; - - while(isConnected() && - thread!=null && - io!=null && - io.in!=null){ - i=io.in.read(buf.buffer, - 14, - buf.buffer.length-14 - -Session.buffer_margin - ); - if(i<=0){ - eof(); - break; - } - packet.reset(); - buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA); - buf.putInt(recipient); - buf.putInt(i); - buf.skip(i); - synchronized(this){ - if(close) - break; - _session.write(packet, this, i); - } - } - } - catch(Exception e){ - // Whenever an exception is thrown by sendChannelOpen(), - // 'connected' is false. - if(!connected){ - connected=true; - } - disconnect(); - return; - } - - eof(); - disconnect(); - } - - @Override - public void setInputStream(InputStream in){ - io.setInputStream(in); - } - @Override - public void setOutputStream(OutputStream out){ - io.setOutputStream(out); - } - - public void setHost(String host){this.host=host;} - public void setPort(int port){this.port=port;} - public void setOrgIPAddress(String foo){this.originator_IP_address=foo;} - public void setOrgPort(int foo){this.originator_port=foo;} - - @Override - protected Packet genChannelOpenPacket(){ - Buffer buf = new Buffer(50 + // 6 + 4*8 + 12 - host.length() + originator_IP_address.length() + - Session.buffer_margin); - Packet packet = new Packet(buf); - // byte SSH_MSG_CHANNEL_OPEN(90) - // string channel type // - // uint32 sender channel // 0 - // uint32 initial window size // 0x100000(65536) - // uint32 maxmum packet size // 0x4000(16384) - packet.reset(); - buf.putByte((byte)90); - buf.putString(this.type); - buf.putInt(id); - buf.putInt(lwsize); - buf.putInt(lmpsize); - buf.putString(Util.str2byte(host)); - buf.putInt(port); - buf.putString(Util.str2byte(originator_IP_address)); - buf.putInt(originator_port); - return packet; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelExec.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelExec.java deleted file mode 100644 index 3980ffd6..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelExec.java +++ /dev/null @@ -1,84 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.io.*; -import java.util.*; - -public class ChannelExec extends ChannelSession{ - - byte[] command=new byte[0]; - - @Override - public void start() throws JSchException{ - Session _session=getSession(); - try{ - sendRequests(); - Request request=new RequestExec(command); - request.request(_session, this); - } - catch(Exception e){ - if(e instanceof JSchException) throw (JSchException)e; - throw new JSchException("ChannelExec", e); - } - - if(io.in!=null){ - thread=new Thread(this::run); - thread.setName("Exec thread "+_session.getHost()); - if(_session.daemon_thread){ - thread.setDaemon(_session.daemon_thread); - } - thread.start(); - } - } - - public void setCommand(String command){ - this.command=Util.str2byte(command); - } - public void setCommand(byte[] command){ - this.command=command; - } - - @Override - void init() throws JSchException { - io.setInputStream(getSession().in); - io.setOutputStream(getSession().out); - } - - public void setErrStream(OutputStream out){ - setExtOutputStream(out); - } - public void setErrStream(OutputStream out, boolean dontclose){ - setExtOutputStream(out, dontclose); - } - public InputStream getErrStream() throws IOException { - return getExtInputStream(); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelForwardedTCPIP.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelForwardedTCPIP.java deleted file mode 100644 index 0210e059..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelForwardedTCPIP.java +++ /dev/null @@ -1,335 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.net.*; -import java.io.*; -import java.util.Vector; - -public class ChannelForwardedTCPIP extends Channel{ - - private static Vector pool = new Vector<>(); - - static private final int LOCAL_WINDOW_SIZE_MAX=0x20000; -//static private final int LOCAL_WINDOW_SIZE_MAX=0x100000; - static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000; - - static private final int TIMEOUT=10*1000; - - private Socket socket=null; - private ForwardedTCPIPDaemon daemon=null; - private Config config = null; - - ChannelForwardedTCPIP(){ - super(); - setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX); - setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX); - setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE); - io=new IO(); - connected=true; - } - - @Override - public void run(){ - try{ - if(config instanceof ConfigDaemon){ - ConfigDaemon _config = (ConfigDaemon)config; - Class c=Class.forName(_config.target).asSubclass(ForwardedTCPIPDaemon.class); - daemon=c.getDeclaredConstructor().newInstance(); - - PipedOutputStream out=new PipedOutputStream(); - io.setInputStream(new PassiveInputStream(out - , 32*1024 - ), false); - - daemon.setChannel(this, getInputStream(), out); - daemon.setArg(_config.arg); - new Thread(daemon).start(); - } - else{ - ConfigLHost _config = (ConfigLHost)config; - socket=(_config.factory==null) ? - Util.createSocket(_config.target, _config.lport, TIMEOUT) : - _config.factory.createSocket(_config.target, _config.lport); - socket.setTcpNoDelay(true); - io.setInputStream(socket.getInputStream()); - io.setOutputStream(socket.getOutputStream()); - } - sendOpenConfirmation(); - } - catch(Exception e){ - sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED); - close=true; - disconnect(); - return; - } - - thread=Thread.currentThread(); - Buffer buf=new Buffer(rmpsize); - Packet packet=new Packet(buf); - int i=0; - try{ - Session _session = getSession(); - while(thread!=null && - io!=null && - io.in!=null){ - i=io.in.read(buf.buffer, - 14, - buf.buffer.length-14 - -Session.buffer_margin - ); - if(i<=0){ - eof(); - break; - } - packet.reset(); - buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA); - buf.putInt(recipient); - buf.putInt(i); - buf.skip(i); - synchronized(this){ - if(close) - break; - _session.write(packet, this, i); - } - } - } - catch(Exception e){ - //System.err.println(e); - } - //thread=null; - //eof(); - disconnect(); - } - - @Override - void getData(Buffer buf){ - setRecipient(buf.getInt()); - setRemoteWindowSize(buf.getUInt()); - setRemotePacketSize(buf.getInt()); - byte[] addr=buf.getString(); - int port=buf.getInt(); - byte[] orgaddr=buf.getString(); - int orgport=buf.getInt(); - - /* - System.err.println("addr: "+Util.byte2str(addr)); - System.err.println("port: "+port); - System.err.println("orgaddr: "+Util.byte2str(orgaddr)); - System.err.println("orgport: "+orgport); - */ - - Session _session=null; - try{ - _session=getSession(); - } - catch(JSchException e){ - // session has been already down. - } - - this.config = getPort(_session, Util.byte2str(addr), port); - if(this.config == null) - this.config = getPort(_session, null, port); - - if(this.config == null){ - if(_session.getLogger().isEnabled(Logger.ERROR)){ - _session.getLogger().log(Logger.ERROR, - "ChannelForwardedTCPIP: "+Util.byte2str(addr)+":"+port+" is not registered."); - } - } - } - - private static Config getPort(Session session, String address_to_bind, int rport){ - synchronized(pool){ - for(int i=0; i foo = new Vector<>(); - synchronized(pool){ - for(int i=0; i env=null; - - protected boolean pty=false; - - protected String ttype="vt100"; - protected int tcol=80; - protected int trow=24; - protected int twp=640; - protected int thp=480; - protected byte[] terminal_mode=null; - - ChannelSession(){ - super(); - type=_session; - io=new IO(); - } - - /** - * Enable the agent forwarding. - * - * @param enable - */ - public void setAgentForwarding(boolean enable){ - agent_forwarding=enable; - } - - /** - * Enable the X11 forwarding. - * Refer to RFC4254 6.3.1. Requesting X11 Forwarding. - * - * @param enable - */ - @Override - public void setXForwarding(boolean enable){ - xforwading=enable; - } - - /** - * @deprecated Use #setEnv(String, String) or #setEnv(byte[], byte[]) instead. - * @see #setEnv(String, String) - * @see #setEnv(byte[], byte[]) - */ - @Deprecated - public void setEnv(Hashtable env){ - synchronized(this){ - this.env=env; - } - } - - /** - * Set the environment variable. - * If name and value are needed to be passed - * to the remote in your favorite encoding, - * use {@link #setEnv(byte[], byte[])}. - * Refer to RFC4254 6.4 Environment Variable Passing. - * - * @param name A name for environment variable. - * @param value A value for environment variable. - */ - public void setEnv(String name, String value){ - setEnv(Util.str2byte(name), Util.str2byte(value)); - } - - /** - * Set the environment variable. - * Refer to RFC4254 6.4 Environment Variable Passing. - * - * @param name A name of environment variable. - * @param value A value of environment variable. - * @see #setEnv(String, String) - */ - public void setEnv(byte[] name, byte[] value){ - synchronized(this){ - getEnv().put(name, value); - } - } - - private Hashtable getEnv(){ - if(env==null) - env=new Hashtable<>(); - return env; - } - - /** - * Allocate a Pseudo-Terminal. - * Refer to RFC4254 6.2. Requesting a Pseudo-Terminal. - * - * @param enable - */ - public void setPty(boolean enable){ - pty=enable; - } - - /** - * Set the terminal mode. - * - * @param terminal_mode - */ - public void setTerminalMode(byte[] terminal_mode){ - this.terminal_mode=terminal_mode; - } - - /** - * Change the window dimension interactively. - * Refer to RFC4254 6.7. Window Dimension Change Message. - * - * @param col terminal width, columns - * @param row terminal height, rows - * @param wp terminal width, pixels - * @param hp terminal height, pixels - */ - public void setPtySize(int col, int row, int wp, int hp){ - setPtyType(this.ttype, col, row, wp, hp); - if(!pty || !isConnected()){ - return; - } - try{ - RequestWindowChange request=new RequestWindowChange(); - request.setSize(col, row, wp, hp); - request.request(getSession(), this); - } - catch(Exception e){ - //System.err.println("ChannelSessio.setPtySize: "+e); - } - } - - /** - * Set the terminal type. - * This method is not effective after Channel#connect(). - * - * @param ttype terminal type(for example, "vt100") - * @see #setPtyType(String, int, int, int, int) - */ - public void setPtyType(String ttype){ - setPtyType(ttype, 80, 24, 640, 480); - } - - /** - * Set the terminal type. - * This method is not effective after Channel#connect(). - * - * @param ttype terminal type(for example, "vt100") - * @param col terminal width, columns - * @param row terminal height, rows - * @param wp terminal width, pixels - * @param hp terminal height, pixels - */ - public void setPtyType(String ttype, int col, int row, int wp, int hp){ - this.ttype=ttype; - this.tcol=col; - this.trow=row; - this.twp=wp; - this.thp=hp; - } - - protected void sendRequests() throws Exception{ - Session _session=getSession(); - Request request; - if(agent_forwarding){ - request=new RequestAgentForwarding(); - request.request(_session, this); - } - - if(xforwading){ - request=new RequestX11(); - request.request(_session, this); - } - - if(pty){ - request=new RequestPtyReq(); - ((RequestPtyReq)request).setTType(ttype); - ((RequestPtyReq)request).setTSize(tcol, trow, twp, thp); - if(terminal_mode!=null){ - ((RequestPtyReq)request).setTerminalMode(terminal_mode); - } - request.request(_session, this); - } - - if(env!=null){ - for(Enumeration _env=env.keys(); _env.hasMoreElements();){ - byte[] name=_env.nextElement(); - byte[] value=env.get(name); - request=new RequestEnv(); - ((RequestEnv)request).setEnv(toByteArray(name), - toByteArray(value)); - request.request(_session, this); - } - } - } - - private byte[] toByteArray(Object o){ - if(o instanceof String){ - return Util.str2byte((String)o); - } - return (byte[])o; - } - - @Override - void run(){ - //System.err.println(this+":run >"); - - Buffer buf=new Buffer(rmpsize); - Packet packet=new Packet(buf); - int i=-1; - try{ - while(isConnected() && - thread!=null && - io!=null && - io.in!=null){ - i=io.in.read(buf.buffer, - 14, - buf.buffer.length-14 - -Session.buffer_margin - ); - if(i==0)continue; - if(i==-1){ - eof(); - break; - } - if(close)break; - //System.out.println("write: "+i); - packet.reset(); - buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA); - buf.putInt(recipient); - buf.putInt(i); - buf.skip(i); - getSession().write(packet, this, i); - } - } - catch(Exception e){ - //System.err.println("# ChannelExec.run"); - //e.printStackTrace(); - } - Thread _thread=thread; - if(_thread!=null){ - synchronized(_thread){ _thread.notifyAll(); } - } - thread=null; - //System.err.println(this+":run <"); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSftp.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSftp.java deleted file mode 100644 index 0157752a..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSftp.java +++ /dev/null @@ -1,3009 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.io.*; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.Hashtable; -import java.util.Vector; - -public class ChannelSftp extends ChannelSession{ - - static private final int LOCAL_MAXIMUM_PACKET_SIZE=32*1024; - static private final int LOCAL_WINDOW_SIZE_MAX=(64*LOCAL_MAXIMUM_PACKET_SIZE); - - private static final byte SSH_FXP_INIT= 1; - private static final byte SSH_FXP_VERSION= 2; - private static final byte SSH_FXP_OPEN= 3; - private static final byte SSH_FXP_CLOSE= 4; - private static final byte SSH_FXP_READ= 5; - private static final byte SSH_FXP_WRITE= 6; - private static final byte SSH_FXP_LSTAT= 7; - private static final byte SSH_FXP_FSTAT= 8; - private static final byte SSH_FXP_SETSTAT= 9; - private static final byte SSH_FXP_FSETSTAT= 10; - private static final byte SSH_FXP_OPENDIR= 11; - private static final byte SSH_FXP_READDIR= 12; - private static final byte SSH_FXP_REMOVE= 13; - private static final byte SSH_FXP_MKDIR= 14; - private static final byte SSH_FXP_RMDIR= 15; - private static final byte SSH_FXP_REALPATH= 16; - private static final byte SSH_FXP_STAT= 17; - private static final byte SSH_FXP_RENAME= 18; - private static final byte SSH_FXP_READLINK= 19; - private static final byte SSH_FXP_SYMLINK= 20; - private static final byte SSH_FXP_STATUS= 101; - private static final byte SSH_FXP_HANDLE= 102; - private static final byte SSH_FXP_DATA= 103; - private static final byte SSH_FXP_NAME= 104; - private static final byte SSH_FXP_ATTRS= 105; - private static final byte SSH_FXP_EXTENDED= (byte)200; - private static final byte SSH_FXP_EXTENDED_REPLY= (byte)201; - - // pflags - private static final int SSH_FXF_READ= 0x00000001; - private static final int SSH_FXF_WRITE= 0x00000002; - private static final int SSH_FXF_APPEND= 0x00000004; - private static final int SSH_FXF_CREAT= 0x00000008; - private static final int SSH_FXF_TRUNC= 0x00000010; - private static final int SSH_FXF_EXCL= 0x00000020; - - private static final int SSH_FILEXFER_ATTR_SIZE= 0x00000001; - private static final int SSH_FILEXFER_ATTR_UIDGID= 0x00000002; - private static final int SSH_FILEXFER_ATTR_PERMISSIONS= 0x00000004; - private static final int SSH_FILEXFER_ATTR_ACMODTIME= 0x00000008; - private static final int SSH_FILEXFER_ATTR_EXTENDED= 0x80000000; - - public static final int SSH_FX_OK= 0; - public static final int SSH_FX_EOF= 1; - public static final int SSH_FX_NO_SUCH_FILE= 2; - public static final int SSH_FX_PERMISSION_DENIED= 3; - public static final int SSH_FX_FAILURE= 4; - public static final int SSH_FX_BAD_MESSAGE= 5; - public static final int SSH_FX_NO_CONNECTION= 6; - public static final int SSH_FX_CONNECTION_LOST= 7; - public static final int SSH_FX_OP_UNSUPPORTED= 8; -/* - SSH_FX_OK - Indicates successful completion of the operation. - SSH_FX_EOF - indicates end-of-file condition; for SSH_FX_READ it means that no - more data is available in the file, and for SSH_FX_READDIR it - indicates that no more files are contained in the directory. - SSH_FX_NO_SUCH_FILE - is returned when a reference is made to a file which should exist - but doesn't. - SSH_FX_PERMISSION_DENIED - is returned when the authenticated user does not have sufficient - permissions to perform the operation. - SSH_FX_FAILURE - is a generic catch-all error message; it should be returned if an - error occurs for which there is no more specific error code - defined. - SSH_FX_BAD_MESSAGE - may be returned if a badly formatted packet or protocol - incompatibility is detected. - SSH_FX_NO_CONNECTION - is a pseudo-error which indicates that the client has no - connection to the server (it can only be generated locally by the - client, and MUST NOT be returned by servers). - SSH_FX_CONNECTION_LOST - is a pseudo-error which indicates that the connection to the - server has been lost (it can only be generated locally by the - client, and MUST NOT be returned by servers). - SSH_FX_OP_UNSUPPORTED - indicates that an attempt was made to perform an operation which - is not supported for the server (it may be generated locally by - the client if e.g. the version number exchange indicates that a - required feature is not supported by the server, or it may be - returned by the server if the server does not implement an - operation). -*/ - private static final int MAX_MSG_LENGTH = 256* 1024; - - public static final int OVERWRITE=0; - public static final int RESUME=1; - public static final int APPEND=2; - - private boolean interactive=false; - private int seq=1; - private int[] ackid=new int[1]; - - private Buffer buf; - private Packet packet; - - // The followings will be used in file uploading. - private Buffer obuf; - private Packet opacket; - - private int client_version=3; - private int server_version=3; - private String version=String.valueOf(client_version); - - private Hashtable extensions=null; - private InputStream io_in=null; - - private boolean extension_posix_rename = false; - private boolean extension_statvfs = false; - // private boolean extension_fstatvfs = false; - private boolean extension_hardlink = false; - -/* -10. Changes from previous protocol versions - The SSH File Transfer Protocol has changed over time, before it's - standardization. The following is a description of the incompatible - changes between different versions. -10.1 Changes between versions 3 and 2 - o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added. - o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were added. - o The SSH_FXP_STATUS message was changed to include fields `error - message' and `language tag'. -10.2 Changes between versions 2 and 1 - o The SSH_FXP_RENAME message was added. -10.3 Changes between versions 1 and 0 - o Implementation changes, no actual protocol changes. -*/ - - private static final String file_separator=File.separator; - private static final char file_separatorc=File.separatorChar; - private static boolean fs_is_bs=(byte)File.separatorChar == '\\'; - - private String cwd; - private String home; - private String lcwd; - - private Charset fEncoding=StandardCharsets.UTF_8; - private boolean fEncoding_is_utf8=true; - - private RequestQueue rq = new RequestQueue(16); - - /** - * Specify how many requests may be sent at any one time. - * Increasing this value may slightly improve file transfer speed but will - * increase memory usage. The default is 16 requests. - * - * @param bulk_requests how many requests may be outstanding at any one time. - */ - public void setBulkRequests(int bulk_requests) throws JSchException { - if(bulk_requests>0) - rq = new RequestQueue(bulk_requests); - else - throw new JSchException("setBulkRequests: "+ - bulk_requests+" must be greater than 0."); - } - - /** - * This method will return the value how many requests may be - * sent at any one time. - * - * @return how many requests may be sent at any one time. - */ - public int getBulkRequests(){ - return rq.size(); - } - - public ChannelSftp(){ - super(); - setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX); - setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX); - setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE); - } - - @Override - void init(){ - } - - @Override - public void start() throws JSchException{ - try{ - - PipedOutputStream pos=new PipedOutputStream(); - io.setOutputStream(pos); - PipedInputStream pis=new MyPipedInputStream(pos, rq.size()*rmpsize); - io.setInputStream(pis); - - io_in=io.in; - - if(io_in==null){ - throw new JSchException("channel is down"); - } - - Request request=new RequestSftp(); - request.request(getSession(), this); - - /* - System.err.println("lmpsize: "+lmpsize); - System.err.println("lwsize: "+lwsize); - System.err.println("rmpsize: "+rmpsize); - System.err.println("rwsize: "+rwsize); - */ - - buf=new Buffer(lmpsize); - packet=new Packet(buf); - - obuf=new Buffer(rmpsize); - opacket=new Packet(obuf); - - int i=0; - int length; - int type; - byte[] str; - - // send SSH_FXP_INIT - sendINIT(); - - // receive SSH_FXP_VERSION - Header header=new Header(); - header=header(buf, header); - length=header.length; - if(length > MAX_MSG_LENGTH){ - throw new SftpException(SSH_FX_FAILURE, - "Received message is too long: " + length); - } - type=header.type; // 2 -> SSH_FXP_VERSION - server_version=header.rid; - //System.err.println("SFTP protocol server-version="+server_version); - extensions=new Hashtable<>(); - if(length>0){ - // extension data - fill(buf, length); - byte[] extension_name=null; - byte[] extension_data=null; - while(length>0){ - extension_name=buf.getString(); - length-=(4+extension_name.length); - extension_data=buf.getString(); - length-=(4+extension_data.length); - extensions.put(Util.byte2str(extension_name), - Util.byte2str(extension_data)); - } - } - - if(extensions.get("posix-rename@openssh.com")!=null && - extensions.get("posix-rename@openssh.com").equals("1")){ - extension_posix_rename = true; - } - - if(extensions.get("statvfs@openssh.com")!=null && - extensions.get("statvfs@openssh.com").equals("2")){ - extension_statvfs = true; - } - - /* - if(extensions.get("fstatvfs@openssh.com")!=null && - extensions.get("fstatvfs@openssh.com").equals("2")){ - extension_fstatvfs = true; - } - */ - - if(extensions.get("hardlink@openssh.com")!=null && - extensions.get("hardlink@openssh.com").equals("1")){ - extension_hardlink = true; - } - - lcwd=new File(".").getCanonicalPath(); - } - catch(Exception e){ - //System.err.println(e); - if(e instanceof JSchException) throw (JSchException)e; - throw new JSchException(e.toString(), e); - } - } - - public void quit(){ disconnect();} - public void exit(){ disconnect();} - public void lcd(String path) throws SftpException{ - path=localAbsolutePath(path); - if((new File(path)).isDirectory()){ - try{ - path=(new File(path)).getCanonicalPath(); - } - catch(Exception e){} - lcwd=path; - return; - } - throw new SftpException(SSH_FX_NO_SUCH_FILE, "No such directory"); - } - - public void cd(String path) throws SftpException{ - try{ - ((MyPipedInputStream)io_in).updateReadSide(); - - path=remoteAbsolutePath(path); - path=isUnique(path); - - byte[] str=_realpath(path); - SftpATTRS attr=_stat(str); - - if((attr.getFlags()&SftpATTRS.SSH_FILEXFER_ATTR_PERMISSIONS)==0){ - throw new SftpException(SSH_FX_FAILURE, - "Can't change directory: "+path); - } - if(!attr.isDir()){ - throw new SftpException(SSH_FX_FAILURE, - "Can't change directory: "+path); - } - - setCwd(Util.byte2str(str, fEncoding)); - } - catch(Exception e){ - if(e instanceof SftpException) throw (SftpException)e; - throw new SftpException(SSH_FX_FAILURE, e.toString(), e); - } - } - - public void put(String src, String dst) throws SftpException{ - put(src, dst, null, OVERWRITE); - } - public void put(String src, String dst, int mode) throws SftpException{ - put(src, dst, null, mode); - } - public void put(String src, String dst, - SftpProgressMonitor monitor) throws SftpException{ - put(src, dst, monitor, OVERWRITE); - } - - /** - * Sends data from src file to dst file. - * The mode should be OVERWRITE, - * RESUME or APPEND. - * - * @param src source file - * @param dst destination file - * @param monitor progress monitor - * @param mode how data should be added to dst - */ - public void put(String src, String dst, - SftpProgressMonitor monitor, int mode) throws SftpException{ - - try{ - ((MyPipedInputStream)io_in).updateReadSide(); - - src=localAbsolutePath(src); - dst=remoteAbsolutePath(dst); - - Vector v=glob_remote(dst); - int vsize=v.size(); - if(vsize!=1){ - if(vsize==0){ - if(isPattern(dst)) - throw new SftpException(SSH_FX_FAILURE, dst); - else - dst=Util.unquote(dst); - } - throw new SftpException(SSH_FX_FAILURE, v.toString()); - } - else{ - dst=v.elementAt(0); - } - - boolean isRemoteDir=isRemoteDir(dst); - - v=glob_local(src); - vsize=v.size(); - - StringBuilder dstsb=null; - if(isRemoteDir){ - if(!dst.endsWith("/")){ - dst+="/"; - } - dstsb=new StringBuilder(dst); - } - else if(vsize>1){ - throw new SftpException(SSH_FX_FAILURE, - "Copying multiple files, but the destination is missing or a file."); - } - - for(int j=0; ji) - i=ii; - } - if(i==-1) dstsb.append(_src); - else dstsb.append(_src.substring(i + 1)); - _dst=dstsb.toString(); - dstsb.delete(dst.length(), _dst.length()); - } - else{ - _dst=dst; - } - //System.err.println("_dst "+_dst); - - long size_of_dst=0; - if(mode==RESUME){ - try{ - SftpATTRS attr=_stat(_dst); - size_of_dst=attr.getSize(); - } - catch(Exception eee){ - //System.err.println(eee); - } - long size_of_src=new File(_src).length(); - if(size_of_srcsrc to dst file. - * The mode should be OVERWRITE, - * RESUME or APPEND. - * - * @param src input stream - * @param dst destination file - * @param monitor progress monitor - * @param mode how data should be added to dst - */ - public void put(InputStream src, String dst, - SftpProgressMonitor monitor, int mode) throws SftpException{ - try{ - ((MyPipedInputStream)io_in).updateReadSide(); - - dst=remoteAbsolutePath(dst); - - Vector v=glob_remote(dst); - int vsize=v.size(); - if(vsize!=1){ - if(vsize==0){ - if(isPattern(dst)) - throw new SftpException(SSH_FX_FAILURE, dst); - else - dst=Util.unquote(dst); - } - throw new SftpException(SSH_FX_FAILURE, v.toString()); - } - else{ - dst=v.elementAt(0); - } - - if(monitor!=null){ - monitor.init(SftpProgressMonitor.PUT, - "-", dst, - SftpProgressMonitor.UNKNOWN_SIZE); - } - - _put(src, dst, monitor, mode); - } - catch(Exception e){ - if(e instanceof SftpException) { - if(((SftpException)e).id == SSH_FX_FAILURE && - isRemoteDir(dst)) { - throw new SftpException(SSH_FX_FAILURE, dst+" is a directory"); - } - throw (SftpException)e; - } - throw new SftpException(SSH_FX_FAILURE, e.toString(), e); - } - } - - public void _put(InputStream src, String dst, - SftpProgressMonitor monitor, int mode) throws SftpException{ - try{ - ((MyPipedInputStream)io_in).updateReadSide(); - - byte[] dstb=Util.str2byte(dst, fEncoding); - long skip=0; - if(mode==RESUME || mode==APPEND){ - try{ - SftpATTRS attr=_stat(dstb); - skip=attr.getSize(); - } - catch(Exception eee){ - //System.err.println(eee); - } - } - if(mode==RESUME && skip>0){ - long skipped=src.skip(skip); - if(skipped0){ - int sent=sendWRITE(handle, _offset[0], d, s, _len); - writecount++; - _offset[0]+=sent; - s+=sent; - _len-=sent; - if((seq-1)==startid || - io_in.available()>=1024){ - while(io_in.available()>0){ - if(checkStatus(ackid, header)){ - _ackid=ackid[0]; - if(startid>_ackid || _ackid>seq-1){ - throw new SftpException(SSH_FX_FAILURE, ""); - } - ackcount++; - } - else{ - break; - } - } - } - } - if(monitor!=null && !monitor.count(len)){ - close(); - throw new IOException("canceled"); - } - } - catch(IOException e){ throw e; } - catch(Exception e){ throw new IOException(e.toString(), e); } - } - - byte[] _data=new byte[1]; - @Override - public void write(int foo) throws IOException{ - _data[0]=(byte)foo; - write(_data, 0, 1); - } - - @Override - public void flush() throws IOException{ - - if(isClosed){ - throw new IOException("stream already closed"); - } - - if(!init){ - try{ - while(writecount>ackcount){ - if(!checkStatus(null, header)){ - break; - } - ackcount++; - } - } - catch(SftpException e){ - throw new IOException(e.toString(), e); - } - } - } - - @Override - public void close() throws IOException{ - if(isClosed){ - return; - } - flush(); - if(monitor!=null)monitor.end(); - try{ _sendCLOSE(handle, header); } - catch(IOException e){ throw e; } - catch(Exception e){ - throw new IOException(e.toString(), e); - } - isClosed=true; - } - }; - return out; - } - catch(Exception e){ - if(e instanceof SftpException) throw (SftpException)e; - throw new SftpException(SSH_FX_FAILURE, e.toString(), e); - } - } - - public void get(String src, String dst) throws SftpException{ - get(src, dst, null, OVERWRITE); - } - public void get(String src, String dst, - SftpProgressMonitor monitor) throws SftpException{ - get(src, dst, monitor, OVERWRITE); - } - public void get(String src, String dst, - SftpProgressMonitor monitor, int mode) throws SftpException{ - // System.out.println("get: "+src+" "+dst); - - boolean _dstExist = false; - String _dst=null; - try{ - ((MyPipedInputStream)io_in).updateReadSide(); - - src=remoteAbsolutePath(src); - dst=localAbsolutePath(dst); - - Vector v=glob_remote(src); - int vsize=v.size(); - if(vsize==0){ - throw new SftpException(SSH_FX_NO_SUCH_FILE, "No such file"); - } - - File dstFile=new File(dst); - boolean isDstDir=dstFile.isDirectory(); - StringBuilder dstsb=null; - if(isDstDir){ - if(!dst.endsWith(file_separator)){ - dst+=file_separator; - } - dstsb=new StringBuilder(dst); - } - else if(vsize>1){ - throw new SftpException(SSH_FX_FAILURE, - "Copying multiple files, but destination is missing or a file."); - } - - for(int j=0; jdstc.length() && - _dstc.substring(0, dstc.length()+1).equals(dstc+file_separator))){ - throw new SftpException(SSH_FX_FAILURE, - "writing to an unexpected file "+_src); - } - } - dstsb.delete(dst.length(), _dst.length()); - } - else{ - _dst=dst; - } - - File _dstFile=new File(_dst); - if(mode==RESUME){ - long size_of_src=attr.getSize(); - long size_of_dst=_dstFile.length(); - if(size_of_dst>size_of_src){ - throw new SftpException(SSH_FX_FAILURE, - "failed to resume for "+_dst); - } - if(size_of_dst==size_of_src){ - return; - } - } - - if(monitor!=null){ - monitor.init(SftpProgressMonitor.GET, _src, _dst, attr.getSize()); - if(mode==RESUME){ - monitor.count(_dstFile.length()); - } - } - - FileOutputStream fos=null; - _dstExist = _dstFile.exists(); - try{ - if(mode==OVERWRITE){ - fos=new FileOutputStream(_dst); - } - else{ - fos=new FileOutputStream(_dst, true); // append - } - // System.err.println("_get: "+_src+", "+_dst); - _get(_src, fos, monitor, mode, new File(_dst).length()); - } - finally{ - if(fos!=null){ - fos.close(); - } - } - } - } - catch(Exception e){ - if(!_dstExist && _dst!=null){ - File _dstFile = new File(_dst); - if(_dstFile.exists() && _dstFile.length()==0){ - _dstFile.delete(); - } - } - if(e instanceof SftpException) throw (SftpException)e; - throw new SftpException(SSH_FX_FAILURE, e.toString(), e); - } - } - public void get(String src, OutputStream dst) throws SftpException{ - get(src, dst, null, OVERWRITE, 0); - } - public void get(String src, OutputStream dst, - SftpProgressMonitor monitor) throws SftpException{ - get(src, dst, monitor, OVERWRITE, 0); - } - public void get(String src, OutputStream dst, - SftpProgressMonitor monitor, int mode, long skip) throws SftpException{ -//System.err.println("get: "+src+", "+dst); - try{ - ((MyPipedInputStream)io_in).updateReadSide(); - - src=remoteAbsolutePath(src); - src=isUnique(src); - - if(monitor!=null){ - SftpATTRS attr=_stat(src); - monitor.init(SftpProgressMonitor.GET, src, "??", attr.getSize()); - if(mode==RESUME){ - monitor.count(skip); - } - } - _get(src, dst, monitor, mode, skip); - } - catch(Exception e){ - if(e instanceof SftpException) throw (SftpException)e; - throw new SftpException(SSH_FX_FAILURE, e.toString(), e); - } - } - - private void _get(String src, OutputStream dst, - SftpProgressMonitor monitor, int mode, long skip) throws SftpException{ - //System.err.println("_get: "+src+", "+dst); - - byte[] srcb=Util.str2byte(src, fEncoding); - try{ - sendOPENR(srcb); - - Header header=new Header(); - header=header(buf, header); - int length=header.length; - int type=header.type; - - fill(buf, length); - - if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){ - throw new SftpException(SSH_FX_FAILURE, ""); - } - - if(type==SSH_FXP_STATUS){ - int i=buf.getInt(); - throwStatusError(buf, i); - } - - byte[] handle=buf.getString(); // filename - - long offset=0; - if(mode==RESUME){ - offset+=skip; - } - - int request_max=1; - rq.init(); - long request_offset=offset; - - int request_len = buf.buffer.length-13; - if(server_version==0){ request_len=1024; } - - loop: - while(true){ - - while(rq.count() < request_max){ - sendREAD(handle, request_offset, request_len, rq); - request_offset += request_len; - } - - header=header(buf, header); - length=header.length; - type=header.type; - - RequestQueue.Request rr = null; - try{ - rr = rq.get(header.rid); - } - catch(RequestQueue.OutOfOrderException e){ - request_offset = e.offset; - skip(header.length); - rq.cancel(header, buf); - continue; - } - - if(type==SSH_FXP_STATUS){ - fill(buf, length); - int i=buf.getInt(); - if(i==SSH_FX_EOF){ - break loop; - } - throwStatusError(buf, i); - } - - if(type!=SSH_FXP_DATA){ - break loop; - } - - buf.rewind(); - fill(buf.buffer, 0, 4); length-=4; - int length_of_data = buf.getInt(); // length of data - - /** - Since sftp protocol version 6, "end-of-file" has been defined, - - byte SSH_FXP_DATA - uint32 request-id - string data - bool end-of-file [optional] - - but some sftpd server will send such a field in the sftp protocol 3 ;-( - */ - int optional_data = length - length_of_data; - - int foo = length_of_data; - while(foo>0){ - int bar=foo; - if(bar>buf.buffer.length){ - bar=buf.buffer.length; - } - int data_len = io_in.read(buf.buffer, 0, bar); - if(data_len<0){ - break loop; - } - - dst.write(buf.buffer, 0, data_len); - - offset+=data_len; - foo-=data_len; - - if(monitor!=null){ - if(!monitor.count(data_len)){ - skip(foo); - if(optional_data>0){ - skip(optional_data); - } - break loop; - } - } - - } - //System.err.println("length: "+length); // length should be 0 - - if(optional_data>0){ - skip(optional_data); - } - - if(length_of_data=rrq.length) tail -= rrq.length; - rrq[tail].id=id; - rrq[tail].offset=offset; - rrq[tail].length=length; - count++; - } - - Request get(int id) throws OutOfOrderException, SftpException { - count -= 1; - int i = head; - head++; - if(head==rrq.length) head=0; - if(rrq[i].id != id){ - long offset = getOffset(); - boolean find = false; - for(int j = 0; jrrq[i].offset) - result=rrq[i].offset; - } - - return result; - } - } - - public InputStream get(String src) throws SftpException{ - return get(src, null, 0L); - } - public InputStream get(String src, SftpProgressMonitor monitor) throws SftpException{ - return get(src, monitor, 0L); - } - - /** - * @deprecated This method will be deleted in the future. - */ - @Deprecated - public InputStream get(String src, int mode) throws SftpException{ - return get(src, null, 0L); - } - /** - * @deprecated This method will be deleted in the future. - */ - @Deprecated - public InputStream get(String src, final SftpProgressMonitor monitor, final int mode) throws SftpException{ - return get(src, monitor, 0L); - } - public InputStream get(String src, final SftpProgressMonitor monitor, final long skip) throws SftpException{ - - try{ - ((MyPipedInputStream)io_in).updateReadSide(); - - src=remoteAbsolutePath(src); - src=isUnique(src); - - byte[] srcb=Util.str2byte(src, fEncoding); - - SftpATTRS attr=_stat(srcb); - if(monitor!=null){ - monitor.init(SftpProgressMonitor.GET, src, "??", attr.getSize()); - } - - sendOPENR(srcb); - - Header header=new Header(); - header=header(buf, header); - int length=header.length; - int type=header.type; - - fill(buf, length); - - if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){ - throw new SftpException(SSH_FX_FAILURE, ""); - } - if(type==SSH_FXP_STATUS){ - int i=buf.getInt(); - throwStatusError(buf, i); - } - - final byte[] handle=buf.getString(); // handle - - rq.init(); - - InputStream in=new InputStream(){ - long offset=skip; - boolean closed=false; - int rest_length=0; - byte[] _data=new byte[1]; - byte[] rest_byte=new byte[1024]; - Header header=new Header(); - int request_max=1; - long request_offset=offset; - - @Override - public int read() throws IOException{ - if(closed)return -1; - int i=read(_data, 0, 1); - if (i==-1) { return -1; } - else { - return _data[0]&0xff; - } - } - @Override - public int read(byte[] d) throws IOException{ - if(closed)return -1; - return read(d, 0, d.length); - } - @Override - public int read(byte[] d, int s, int len) throws IOException{ - if(closed)return -1; - if(d==null){throw new NullPointerException();} - if(s<0 || len <0 || s+len>d.length){ - throw new IndexOutOfBoundsException(); - } - if(len==0){ return 0; } - - if(rest_length>0){ - int foo=rest_length; - if(foo>len) foo=len; - System.arraycopy(rest_byte, 0, d, s, foo); - if(foo!=rest_length){ - System.arraycopy(rest_byte, foo, - rest_byte, 0, rest_length-foo); - } - - if(monitor!=null){ - if(!monitor.count(foo)){ - close(); - return -1; - } - } - - rest_length-=foo; - return foo; - } - - if(buf.buffer.length-131024){ - len=1024; - } - - if(rq.count()==0 - || true // working around slow transfer speed for - // some sftp servers including Titan FTP. - ) { - int request_len = buf.buffer.length-13; - if(server_version==0){ request_len=1024; } - - while(rq.count() < request_max){ - try{ - sendREAD(handle, request_offset, request_len, rq); - } - catch(Exception e){ throw new IOException("error"); } - request_offset += request_len; - } - } - - header=header(buf, header); - rest_length=header.length; - int type=header.type; - int id=header.rid; - - RequestQueue.Request rr = null; - try{ - rr = rq.get(header.rid); - } - catch(RequestQueue.OutOfOrderException e){ - request_offset = e.offset; - skip(header.length); - rq.cancel(header, buf); - return 0; - } - catch(SftpException e){ - throw new IOException("error: "+e.toString(), e); - } - - if(type!=SSH_FXP_STATUS && type!=SSH_FXP_DATA){ - throw new IOException("error"); - } - if(type==SSH_FXP_STATUS){ - fill(buf, rest_length); - int i=buf.getInt(); - rest_length=0; - if(i==SSH_FX_EOF){ - close(); - return -1; - } - //throwStatusError(buf, i); - throw new IOException("error"); - } - - buf.rewind(); - fill(buf.buffer, 0, 4); - int length_of_data = buf.getInt(); rest_length-=4; - - /** - Since sftp protocol version 6, "end-of-file" has been defined, - - byte SSH_FXP_DATA - uint32 request-id - string data - bool end-of-file [optional] - - but some sftpd server will send such a field in the sftp protocol 3 ;-( - */ - int optional_data = rest_length - length_of_data; - - offset += length_of_data; - int foo = length_of_data; - if(foo>0){ - int bar=foo; - if(bar>len){ - bar=len; - } - int i=io_in.read(d, s, bar); - if(i<0){ - return -1; - } - foo-=i; - rest_length=foo; - - if(foo>0){ - if(rest_byte.length0){ - j=io_in.read(rest_byte, _s, _len); - if(j<=0)break; - _s+=j; - _len-=j; - } - } - - if(optional_data>0){ - io_in.skip(optional_data); - } - - if(length_of_data ls(String path) throws SftpException{ - final Vector v = new Vector<>(); - LsEntrySelector selector = new LsEntrySelector(){ - @Override - public int select(LsEntry entry){ - v.addElement(entry); - return CONTINUE; - } - }; - ls(path, selector); - return v; - } - - /** - * List files specified by the remote path. - * Each files and directories will be passed to - * LsEntrySelector#select(LsEntry) method, and if that method - * returns LsEntrySelector#BREAK, the operation will be - * canceled immediately. - * - * @see ChannelSftp.LsEntrySelector - * @since 0.1.47 - */ - public void ls(String path, LsEntrySelector selector) throws SftpException{ - //System.out.println("ls: "+path); - try{ - ((MyPipedInputStream)io_in).updateReadSide(); - - path=remoteAbsolutePath(path); - byte[] pattern=null; - Vector v=new Vector<>(); - - int foo=path.lastIndexOf('/'); - String dir=path.substring(0, ((foo==0)?1:foo)); - String _pattern=path.substring(foo+1); - dir=Util.unquote(dir); - - // If pattern has included '*' or '?', we need to convert - // to UTF-8 string before globbing. - byte[][] _pattern_utf8=new byte[1][]; - boolean pattern_has_wildcard=isPattern(_pattern, _pattern_utf8); - - if(pattern_has_wildcard){ - pattern=_pattern_utf8[0]; - } - else{ - String upath=Util.unquote(path); - //SftpATTRS attr=_lstat(upath); - SftpATTRS attr=_stat(upath); - if(attr.isDir()){ - pattern=null; - dir=upath; - } - else{ - /* - // If we can generage longname by ourself, - // we don't have to use openDIR. - String filename=Util.unquote(_pattern); - String longname=... - v.addElement(new LsEntry(filename, longname, attr)); - return v; - */ - - if(fEncoding_is_utf8){ - pattern=_pattern_utf8[0]; - pattern=Util.unquote(pattern); - } - else{ - _pattern=Util.unquote(_pattern); - pattern=Util.str2byte(_pattern, fEncoding); - } - - } - } - - sendOPENDIR(Util.str2byte(dir, fEncoding)); - - Header header=new Header(); - header=header(buf, header); - int length=header.length; - int type=header.type; - - fill(buf, length); - - if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){ - throw new SftpException(SSH_FX_FAILURE, ""); - } - if(type==SSH_FXP_STATUS){ - int i=buf.getInt(); - throwStatusError(buf, i); - } - - int cancel = LsEntrySelector.CONTINUE; - byte[] handle=buf.getString(); // handle - - while(cancel==LsEntrySelector.CONTINUE){ - - sendREADDIR(handle); - - header=header(buf, header); - length=header.length; - type=header.type; - if(type!=SSH_FXP_STATUS && type!=SSH_FXP_NAME){ - throw new SftpException(SSH_FX_FAILURE, ""); - } - if(type==SSH_FXP_STATUS){ - fill(buf, length); - int i=buf.getInt(); - if(i==SSH_FX_EOF) - break; - throwStatusError(buf, i); - } - - buf.rewind(); - fill(buf.buffer, 0, 4); length-=4; - int count=buf.getInt(); - - byte[] str; - int flags; - - buf.reset(); - while(count>0){ - if(length>0){ - buf.shift(); - int j=(buf.buffer.length>(buf.index+length)) ? - length : - (buf.buffer.length-buf.index); - int i=fill(buf.buffer, buf.index, j); - buf.index+=i; - length-=i; - } - byte[] filename=buf.getString(); - byte[] longname=null; - if(server_version<=3){ - longname=buf.getString(); - } - SftpATTRS attrs=SftpATTRS.getATTR(buf); - - if(cancel==LsEntrySelector.BREAK){ - count--; - continue; - } - - boolean find=false; - String f=null; - if(pattern==null){ - find=true; - } - else if(!pattern_has_wildcard){ - find=Util.array_equals(pattern, filename); - } - else{ - byte[] _filename=filename; - if(!fEncoding_is_utf8){ - f=Util.byte2str(_filename, fEncoding); - _filename=Util.str2byte(f, StandardCharsets.UTF_8); - } - find=Util.glob(pattern, _filename); - } - - if(find){ - if(f==null){ - f=Util.byte2str(filename, fEncoding); - } - String l=null; - if(longname==null){ - // TODO: we need to generate long name from attrs - // for the sftp protocol 4(and later). - l=attrs.toString()+" "+f; - } - else{ - l=Util.byte2str(longname, fEncoding); - } - - cancel = selector.select(new LsEntry(f, l, attrs)); - } - - count--; - } - } - _sendCLOSE(handle, header); - - /* - if(v.size()==1 && pattern_has_wildcard){ - LsEntry le=(LsEntry)v.elementAt(0); - if(le.getAttrs().isDir()){ - String f=le.getFilename(); - if(isPattern(f)){ - f=Util.quote(f); - } - if(!dir.endsWith("/")){ - dir+="/"; - } - v=null; - return ls(dir+f); - } - } - */ - - } - catch(Exception e){ - if(e instanceof SftpException) throw (SftpException)e; - throw new SftpException(SSH_FX_FAILURE, e.toString(), e); - } - } - - public String readlink(String path) throws SftpException{ - try{ - if(server_version<3){ - throw new SftpException(SSH_FX_OP_UNSUPPORTED, - "The remote sshd is too old to support symlink operation."); - } - - ((MyPipedInputStream)io_in).updateReadSide(); - - path=remoteAbsolutePath(path); - - path=isUnique(path); - - sendREADLINK(Util.str2byte(path, fEncoding)); - - Header header=new Header(); - header=header(buf, header); - int length=header.length; - int type=header.type; - - fill(buf, length); - - if(type!=SSH_FXP_STATUS && type!=SSH_FXP_NAME){ - throw new SftpException(SSH_FX_FAILURE, ""); - } - if(type==SSH_FXP_NAME){ - int count=buf.getInt(); // count - byte[] filename=null; - for(int i=0; i v=glob_remote(newpath); - int vsize=v.size(); - if(vsize>=2){ - throw new SftpException(SSH_FX_FAILURE, v.toString()); - } - if(vsize==1){ - newpath=v.elementAt(0); - } - else{ // vsize==0 - if(isPattern(newpath)) - throw new SftpException(SSH_FX_FAILURE, newpath); - newpath=Util.unquote(newpath); - } - - sendRENAME(Util.str2byte(oldpath, fEncoding), - Util.str2byte(newpath, fEncoding)); - - Header header=new Header(); - header=header(buf, header); - int length=header.length; - int type=header.type; - - fill(buf, length); - - if(type!=SSH_FXP_STATUS){ - throw new SftpException(SSH_FX_FAILURE, ""); - } - - int i=buf.getInt(); - if(i==SSH_FX_OK) return; - throwStatusError(buf, i); - } - catch(Exception e){ - if(e instanceof SftpException) throw (SftpException)e; - throw new SftpException(SSH_FX_FAILURE, e.toString(), e); - } - } - public void rm(String path) throws SftpException{ - try{ - ((MyPipedInputStream)io_in).updateReadSide(); - - path=remoteAbsolutePath(path); - - Vector v=glob_remote(path); - int vsize=v.size(); - - Header header=new Header(); - - for(int j=0; j v=glob_remote(path); - int vsize=v.size(); - for(int j=0; j v=glob_remote(path); - int vsize=v.size(); - for(int j=0; j v=glob_remote(path); - int vsize=v.size(); - for(int j=0; j v=glob_remote(path); - int vsize=v.size(); - for(int j=0; j v=glob_remote(path); - int vsize=v.size(); - - Header header=new Header(); - - for(int j=0; j0){ - str=buf.getString(); // absolute path; - if(server_version<=3){ - byte[] lname=buf.getString(); // long filename - } - SftpATTRS attr=SftpATTRS.getATTR(buf); // dummy attribute - } - return str; - } - - public void setStat(String path, SftpATTRS attr) throws SftpException{ - try{ - ((MyPipedInputStream)io_in).updateReadSide(); - - path=remoteAbsolutePath(path); - - Vector v=glob_remote(path); - int vsize=v.size(); - for(int j=0; j0){ - i=io_in.read(buf, s, l); - if(i<=0){ - throw new SftpException(SSH_FX_FAILURE, ""); - } - s+=i; - l-=i; - } - } - - private boolean checkStatus(int[] ackid, Header header) throws IOException, SftpException{ - header=header(buf, header); - int length=header.length; - int type=header.type; - if(ackid!=null) - ackid[0]=header.rid; - - fill(buf, length); - - if(type!=SSH_FXP_STATUS){ - throw new SftpException(SSH_FX_FAILURE, ""); - } - int i=buf.getInt(); - if(i!=SSH_FX_OK){ - throwStatusError(buf, i); - } - return true; - } - private boolean _sendCLOSE(byte[] handle, Header header) throws Exception{ - sendCLOSE(handle); - return checkStatus(null, header); - } - - private void sendINIT() throws Exception{ - packet.reset(); - putHEAD(SSH_FXP_INIT, 5); - buf.putInt(3); // version 3 - getSession().write(packet, this, 5+4); - } - - private void sendREALPATH(byte[] path) throws Exception{ - sendPacketPath(SSH_FXP_REALPATH, path); - } - private void sendSTAT(byte[] path) throws Exception{ - sendPacketPath(SSH_FXP_STAT, path); - } - private void sendSTATVFS(byte[] path) throws Exception{ - sendPacketPath((byte)0, path, "statvfs@openssh.com"); - } - /* - private void sendFSTATVFS(byte[] handle) throws Exception{ - sendPacketPath((byte)0, handle, "fstatvfs@openssh.com"); - } - */ - private void sendLSTAT(byte[] path) throws Exception{ - sendPacketPath(SSH_FXP_LSTAT, path); - } - private void sendFSTAT(byte[] handle) throws Exception{ - sendPacketPath(SSH_FXP_FSTAT, handle); - } - private void sendSETSTAT(byte[] path, SftpATTRS attr) throws Exception{ - packet.reset(); - putHEAD(SSH_FXP_SETSTAT, 9+path.length+attr.length()); - buf.putInt(seq++); - buf.putString(path); // path - attr.dump(buf); - getSession().write(packet, this, 9+path.length+attr.length()+4); - } - private void sendREMOVE(byte[] path) throws Exception{ - sendPacketPath(SSH_FXP_REMOVE, path); - } - private void sendMKDIR(byte[] path, SftpATTRS attr) throws Exception{ - packet.reset(); - putHEAD(SSH_FXP_MKDIR, 9+path.length+(attr!=null?attr.length():4)); - buf.putInt(seq++); - buf.putString(path); // path - if(attr!=null) attr.dump(buf); - else buf.putInt(0); - getSession().write(packet, this, 9+path.length+(attr!=null?attr.length():4)+4); - } - private void sendRMDIR(byte[] path) throws Exception{ - sendPacketPath(SSH_FXP_RMDIR, path); - } - private void sendSYMLINK(byte[] p1, byte[] p2) throws Exception{ - sendPacketPath(SSH_FXP_SYMLINK, p1, p2); - } - private void sendHARDLINK(byte[] p1, byte[] p2) throws Exception{ - sendPacketPath((byte)0, p1, p2, "hardlink@openssh.com"); - } - private void sendREADLINK(byte[] path) throws Exception{ - sendPacketPath(SSH_FXP_READLINK, path); - } - private void sendOPENDIR(byte[] path) throws Exception{ - sendPacketPath(SSH_FXP_OPENDIR, path); - } - private void sendREADDIR(byte[] path) throws Exception{ - sendPacketPath(SSH_FXP_READDIR, path); - } - private void sendRENAME(byte[] p1, byte[] p2) throws Exception{ - sendPacketPath(SSH_FXP_RENAME, p1, p2, - extension_posix_rename ? "posix-rename@openssh.com" : null); - } - private void sendCLOSE(byte[] path) throws Exception{ - sendPacketPath(SSH_FXP_CLOSE, path); - } - private void sendOPENR(byte[] path) throws Exception{ - sendOPEN(path, SSH_FXF_READ); - } - private void sendOPENW(byte[] path) throws Exception{ - sendOPEN(path, SSH_FXF_WRITE|SSH_FXF_CREAT|SSH_FXF_TRUNC); - } - private void sendOPENA(byte[] path) throws Exception{ - sendOPEN(path, SSH_FXF_WRITE|/*SSH_FXF_APPEND|*/SSH_FXF_CREAT); - } - private void sendOPEN(byte[] path, int mode) throws Exception{ - packet.reset(); - putHEAD(SSH_FXP_OPEN, 17+path.length); - buf.putInt(seq++); - buf.putString(path); - buf.putInt(mode); - buf.putInt(0); // attrs - getSession().write(packet, this, 17+path.length+4); - } - private void sendPacketPath(byte fxp, byte[] path) throws Exception{ - sendPacketPath(fxp, path, (String)null); - } - private void sendPacketPath(byte fxp, byte[] path, String extension) throws Exception{ - packet.reset(); - int len = 9+path.length; - if(extension == null) { - putHEAD(fxp, len); - buf.putInt(seq++); - } - else { - len+=(4+extension.length()); - putHEAD(SSH_FXP_EXTENDED, len); - buf.putInt(seq++); - buf.putString(Util.str2byte(extension)); - } - buf.putString(path); // path - getSession().write(packet, this, len+4); - } - - private void sendPacketPath(byte fxp, byte[] p1, byte[] p2) throws Exception{ - sendPacketPath(fxp, p1, p2, null); - } - private void sendPacketPath(byte fxp, byte[] p1, byte[] p2, String extension) throws Exception{ - packet.reset(); - int len = 13+p1.length+p2.length; - if(extension==null){ - putHEAD(fxp, len); - buf.putInt(seq++); - } - else { - len+=(4+extension.length()); - putHEAD(SSH_FXP_EXTENDED, len); - buf.putInt(seq++); - buf.putString(Util.str2byte(extension)); - } - buf.putString(p1); - buf.putString(p2); - getSession().write(packet, this, len+4); - } - - private int sendWRITE(byte[] handle, long offset, - byte[] data, int start, int length) throws Exception{ - int _length=length; - opacket.reset(); - if(obuf.buffer.length0){ - if(length>0){ - buf.shift(); - int j=(buf.buffer.length>(buf.index+length)) ? length : (buf.buffer.length-buf.index); - i=io_in.read(buf.buffer, buf.index, j); - if(i<=0)break; - buf.index+=i; - length-=i; - } - - byte[] filename=buf.getString(); - //System.err.println("filename: "+new String(filename)); - if(server_version<=3){ - str=buf.getString(); // longname - } - SftpATTRS attrs=SftpATTRS.getATTR(buf); - - byte[] _filename=filename; - String f=null; - boolean found=false; - - if(!fEncoding_is_utf8){ - f=Util.byte2str(filename, fEncoding); - _filename=Util.str2byte(f, StandardCharsets.UTF_8); - } - found=Util.glob(pattern, _filename); - - if(found){ - if(f==null){ - f=Util.byte2str(filename, fEncoding); - } - if(pdir==null){ - pdir=dir; - if(!pdir.endsWith("/")){ - pdir+="/"; - } - } - v.addElement(pdir+f); - } - count--; - } - } - if(_sendCLOSE(handle, header)) - return v; - return null; - } - - private boolean isPattern(byte[] path){ - int length=path.length; - int i=0; - while(i glob_local(String _path) throws Exception{ -//System.err.println("glob_local: "+_path); - Vector v=new Vector<>(); - byte[] path=Util.str2byte(_path, StandardCharsets.UTF_8); - int i=path.length-1; - while(i>=0){ - if(path[i]!='*' && path[i]!='?'){ - i--; - continue; - } - if(!fs_is_bs && - i>0 && path[i-1]=='\\'){ - i--; - if(i>0 && path[i-1]=='\\'){ - i--; - i--; - continue; - } - } - break; - } - - if(i<0){ v.addElement(fs_is_bs ? _path : Util.unquote(_path)); return v;} - - while(i>=0){ - if(path[i]==file_separatorc || - (fs_is_bs && path[i]=='/')){ // On Windows, '/' is also the separator. - break; - } - i--; - } - - if(i<0){ v.addElement(fs_is_bs ? _path : Util.unquote(_path)); return v;} - - byte[] dir; - if(i==0){dir=new byte[]{(byte)file_separatorc};} - else{ - dir=new byte[i]; - System.arraycopy(path, 0, dir, 0, i); - } - - byte[] pattern=new byte[path.length-i-1]; - System.arraycopy(path, i+1, pattern, 0, pattern.length); - -//System.err.println("dir: "+new String(dir)+" pattern: "+new String(pattern)); - try{ - String[] children=(new File(Util.byte2str(dir, StandardCharsets.UTF_8))).list(); - String pdir=Util.byte2str(dir)+file_separator; - for(int j=0; j=3 && // WindRiver's sftp will send invalid - buf.getLength()>=4){ // SSH_FXP_STATUS packet. - byte[] str=buf.getString(); - //byte[] tag=buf.getString(); - throw new SftpException(i, Util.byte2str(str, StandardCharsets.UTF_8)); - } - else{ - throw new SftpException(i, "Failure"); - } - } - - private static boolean isLocalAbsolutePath(String path){ - return (new File(path)).isAbsolute(); - } - - @Override - public void disconnect(){ - super.disconnect(); - } - - private boolean isPattern(String path, byte[][] utf8){ - byte[] _path=Util.str2byte(path, StandardCharsets.UTF_8); - if(utf8!=null) - utf8[0]=_path; - return isPattern(_path); - } - - private boolean isPattern(String path){ - return isPattern(path, null); - } - - private void fill(Buffer buf, int len) throws IOException{ - buf.reset(); - fill(buf.buffer, 0, len); - buf.skip(len); - } - - private int fill(byte[] buf, int s, int len) throws IOException{ - int i=0; - int foo=s; - while(len>0){ - i=io_in.read(buf, s, len); - if(i<=0){ - throw new IOException("inputstream is closed"); - //return (s-foo)==0 ? i : s-foo; - } - s+=i; - len-=i; - } - return s-foo; - } - private void skip(long foo) throws IOException{ - while(foo>0){ - long bar=io_in.skip(foo); - if(bar<=0) - break; - foo-=bar; - } - } - - static class Header{ - int length; - int type; - int rid; - } - private Header header(Buffer buf, Header header) throws IOException{ - buf.rewind(); - int i=fill(buf.buffer, 0, 9); - header.length=buf.getInt()-5; - header.type=buf.getByte()&0xff; - header.rid=buf.getInt(); - return header; - } - - private String remoteAbsolutePath(String path) throws SftpException{ - if(path.charAt(0)=='/') return path; - String cwd=getCwd(); -// if(cwd.equals(getHome())) return path; - if(cwd.endsWith("/")) return cwd+path; - return cwd+"/"+path; - } - - private String localAbsolutePath(String path){ - if(isLocalAbsolutePath(path)) return path; - if(lcwd.endsWith(file_separator)) return lcwd+path; - return lcwd+file_separator+path; - } - - /** - * This method will check if the given string can be expanded to the - * unique string. If it can be expanded to mutiple files, SftpException - * will be thrown. - * @return the returned string is unquoted. - */ - private String isUnique(String path) throws SftpException, Exception{ - Vector v=glob_remote(path); - if(v.size()!=1){ - throw new SftpException(SSH_FX_FAILURE, path+" is not unique: "+v.toString()); - } - return v.elementAt(0); - } - - public int getServerVersion() throws SftpException{ - if(!isConnected()){ - throw new SftpException(SSH_FX_FAILURE, "The channel is not connected."); - } - return server_version; - } - - @Deprecated - public void setFilenameEncoding(String encoding) throws SftpException{ - try{ - setFilenameEncoding(Charset.forName(encoding)); - } - catch(Exception e){ - if(e instanceof SftpException) throw (SftpException)e; - throw new SftpException(SSH_FX_FAILURE, e.toString(), e); - } - } - - public void setFilenameEncoding(Charset encoding){ - fEncoding=encoding; - fEncoding_is_utf8=fEncoding.equals(StandardCharsets.UTF_8); - } - - public String getExtension(String key){ - if(extensions==null) - return null; - return extensions.get(key); - } - - public String realpath(String path) throws SftpException{ - try{ - byte[] _path=_realpath(remoteAbsolutePath(path)); - return Util.byte2str(_path, fEncoding); - } - catch(Exception e){ - if(e instanceof SftpException) throw (SftpException)e; - throw new SftpException(SSH_FX_FAILURE, e.toString(), e); - } - } - - public static class LsEntry implements Comparable{ - private String filename; - private String longname; - private SftpATTRS attrs; - LsEntry(String filename, String longname, SftpATTRS attrs){ - setFilename(filename); - setLongname(longname); - setAttrs(attrs); - } - public String getFilename(){return filename;}; - void setFilename(String filename){this.filename = filename;}; - public String getLongname(){return longname;}; - void setLongname(String longname){this.longname = longname;}; - public SftpATTRS getAttrs(){return attrs;}; - void setAttrs(SftpATTRS attrs) {this.attrs = attrs;}; - @Override - public String toString(){ return longname; } - @Override - public int compareTo(LsEntry o){ - return filename.compareTo(o.getFilename()); - } - } - - /** - * This interface will be passed as an argument for ls method. - * - * @see ChannelSftp.LsEntry - * @see #ls(String, ChannelSftp.LsEntrySelector) - * @since 0.1.47 - */ - public interface LsEntrySelector { - public final int CONTINUE = 0; - public final int BREAK = 1; - - /** - *

The select method will be invoked in ls - * method for each file entry. If this method returns BREAK, - * ls will be canceled. - * - * @param entry one of entry from ls - * @return if BREAK is returned, the 'ls' operation will be canceled. - */ - public int select(LsEntry entry); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelShell.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelShell.java deleted file mode 100644 index 2e8250d3..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelShell.java +++ /dev/null @@ -1,70 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.util.*; - -public class ChannelShell extends ChannelSession{ - - ChannelShell(){ - super(); - pty=true; - } - - @Override - public void start() throws JSchException{ - Session _session=getSession(); - try{ - sendRequests(); - - Request request=new RequestShell(); - request.request(_session, this); - } - catch(Exception e){ - if(e instanceof JSchException) throw (JSchException)e; - throw new JSchException("ChannelShell", e); - } - - if(io.in!=null){ - thread=new Thread(this::run); - thread.setName("Shell for "+_session.host); - if(_session.daemon_thread){ - thread.setDaemon(_session.daemon_thread); - } - thread.start(); - } - } - - @Override - void init() throws JSchException { - io.setInputStream(getSession().in); - io.setOutputStream(getSession().out); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSubsystem.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSubsystem.java deleted file mode 100644 index 04a4fc89..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSubsystem.java +++ /dev/null @@ -1,81 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.io.*; - -public class ChannelSubsystem extends ChannelSession{ - boolean want_reply=true; - String subsystem=""; - public void setWantReply(boolean foo){ want_reply=foo; } - public void setSubsystem(String foo){ subsystem=foo; } - @Override - public void start() throws JSchException{ - Session _session=getSession(); - try{ - Request request; - if(xforwading){ - request=new RequestX11(); - request.request(_session, this); - } - if(pty){ - request=new RequestPtyReq(); - request.request(_session, this); - } - request=new RequestSubsystem(); - ((RequestSubsystem)request).request(_session, this, subsystem, want_reply); - } - catch(Exception e){ - if(e instanceof JSchException){ throw (JSchException)e; } - throw new JSchException("ChannelSubsystem", e); - } - if(io.in!=null){ - thread=new Thread(this::run); - thread.setName("Subsystem for "+_session.host); - if(_session.daemon_thread){ - thread.setDaemon(_session.daemon_thread); - } - thread.start(); - } - } - - @Override - void init() throws JSchException { - io.setInputStream(getSession().in); - io.setOutputStream(getSession().out); - } - - public void setErrStream(OutputStream out){ - setExtOutputStream(out); - } - public InputStream getErrStream() throws IOException { - return getExtInputStream(); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelX11.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelX11.java deleted file mode 100644 index 2f211fb2..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelX11.java +++ /dev/null @@ -1,277 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.io.IOException; -import java.net.*; -import java.util.Hashtable; - -class ChannelX11 extends Channel{ - - static private final int LOCAL_WINDOW_SIZE_MAX=0x20000; - static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000; - - static private final int TIMEOUT=10*1000; - - private static String host="127.0.0.1"; - private static int port=6000; - - private boolean init=true; - - static byte[] cookie=null; - private static byte[] cookie_hex=null; - - private static Hashtable faked_cookie_pool=new Hashtable<>(); - private static Hashtable faked_cookie_hex_pool=new Hashtable<>(); - - private static byte[] table={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39, - 0x61,0x62,0x63,0x64,0x65,0x66}; - - private Socket socket = null; - - static int revtable(byte foo){ - for(int i=0; i>>4)&0xf]; - bar[2*i+1]=table[(foo[i])&0xf]; - } - faked_cookie_hex_pool.put(session, bar); - foo=bar; - } - return foo; - } - } - - static void removeFakedCookie(Session session){ - synchronized(faked_cookie_hex_pool){ - faked_cookie_hex_pool.remove(session); - faked_cookie_pool.remove(session); - } - } - - ChannelX11(){ - super(); - - setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX); - setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX); - setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE); - - type=Util.str2byte("x11"); - - connected=true; - /* - try{ - socket=Util.createSocket(host, port, TIMEOUT); - socket.setTcpNoDelay(true); - io=new IO(); - io.setInputStream(socket.getInputStream()); - io.setOutputStream(socket.getOutputStream()); - } - catch(Exception e){ - //System.err.println(e); - } - */ - } - - @Override - void run(){ - - try{ - socket=Util.createSocket(host, port, TIMEOUT); - socket.setTcpNoDelay(true); - io=new IO(); - io.setInputStream(socket.getInputStream()); - io.setOutputStream(socket.getOutputStream()); - sendOpenConfirmation(); - } - catch(Exception e){ - sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED); - close=true; - disconnect(); - return; - } - - thread=Thread.currentThread(); - Buffer buf=new Buffer(rmpsize); - Packet packet=new Packet(buf); - int i=0; - try{ - while(thread!=null && - io!=null && - io.in!=null){ - i=io.in.read(buf.buffer, - 14, - buf.buffer.length-14-Session.buffer_margin); - if(i<=0){ - eof(); - break; - } - if(close)break; - packet.reset(); - buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA); - buf.putInt(recipient); - buf.putInt(i); - buf.skip(i); - getSession().write(packet, this, i); - } - } - catch(Exception e){ - //System.err.println(e); - } - disconnect(); - } - - private byte[] cache=new byte[0]; - private byte[] addCache(byte[] foo, int s, int l){ - byte[] bar=new byte[cache.length+l]; - System.arraycopy(foo, s, bar, cache.length, l); - if(cache.length>0) - System.arraycopy(cache, 0, bar, 0, cache.length); - cache=bar; - return cache; - } - - @Override - void write(byte[] foo, int s, int l) throws IOException { - //if(eof_local)return; - - if(init){ - - Session _session=null; - try{ - _session=getSession(); - } - catch(JSchException e){ - throw new IOException(e.toString(), e); - } - - foo=addCache(foo, s, l); - s=0; - l=foo.length; - - if(l<9) - return; - - int plen=(foo[s+6]&0xff)*256+(foo[s+7]&0xff); - int dlen=(foo[s+8]&0xff)*256+(foo[s+9]&0xff); - - if((foo[s]&0xff)==0x42){ - } - else if((foo[s]&0xff)==0x6c){ - plen=((plen>>>8)&0xff)|((plen<<8)&0xff00); - dlen=((dlen>>>8)&0xff)|((dlen<<8)&0xff00); - } - else{ - // ?? - } - - if(l<12+plen+((-plen)&3)+dlen) - return; - - byte[] bar=new byte[dlen]; - System.arraycopy(foo, s+12+plen+((-plen)&3), bar, 0, dlen); - byte[] faked_cookie=null; - - synchronized(faked_cookie_pool){ - faked_cookie=faked_cookie_pool.get(_session); - } - - /* -System.err.print("faked_cookie: "); -for(int i=0; i c=Class.forName(session.getConfig(sha_name)).asSubclass(HASH.class); - sha=c.getDeclaredConstructor().newInstance(); - sha.init(); - } - catch(Exception e){ - System.err.println(e); - } - - buf=new Buffer(); - packet=new Packet(buf); - - packet.reset(); - buf.putByte((byte)SSH_MSG_KEX_ECDH_INIT); - - try{ - Class c=Class.forName(session.getConfig("ecdh-sha2-nistp")).asSubclass(ECDH.class); - ecdh=c.getDeclaredConstructor().newInstance(); - ecdh.init(key_size); - - Q_C = ecdh.getQ(); - buf.putString(Q_C); - } - catch(Exception e){ - throw new JSchException(e.toString(), e); - } - - if(V_S==null){ // This is a really ugly hack for Session.checkKexes ;-( - return; - } - - session.write(packet); - - if(session.getLogger().isEnabled(Logger.INFO)){ - session.getLogger().log(Logger.INFO, - "SSH_MSG_KEX_ECDH_INIT sent"); - session.getLogger().log(Logger.INFO, - "expecting SSH_MSG_KEX_ECDH_REPLY"); - } - - state=SSH_MSG_KEX_ECDH_REPLY; - } - - @Override - public boolean next(Buffer _buf) throws Exception{ - int i,j; - switch(state){ - case SSH_MSG_KEX_ECDH_REPLY: - // The server responds with: - // byte SSH_MSG_KEX_ECDH_REPLY - // string K_S, server's public host key - // string Q_S, server's ephemeral public key octet string - // string the signature on the exchange hash - j=_buf.getInt(); - j=_buf.getByte(); - j=_buf.getByte(); - if(j!=SSH_MSG_KEX_ECDH_REPLY){ - System.err.println("type: must be SSH_MSG_KEX_ECDH_REPLY "+j); - return false; - } - - K_S=_buf.getString(); - - byte[] Q_S=_buf.getString(); - - byte[][] r_s = KeyPairECDSA.fromPoint(Q_S); - - // RFC 5656, - // 4. ECDH Key Exchange - // All elliptic curve public keys MUST be validated after they are - // received. An example of a validation algorithm can be found in - // Section 3.2.2 of [SEC1]. If a key fails validation, - // the key exchange MUST fail. - if(!ecdh.validate(r_s[0], r_s[1])){ - return false; - } - - K = ecdh.getSecret(r_s[0], r_s[1]); - K=normalize(K); - - byte[] sig_of_H=_buf.getString(); - - //The hash H is computed as the HASH hash of the concatenation of the - //following: - // string V_C, client's identification string (CR and LF excluded) - // string V_S, server's identification string (CR and LF excluded) - // string I_C, payload of the client's SSH_MSG_KEXINIT - // string I_S, payload of the server's SSH_MSG_KEXINIT - // string K_S, server's public host key - // string Q_C, client's ephemeral public key octet string - // string Q_S, server's ephemeral public key octet string - // mpint K, shared secret - - // This value is called the exchange hash, and it is used to authenti- - // cate the key exchange. - buf.reset(); - buf.putString(V_C); buf.putString(V_S); - buf.putString(I_C); buf.putString(I_S); - buf.putString(K_S); - buf.putString(Q_C); buf.putString(Q_S); - buf.putMPInt(K); - byte[] foo=new byte[buf.getLength()]; - buf.getByte(foo); - - sha.update(foo, 0, foo.length); - H=sha.digest(); - - i=0; - j=0; - j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); - String alg=Util.byte2str(K_S, i, j); - i+=j; - - boolean result = verify(alg, K_S, i, sig_of_H); - - state=STATE_END; - return result; - } - return false; - } - - @Override - public int getState(){return state; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG1.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG1.java deleted file mode 100644 index 6d71c721..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG1.java +++ /dev/null @@ -1,61 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class DHG1 extends DHGN{ - - static final byte[] g={ 2 }; - static final byte[] p={ -(byte)0x00, -(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, -(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34, -(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1, -(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74, -(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22, -(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD, -(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B, -(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37, -(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45, -(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6, -(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B, -(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED, -(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5, -(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6, -(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE6,(byte)0x53,(byte)0x81, -(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF -}; - - @Override - byte[] G(){ return g; } - @Override - byte[] P(){ return p; } - @Override - String sha_name(){ return "sha-1"; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14.java deleted file mode 100644 index 0ddb65e8..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class DHG14 extends DHG14N{ - - @Override - String sha_name(){ return "sha-1"; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14224.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14224.java deleted file mode 100644 index 69c0d4bf..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14224.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class DHG14224 extends DHG14N{ - - @Override - String sha_name(){ return "sha-224"; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14256.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14256.java deleted file mode 100644 index 9403843b..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14256.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class DHG14256 extends DHG14N{ - - @Override - String sha_name(){ return "sha-256"; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14N.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14N.java deleted file mode 100644 index 5c95b6d8..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14N.java +++ /dev/null @@ -1,75 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -abstract class DHG14N extends DHGN{ - - static final byte[] g={ 2 }; - static final byte[] p={ -(byte)0x00, -(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, -(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34, -(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1, -(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74, -(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22, -(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD, -(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B, -(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37, -(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45, -(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6, -(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B, -(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED, -(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5, -(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6, -(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D, -(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05, -(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A, -(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F, -(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96, -(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB, -(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D, -(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04, -(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C, -(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B, -(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03, -(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F, -(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9, -(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18, -(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5, -(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10, -(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAC,(byte)0xAA,(byte)0x68, -(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF -}; - - @Override - byte[] G(){ return g; } - @Override - byte[] P(){ return p; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15.java deleted file mode 100644 index 0e31d859..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class DHG15 extends DHG15N{ - - @Override - String sha_name(){ return "sha-512"; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15256.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15256.java deleted file mode 100644 index 359450a3..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15256.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class DHG15256 extends DHG15N{ - - @Override - String sha_name(){ return "sha-256"; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15384.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15384.java deleted file mode 100644 index 7c9f2fb7..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15384.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class DHG15384 extends DHG15N{ - - @Override - String sha_name(){ return "sha-384"; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15N.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15N.java deleted file mode 100644 index 8d72935f..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15N.java +++ /dev/null @@ -1,91 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -abstract class DHG15N extends DHGN{ - - static final byte[] g={ 2 }; - static final byte[] p={ -(byte)0x00, -(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, -(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34, -(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1, -(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74, -(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22, -(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD, -(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B, -(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37, -(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45, -(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6, -(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B, -(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED, -(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5, -(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6, -(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D, -(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05, -(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A, -(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F, -(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96, -(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB, -(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D, -(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04, -(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C, -(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B, -(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03, -(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F, -(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9, -(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18, -(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5, -(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10, -(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAA,(byte)0xC4,(byte)0x2D, -(byte)0xAD,(byte)0x33,(byte)0x17,(byte)0x0D,(byte)0x04,(byte)0x50,(byte)0x7A,(byte)0x33, -(byte)0xA8,(byte)0x55,(byte)0x21,(byte)0xAB,(byte)0xDF,(byte)0x1C,(byte)0xBA,(byte)0x64, -(byte)0xEC,(byte)0xFB,(byte)0x85,(byte)0x04,(byte)0x58,(byte)0xDB,(byte)0xEF,(byte)0x0A, -(byte)0x8A,(byte)0xEA,(byte)0x71,(byte)0x57,(byte)0x5D,(byte)0x06,(byte)0x0C,(byte)0x7D, -(byte)0xB3,(byte)0x97,(byte)0x0F,(byte)0x85,(byte)0xA6,(byte)0xE1,(byte)0xE4,(byte)0xC7, -(byte)0xAB,(byte)0xF5,(byte)0xAE,(byte)0x8C,(byte)0xDB,(byte)0x09,(byte)0x33,(byte)0xD7, -(byte)0x1E,(byte)0x8C,(byte)0x94,(byte)0xE0,(byte)0x4A,(byte)0x25,(byte)0x61,(byte)0x9D, -(byte)0xCE,(byte)0xE3,(byte)0xD2,(byte)0x26,(byte)0x1A,(byte)0xD2,(byte)0xEE,(byte)0x6B, -(byte)0xF1,(byte)0x2F,(byte)0xFA,(byte)0x06,(byte)0xD9,(byte)0x8A,(byte)0x08,(byte)0x64, -(byte)0xD8,(byte)0x76,(byte)0x02,(byte)0x73,(byte)0x3E,(byte)0xC8,(byte)0x6A,(byte)0x64, -(byte)0x52,(byte)0x1F,(byte)0x2B,(byte)0x18,(byte)0x17,(byte)0x7B,(byte)0x20,(byte)0x0C, -(byte)0xBB,(byte)0xE1,(byte)0x17,(byte)0x57,(byte)0x7A,(byte)0x61,(byte)0x5D,(byte)0x6C, -(byte)0x77,(byte)0x09,(byte)0x88,(byte)0xC0,(byte)0xBA,(byte)0xD9,(byte)0x46,(byte)0xE2, -(byte)0x08,(byte)0xE2,(byte)0x4F,(byte)0xA0,(byte)0x74,(byte)0xE5,(byte)0xAB,(byte)0x31, -(byte)0x43,(byte)0xDB,(byte)0x5B,(byte)0xFC,(byte)0xE0,(byte)0xFD,(byte)0x10,(byte)0x8E, -(byte)0x4B,(byte)0x82,(byte)0xD1,(byte)0x20,(byte)0xA9,(byte)0x3A,(byte)0xD2,(byte)0xCA, -(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF -}; - - @Override - byte[] G(){ return g; } - @Override - byte[] P(){ return p; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16.java deleted file mode 100644 index f8c62a20..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class DHG16 extends DHG16N{ - - @Override - String sha_name(){ return "sha-512"; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16384.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16384.java deleted file mode 100644 index 533b2046..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16384.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class DHG16384 extends DHG16N{ - - @Override - String sha_name(){ return "sha-384"; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16N.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16N.java deleted file mode 100644 index acfcbab2..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16N.java +++ /dev/null @@ -1,107 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -abstract class DHG16N extends DHGN{ - - static final byte[] g={ 2 }; - static final byte[] p={ -(byte)0x00, -(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, -(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34, -(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1, -(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74, -(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22, -(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD, -(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B, -(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37, -(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45, -(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6, -(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B, -(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED, -(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5, -(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6, -(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D, -(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05, -(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A, -(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F, -(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96, -(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB, -(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D, -(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04, -(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C, -(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B, -(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03, -(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F, -(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9, -(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18, -(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5, -(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10, -(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAA,(byte)0xC4,(byte)0x2D, -(byte)0xAD,(byte)0x33,(byte)0x17,(byte)0x0D,(byte)0x04,(byte)0x50,(byte)0x7A,(byte)0x33, -(byte)0xA8,(byte)0x55,(byte)0x21,(byte)0xAB,(byte)0xDF,(byte)0x1C,(byte)0xBA,(byte)0x64, -(byte)0xEC,(byte)0xFB,(byte)0x85,(byte)0x04,(byte)0x58,(byte)0xDB,(byte)0xEF,(byte)0x0A, -(byte)0x8A,(byte)0xEA,(byte)0x71,(byte)0x57,(byte)0x5D,(byte)0x06,(byte)0x0C,(byte)0x7D, -(byte)0xB3,(byte)0x97,(byte)0x0F,(byte)0x85,(byte)0xA6,(byte)0xE1,(byte)0xE4,(byte)0xC7, -(byte)0xAB,(byte)0xF5,(byte)0xAE,(byte)0x8C,(byte)0xDB,(byte)0x09,(byte)0x33,(byte)0xD7, -(byte)0x1E,(byte)0x8C,(byte)0x94,(byte)0xE0,(byte)0x4A,(byte)0x25,(byte)0x61,(byte)0x9D, -(byte)0xCE,(byte)0xE3,(byte)0xD2,(byte)0x26,(byte)0x1A,(byte)0xD2,(byte)0xEE,(byte)0x6B, -(byte)0xF1,(byte)0x2F,(byte)0xFA,(byte)0x06,(byte)0xD9,(byte)0x8A,(byte)0x08,(byte)0x64, -(byte)0xD8,(byte)0x76,(byte)0x02,(byte)0x73,(byte)0x3E,(byte)0xC8,(byte)0x6A,(byte)0x64, -(byte)0x52,(byte)0x1F,(byte)0x2B,(byte)0x18,(byte)0x17,(byte)0x7B,(byte)0x20,(byte)0x0C, -(byte)0xBB,(byte)0xE1,(byte)0x17,(byte)0x57,(byte)0x7A,(byte)0x61,(byte)0x5D,(byte)0x6C, -(byte)0x77,(byte)0x09,(byte)0x88,(byte)0xC0,(byte)0xBA,(byte)0xD9,(byte)0x46,(byte)0xE2, -(byte)0x08,(byte)0xE2,(byte)0x4F,(byte)0xA0,(byte)0x74,(byte)0xE5,(byte)0xAB,(byte)0x31, -(byte)0x43,(byte)0xDB,(byte)0x5B,(byte)0xFC,(byte)0xE0,(byte)0xFD,(byte)0x10,(byte)0x8E, -(byte)0x4B,(byte)0x82,(byte)0xD1,(byte)0x20,(byte)0xA9,(byte)0x21,(byte)0x08,(byte)0x01, -(byte)0x1A,(byte)0x72,(byte)0x3C,(byte)0x12,(byte)0xA7,(byte)0x87,(byte)0xE6,(byte)0xD7, -(byte)0x88,(byte)0x71,(byte)0x9A,(byte)0x10,(byte)0xBD,(byte)0xBA,(byte)0x5B,(byte)0x26, -(byte)0x99,(byte)0xC3,(byte)0x27,(byte)0x18,(byte)0x6A,(byte)0xF4,(byte)0xE2,(byte)0x3C, -(byte)0x1A,(byte)0x94,(byte)0x68,(byte)0x34,(byte)0xB6,(byte)0x15,(byte)0x0B,(byte)0xDA, -(byte)0x25,(byte)0x83,(byte)0xE9,(byte)0xCA,(byte)0x2A,(byte)0xD4,(byte)0x4C,(byte)0xE8, -(byte)0xDB,(byte)0xBB,(byte)0xC2,(byte)0xDB,(byte)0x04,(byte)0xDE,(byte)0x8E,(byte)0xF9, -(byte)0x2E,(byte)0x8E,(byte)0xFC,(byte)0x14,(byte)0x1F,(byte)0xBE,(byte)0xCA,(byte)0xA6, -(byte)0x28,(byte)0x7C,(byte)0x59,(byte)0x47,(byte)0x4E,(byte)0x6B,(byte)0xC0,(byte)0x5D, -(byte)0x99,(byte)0xB2,(byte)0x96,(byte)0x4F,(byte)0xA0,(byte)0x90,(byte)0xC3,(byte)0xA2, -(byte)0x23,(byte)0x3B,(byte)0xA1,(byte)0x86,(byte)0x51,(byte)0x5B,(byte)0xE7,(byte)0xED, -(byte)0x1F,(byte)0x61,(byte)0x29,(byte)0x70,(byte)0xCE,(byte)0xE2,(byte)0xD7,(byte)0xAF, -(byte)0xB8,(byte)0x1B,(byte)0xDD,(byte)0x76,(byte)0x21,(byte)0x70,(byte)0x48,(byte)0x1C, -(byte)0xD0,(byte)0x06,(byte)0x91,(byte)0x27,(byte)0xD5,(byte)0xB0,(byte)0x5A,(byte)0xA9, -(byte)0x93,(byte)0xB4,(byte)0xEA,(byte)0x98,(byte)0x8D,(byte)0x8F,(byte)0xDD,(byte)0xC1, -(byte)0x86,(byte)0xFF,(byte)0xB7,(byte)0xDC,(byte)0x90,(byte)0xA6,(byte)0xC0,(byte)0x8F, -(byte)0x4D,(byte)0xF4,(byte)0x35,(byte)0xC9,(byte)0x34,(byte)0x06,(byte)0x31,(byte)0x99, -(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF -}; - - @Override - byte[] G(){ return g; } - @Override - byte[] P(){ return p; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG17.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG17.java deleted file mode 100644 index 9d415cf0..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG17.java +++ /dev/null @@ -1,141 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class DHG17 extends DHGN{ - - static final byte[] g={ 2 }; - static final byte[] p={ -(byte)0x00, -(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, -(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34, -(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1, -(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74, -(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22, -(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD, -(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B, -(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37, -(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45, -(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6, -(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B, -(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED, -(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5, -(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6, -(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D, -(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05, -(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A, -(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F, -(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96, -(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB, -(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D, -(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04, -(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C, -(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B, -(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03, -(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F, -(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9, -(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18, -(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5, -(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10, -(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAA,(byte)0xC4,(byte)0x2D, -(byte)0xAD,(byte)0x33,(byte)0x17,(byte)0x0D,(byte)0x04,(byte)0x50,(byte)0x7A,(byte)0x33, -(byte)0xA8,(byte)0x55,(byte)0x21,(byte)0xAB,(byte)0xDF,(byte)0x1C,(byte)0xBA,(byte)0x64, -(byte)0xEC,(byte)0xFB,(byte)0x85,(byte)0x04,(byte)0x58,(byte)0xDB,(byte)0xEF,(byte)0x0A, -(byte)0x8A,(byte)0xEA,(byte)0x71,(byte)0x57,(byte)0x5D,(byte)0x06,(byte)0x0C,(byte)0x7D, -(byte)0xB3,(byte)0x97,(byte)0x0F,(byte)0x85,(byte)0xA6,(byte)0xE1,(byte)0xE4,(byte)0xC7, -(byte)0xAB,(byte)0xF5,(byte)0xAE,(byte)0x8C,(byte)0xDB,(byte)0x09,(byte)0x33,(byte)0xD7, -(byte)0x1E,(byte)0x8C,(byte)0x94,(byte)0xE0,(byte)0x4A,(byte)0x25,(byte)0x61,(byte)0x9D, -(byte)0xCE,(byte)0xE3,(byte)0xD2,(byte)0x26,(byte)0x1A,(byte)0xD2,(byte)0xEE,(byte)0x6B, -(byte)0xF1,(byte)0x2F,(byte)0xFA,(byte)0x06,(byte)0xD9,(byte)0x8A,(byte)0x08,(byte)0x64, -(byte)0xD8,(byte)0x76,(byte)0x02,(byte)0x73,(byte)0x3E,(byte)0xC8,(byte)0x6A,(byte)0x64, -(byte)0x52,(byte)0x1F,(byte)0x2B,(byte)0x18,(byte)0x17,(byte)0x7B,(byte)0x20,(byte)0x0C, -(byte)0xBB,(byte)0xE1,(byte)0x17,(byte)0x57,(byte)0x7A,(byte)0x61,(byte)0x5D,(byte)0x6C, -(byte)0x77,(byte)0x09,(byte)0x88,(byte)0xC0,(byte)0xBA,(byte)0xD9,(byte)0x46,(byte)0xE2, -(byte)0x08,(byte)0xE2,(byte)0x4F,(byte)0xA0,(byte)0x74,(byte)0xE5,(byte)0xAB,(byte)0x31, -(byte)0x43,(byte)0xDB,(byte)0x5B,(byte)0xFC,(byte)0xE0,(byte)0xFD,(byte)0x10,(byte)0x8E, -(byte)0x4B,(byte)0x82,(byte)0xD1,(byte)0x20,(byte)0xA9,(byte)0x21,(byte)0x08,(byte)0x01, -(byte)0x1A,(byte)0x72,(byte)0x3C,(byte)0x12,(byte)0xA7,(byte)0x87,(byte)0xE6,(byte)0xD7, -(byte)0x88,(byte)0x71,(byte)0x9A,(byte)0x10,(byte)0xBD,(byte)0xBA,(byte)0x5B,(byte)0x26, -(byte)0x99,(byte)0xC3,(byte)0x27,(byte)0x18,(byte)0x6A,(byte)0xF4,(byte)0xE2,(byte)0x3C, -(byte)0x1A,(byte)0x94,(byte)0x68,(byte)0x34,(byte)0xB6,(byte)0x15,(byte)0x0B,(byte)0xDA, -(byte)0x25,(byte)0x83,(byte)0xE9,(byte)0xCA,(byte)0x2A,(byte)0xD4,(byte)0x4C,(byte)0xE8, -(byte)0xDB,(byte)0xBB,(byte)0xC2,(byte)0xDB,(byte)0x04,(byte)0xDE,(byte)0x8E,(byte)0xF9, -(byte)0x2E,(byte)0x8E,(byte)0xFC,(byte)0x14,(byte)0x1F,(byte)0xBE,(byte)0xCA,(byte)0xA6, -(byte)0x28,(byte)0x7C,(byte)0x59,(byte)0x47,(byte)0x4E,(byte)0x6B,(byte)0xC0,(byte)0x5D, -(byte)0x99,(byte)0xB2,(byte)0x96,(byte)0x4F,(byte)0xA0,(byte)0x90,(byte)0xC3,(byte)0xA2, -(byte)0x23,(byte)0x3B,(byte)0xA1,(byte)0x86,(byte)0x51,(byte)0x5B,(byte)0xE7,(byte)0xED, -(byte)0x1F,(byte)0x61,(byte)0x29,(byte)0x70,(byte)0xCE,(byte)0xE2,(byte)0xD7,(byte)0xAF, -(byte)0xB8,(byte)0x1B,(byte)0xDD,(byte)0x76,(byte)0x21,(byte)0x70,(byte)0x48,(byte)0x1C, -(byte)0xD0,(byte)0x06,(byte)0x91,(byte)0x27,(byte)0xD5,(byte)0xB0,(byte)0x5A,(byte)0xA9, -(byte)0x93,(byte)0xB4,(byte)0xEA,(byte)0x98,(byte)0x8D,(byte)0x8F,(byte)0xDD,(byte)0xC1, -(byte)0x86,(byte)0xFF,(byte)0xB7,(byte)0xDC,(byte)0x90,(byte)0xA6,(byte)0xC0,(byte)0x8F, -(byte)0x4D,(byte)0xF4,(byte)0x35,(byte)0xC9,(byte)0x34,(byte)0x02,(byte)0x84,(byte)0x92, -(byte)0x36,(byte)0xC3,(byte)0xFA,(byte)0xB4,(byte)0xD2,(byte)0x7C,(byte)0x70,(byte)0x26, -(byte)0xC1,(byte)0xD4,(byte)0xDC,(byte)0xB2,(byte)0x60,(byte)0x26,(byte)0x46,(byte)0xDE, -(byte)0xC9,(byte)0x75,(byte)0x1E,(byte)0x76,(byte)0x3D,(byte)0xBA,(byte)0x37,(byte)0xBD, -(byte)0xF8,(byte)0xFF,(byte)0x94,(byte)0x06,(byte)0xAD,(byte)0x9E,(byte)0x53,(byte)0x0E, -(byte)0xE5,(byte)0xDB,(byte)0x38,(byte)0x2F,(byte)0x41,(byte)0x30,(byte)0x01,(byte)0xAE, -(byte)0xB0,(byte)0x6A,(byte)0x53,(byte)0xED,(byte)0x90,(byte)0x27,(byte)0xD8,(byte)0x31, -(byte)0x17,(byte)0x97,(byte)0x27,(byte)0xB0,(byte)0x86,(byte)0x5A,(byte)0x89,(byte)0x18, -(byte)0xDA,(byte)0x3E,(byte)0xDB,(byte)0xEB,(byte)0xCF,(byte)0x9B,(byte)0x14,(byte)0xED, -(byte)0x44,(byte)0xCE,(byte)0x6C,(byte)0xBA,(byte)0xCE,(byte)0xD4,(byte)0xBB,(byte)0x1B, -(byte)0xDB,(byte)0x7F,(byte)0x14,(byte)0x47,(byte)0xE6,(byte)0xCC,(byte)0x25,(byte)0x4B, -(byte)0x33,(byte)0x20,(byte)0x51,(byte)0x51,(byte)0x2B,(byte)0xD7,(byte)0xAF,(byte)0x42, -(byte)0x6F,(byte)0xB8,(byte)0xF4,(byte)0x01,(byte)0x37,(byte)0x8C,(byte)0xD2,(byte)0xBF, -(byte)0x59,(byte)0x83,(byte)0xCA,(byte)0x01,(byte)0xC6,(byte)0x4B,(byte)0x92,(byte)0xEC, -(byte)0xF0,(byte)0x32,(byte)0xEA,(byte)0x15,(byte)0xD1,(byte)0x72,(byte)0x1D,(byte)0x03, -(byte)0xF4,(byte)0x82,(byte)0xD7,(byte)0xCE,(byte)0x6E,(byte)0x74,(byte)0xFE,(byte)0xF6, -(byte)0xD5,(byte)0x5E,(byte)0x70,(byte)0x2F,(byte)0x46,(byte)0x98,(byte)0x0C,(byte)0x82, -(byte)0xB5,(byte)0xA8,(byte)0x40,(byte)0x31,(byte)0x90,(byte)0x0B,(byte)0x1C,(byte)0x9E, -(byte)0x59,(byte)0xE7,(byte)0xC9,(byte)0x7F,(byte)0xBE,(byte)0xC7,(byte)0xE8,(byte)0xF3, -(byte)0x23,(byte)0xA9,(byte)0x7A,(byte)0x7E,(byte)0x36,(byte)0xCC,(byte)0x88,(byte)0xBE, -(byte)0x0F,(byte)0x1D,(byte)0x45,(byte)0xB7,(byte)0xFF,(byte)0x58,(byte)0x5A,(byte)0xC5, -(byte)0x4B,(byte)0xD4,(byte)0x07,(byte)0xB2,(byte)0x2B,(byte)0x41,(byte)0x54,(byte)0xAA, -(byte)0xCC,(byte)0x8F,(byte)0x6D,(byte)0x7E,(byte)0xBF,(byte)0x48,(byte)0xE1,(byte)0xD8, -(byte)0x14,(byte)0xCC,(byte)0x5E,(byte)0xD2,(byte)0x0F,(byte)0x80,(byte)0x37,(byte)0xE0, -(byte)0xA7,(byte)0x97,(byte)0x15,(byte)0xEE,(byte)0xF2,(byte)0x9B,(byte)0xE3,(byte)0x28, -(byte)0x06,(byte)0xA1,(byte)0xD5,(byte)0x8B,(byte)0xB7,(byte)0xC5,(byte)0xDA,(byte)0x76, -(byte)0xF5,(byte)0x50,(byte)0xAA,(byte)0x3D,(byte)0x8A,(byte)0x1F,(byte)0xBF,(byte)0xF0, -(byte)0xEB,(byte)0x19,(byte)0xCC,(byte)0xB1,(byte)0xA3,(byte)0x13,(byte)0xD5,(byte)0x5C, -(byte)0xDA,(byte)0x56,(byte)0xC9,(byte)0xEC,(byte)0x2E,(byte)0xF2,(byte)0x96,(byte)0x32, -(byte)0x38,(byte)0x7F,(byte)0xE8,(byte)0xD7,(byte)0x6E,(byte)0x3C,(byte)0x04,(byte)0x68, -(byte)0x04,(byte)0x3E,(byte)0x8F,(byte)0x66,(byte)0x3F,(byte)0x48,(byte)0x60,(byte)0xEE, -(byte)0x12,(byte)0xBF,(byte)0x2D,(byte)0x5B,(byte)0x0B,(byte)0x74,(byte)0x74,(byte)0xD6, -(byte)0xE6,(byte)0x94,(byte)0xF9,(byte)0x1E,(byte)0x6D,(byte)0xCC,(byte)0x40,(byte)0x24, -(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, -}; - - @Override - byte[] G(){ return g; } - @Override - byte[] P(){ return p; } - @Override - String sha_name(){ return "sha-512"; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG18.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG18.java deleted file mode 100644 index 8f101ca0..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG18.java +++ /dev/null @@ -1,173 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class DHG18 extends DHGN{ - - static final byte[] g={ 2 }; - static final byte[] p={ -(byte)0x00, -(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, -(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34, -(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1, -(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74, -(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22, -(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD, -(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B, -(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37, -(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45, -(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6, -(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B, -(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED, -(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5, -(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6, -(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D, -(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05, -(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A, -(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F, -(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96, -(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB, -(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D, -(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04, -(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C, -(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B, -(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03, -(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F, -(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9, -(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18, -(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5, -(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10, -(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAA,(byte)0xC4,(byte)0x2D, -(byte)0xAD,(byte)0x33,(byte)0x17,(byte)0x0D,(byte)0x04,(byte)0x50,(byte)0x7A,(byte)0x33, -(byte)0xA8,(byte)0x55,(byte)0x21,(byte)0xAB,(byte)0xDF,(byte)0x1C,(byte)0xBA,(byte)0x64, -(byte)0xEC,(byte)0xFB,(byte)0x85,(byte)0x04,(byte)0x58,(byte)0xDB,(byte)0xEF,(byte)0x0A, -(byte)0x8A,(byte)0xEA,(byte)0x71,(byte)0x57,(byte)0x5D,(byte)0x06,(byte)0x0C,(byte)0x7D, -(byte)0xB3,(byte)0x97,(byte)0x0F,(byte)0x85,(byte)0xA6,(byte)0xE1,(byte)0xE4,(byte)0xC7, -(byte)0xAB,(byte)0xF5,(byte)0xAE,(byte)0x8C,(byte)0xDB,(byte)0x09,(byte)0x33,(byte)0xD7, -(byte)0x1E,(byte)0x8C,(byte)0x94,(byte)0xE0,(byte)0x4A,(byte)0x25,(byte)0x61,(byte)0x9D, -(byte)0xCE,(byte)0xE3,(byte)0xD2,(byte)0x26,(byte)0x1A,(byte)0xD2,(byte)0xEE,(byte)0x6B, -(byte)0xF1,(byte)0x2F,(byte)0xFA,(byte)0x06,(byte)0xD9,(byte)0x8A,(byte)0x08,(byte)0x64, -(byte)0xD8,(byte)0x76,(byte)0x02,(byte)0x73,(byte)0x3E,(byte)0xC8,(byte)0x6A,(byte)0x64, -(byte)0x52,(byte)0x1F,(byte)0x2B,(byte)0x18,(byte)0x17,(byte)0x7B,(byte)0x20,(byte)0x0C, -(byte)0xBB,(byte)0xE1,(byte)0x17,(byte)0x57,(byte)0x7A,(byte)0x61,(byte)0x5D,(byte)0x6C, -(byte)0x77,(byte)0x09,(byte)0x88,(byte)0xC0,(byte)0xBA,(byte)0xD9,(byte)0x46,(byte)0xE2, -(byte)0x08,(byte)0xE2,(byte)0x4F,(byte)0xA0,(byte)0x74,(byte)0xE5,(byte)0xAB,(byte)0x31, -(byte)0x43,(byte)0xDB,(byte)0x5B,(byte)0xFC,(byte)0xE0,(byte)0xFD,(byte)0x10,(byte)0x8E, -(byte)0x4B,(byte)0x82,(byte)0xD1,(byte)0x20,(byte)0xA9,(byte)0x21,(byte)0x08,(byte)0x01, -(byte)0x1A,(byte)0x72,(byte)0x3C,(byte)0x12,(byte)0xA7,(byte)0x87,(byte)0xE6,(byte)0xD7, -(byte)0x88,(byte)0x71,(byte)0x9A,(byte)0x10,(byte)0xBD,(byte)0xBA,(byte)0x5B,(byte)0x26, -(byte)0x99,(byte)0xC3,(byte)0x27,(byte)0x18,(byte)0x6A,(byte)0xF4,(byte)0xE2,(byte)0x3C, -(byte)0x1A,(byte)0x94,(byte)0x68,(byte)0x34,(byte)0xB6,(byte)0x15,(byte)0x0B,(byte)0xDA, -(byte)0x25,(byte)0x83,(byte)0xE9,(byte)0xCA,(byte)0x2A,(byte)0xD4,(byte)0x4C,(byte)0xE8, -(byte)0xDB,(byte)0xBB,(byte)0xC2,(byte)0xDB,(byte)0x04,(byte)0xDE,(byte)0x8E,(byte)0xF9, -(byte)0x2E,(byte)0x8E,(byte)0xFC,(byte)0x14,(byte)0x1F,(byte)0xBE,(byte)0xCA,(byte)0xA6, -(byte)0x28,(byte)0x7C,(byte)0x59,(byte)0x47,(byte)0x4E,(byte)0x6B,(byte)0xC0,(byte)0x5D, -(byte)0x99,(byte)0xB2,(byte)0x96,(byte)0x4F,(byte)0xA0,(byte)0x90,(byte)0xC3,(byte)0xA2, -(byte)0x23,(byte)0x3B,(byte)0xA1,(byte)0x86,(byte)0x51,(byte)0x5B,(byte)0xE7,(byte)0xED, -(byte)0x1F,(byte)0x61,(byte)0x29,(byte)0x70,(byte)0xCE,(byte)0xE2,(byte)0xD7,(byte)0xAF, -(byte)0xB8,(byte)0x1B,(byte)0xDD,(byte)0x76,(byte)0x21,(byte)0x70,(byte)0x48,(byte)0x1C, -(byte)0xD0,(byte)0x06,(byte)0x91,(byte)0x27,(byte)0xD5,(byte)0xB0,(byte)0x5A,(byte)0xA9, -(byte)0x93,(byte)0xB4,(byte)0xEA,(byte)0x98,(byte)0x8D,(byte)0x8F,(byte)0xDD,(byte)0xC1, -(byte)0x86,(byte)0xFF,(byte)0xB7,(byte)0xDC,(byte)0x90,(byte)0xA6,(byte)0xC0,(byte)0x8F, -(byte)0x4D,(byte)0xF4,(byte)0x35,(byte)0xC9,(byte)0x34,(byte)0x02,(byte)0x84,(byte)0x92, -(byte)0x36,(byte)0xC3,(byte)0xFA,(byte)0xB4,(byte)0xD2,(byte)0x7C,(byte)0x70,(byte)0x26, -(byte)0xC1,(byte)0xD4,(byte)0xDC,(byte)0xB2,(byte)0x60,(byte)0x26,(byte)0x46,(byte)0xDE, -(byte)0xC9,(byte)0x75,(byte)0x1E,(byte)0x76,(byte)0x3D,(byte)0xBA,(byte)0x37,(byte)0xBD, -(byte)0xF8,(byte)0xFF,(byte)0x94,(byte)0x06,(byte)0xAD,(byte)0x9E,(byte)0x53,(byte)0x0E, -(byte)0xE5,(byte)0xDB,(byte)0x38,(byte)0x2F,(byte)0x41,(byte)0x30,(byte)0x01,(byte)0xAE, -(byte)0xB0,(byte)0x6A,(byte)0x53,(byte)0xED,(byte)0x90,(byte)0x27,(byte)0xD8,(byte)0x31, -(byte)0x17,(byte)0x97,(byte)0x27,(byte)0xB0,(byte)0x86,(byte)0x5A,(byte)0x89,(byte)0x18, -(byte)0xDA,(byte)0x3E,(byte)0xDB,(byte)0xEB,(byte)0xCF,(byte)0x9B,(byte)0x14,(byte)0xED, -(byte)0x44,(byte)0xCE,(byte)0x6C,(byte)0xBA,(byte)0xCE,(byte)0xD4,(byte)0xBB,(byte)0x1B, -(byte)0xDB,(byte)0x7F,(byte)0x14,(byte)0x47,(byte)0xE6,(byte)0xCC,(byte)0x25,(byte)0x4B, -(byte)0x33,(byte)0x20,(byte)0x51,(byte)0x51,(byte)0x2B,(byte)0xD7,(byte)0xAF,(byte)0x42, -(byte)0x6F,(byte)0xB8,(byte)0xF4,(byte)0x01,(byte)0x37,(byte)0x8C,(byte)0xD2,(byte)0xBF, -(byte)0x59,(byte)0x83,(byte)0xCA,(byte)0x01,(byte)0xC6,(byte)0x4B,(byte)0x92,(byte)0xEC, -(byte)0xF0,(byte)0x32,(byte)0xEA,(byte)0x15,(byte)0xD1,(byte)0x72,(byte)0x1D,(byte)0x03, -(byte)0xF4,(byte)0x82,(byte)0xD7,(byte)0xCE,(byte)0x6E,(byte)0x74,(byte)0xFE,(byte)0xF6, -(byte)0xD5,(byte)0x5E,(byte)0x70,(byte)0x2F,(byte)0x46,(byte)0x98,(byte)0x0C,(byte)0x82, -(byte)0xB5,(byte)0xA8,(byte)0x40,(byte)0x31,(byte)0x90,(byte)0x0B,(byte)0x1C,(byte)0x9E, -(byte)0x59,(byte)0xE7,(byte)0xC9,(byte)0x7F,(byte)0xBE,(byte)0xC7,(byte)0xE8,(byte)0xF3, -(byte)0x23,(byte)0xA9,(byte)0x7A,(byte)0x7E,(byte)0x36,(byte)0xCC,(byte)0x88,(byte)0xBE, -(byte)0x0F,(byte)0x1D,(byte)0x45,(byte)0xB7,(byte)0xFF,(byte)0x58,(byte)0x5A,(byte)0xC5, -(byte)0x4B,(byte)0xD4,(byte)0x07,(byte)0xB2,(byte)0x2B,(byte)0x41,(byte)0x54,(byte)0xAA, -(byte)0xCC,(byte)0x8F,(byte)0x6D,(byte)0x7E,(byte)0xBF,(byte)0x48,(byte)0xE1,(byte)0xD8, -(byte)0x14,(byte)0xCC,(byte)0x5E,(byte)0xD2,(byte)0x0F,(byte)0x80,(byte)0x37,(byte)0xE0, -(byte)0xA7,(byte)0x97,(byte)0x15,(byte)0xEE,(byte)0xF2,(byte)0x9B,(byte)0xE3,(byte)0x28, -(byte)0x06,(byte)0xA1,(byte)0xD5,(byte)0x8B,(byte)0xB7,(byte)0xC5,(byte)0xDA,(byte)0x76, -(byte)0xF5,(byte)0x50,(byte)0xAA,(byte)0x3D,(byte)0x8A,(byte)0x1F,(byte)0xBF,(byte)0xF0, -(byte)0xEB,(byte)0x19,(byte)0xCC,(byte)0xB1,(byte)0xA3,(byte)0x13,(byte)0xD5,(byte)0x5C, -(byte)0xDA,(byte)0x56,(byte)0xC9,(byte)0xEC,(byte)0x2E,(byte)0xF2,(byte)0x96,(byte)0x32, -(byte)0x38,(byte)0x7F,(byte)0xE8,(byte)0xD7,(byte)0x6E,(byte)0x3C,(byte)0x04,(byte)0x68, -(byte)0x04,(byte)0x3E,(byte)0x8F,(byte)0x66,(byte)0x3F,(byte)0x48,(byte)0x60,(byte)0xEE, -(byte)0x12,(byte)0xBF,(byte)0x2D,(byte)0x5B,(byte)0x0B,(byte)0x74,(byte)0x74,(byte)0xD6, -(byte)0xE6,(byte)0x94,(byte)0xF9,(byte)0x1E,(byte)0x6D,(byte)0xBE,(byte)0x11,(byte)0x59, -(byte)0x74,(byte)0xA3,(byte)0x92,(byte)0x6F,(byte)0x12,(byte)0xFE,(byte)0xE5,(byte)0xE4, -(byte)0x38,(byte)0x77,(byte)0x7C,(byte)0xB6,(byte)0xA9,(byte)0x32,(byte)0xDF,(byte)0x8C, -(byte)0xD8,(byte)0xBE,(byte)0xC4,(byte)0xD0,(byte)0x73,(byte)0xB9,(byte)0x31,(byte)0xBA, -(byte)0x3B,(byte)0xC8,(byte)0x32,(byte)0xB6,(byte)0x8D,(byte)0x9D,(byte)0xD3,(byte)0x00, -(byte)0x74,(byte)0x1F,(byte)0xA7,(byte)0xBF,(byte)0x8A,(byte)0xFC,(byte)0x47,(byte)0xED, -(byte)0x25,(byte)0x76,(byte)0xF6,(byte)0x93,(byte)0x6B,(byte)0xA4,(byte)0x24,(byte)0x66, -(byte)0x3A,(byte)0xAB,(byte)0x63,(byte)0x9C,(byte)0x5A,(byte)0xE4,(byte)0xF5,(byte)0x68, -(byte)0x34,(byte)0x23,(byte)0xB4,(byte)0x74,(byte)0x2B,(byte)0xF1,(byte)0xC9,(byte)0x78, -(byte)0x23,(byte)0x8F,(byte)0x16,(byte)0xCB,(byte)0xE3,(byte)0x9D,(byte)0x65,(byte)0x2D, -(byte)0xE3,(byte)0xFD,(byte)0xB8,(byte)0xBE,(byte)0xFC,(byte)0x84,(byte)0x8A,(byte)0xD9, -(byte)0x22,(byte)0x22,(byte)0x2E,(byte)0x04,(byte)0xA4,(byte)0x03,(byte)0x7C,(byte)0x07, -(byte)0x13,(byte)0xEB,(byte)0x57,(byte)0xA8,(byte)0x1A,(byte)0x23,(byte)0xF0,(byte)0xC7, -(byte)0x34,(byte)0x73,(byte)0xFC,(byte)0x64,(byte)0x6C,(byte)0xEA,(byte)0x30,(byte)0x6B, -(byte)0x4B,(byte)0xCB,(byte)0xC8,(byte)0x86,(byte)0x2F,(byte)0x83,(byte)0x85,(byte)0xDD, -(byte)0xFA,(byte)0x9D,(byte)0x4B,(byte)0x7F,(byte)0xA2,(byte)0xC0,(byte)0x87,(byte)0xE8, -(byte)0x79,(byte)0x68,(byte)0x33,(byte)0x03,(byte)0xED,(byte)0x5B,(byte)0xDD,(byte)0x3A, -(byte)0x06,(byte)0x2B,(byte)0x3C,(byte)0xF5,(byte)0xB3,(byte)0xA2,(byte)0x78,(byte)0xA6, -(byte)0x6D,(byte)0x2A,(byte)0x13,(byte)0xF8,(byte)0x3F,(byte)0x44,(byte)0xF8,(byte)0x2D, -(byte)0xDF,(byte)0x31,(byte)0x0E,(byte)0xE0,(byte)0x74,(byte)0xAB,(byte)0x6A,(byte)0x36, -(byte)0x45,(byte)0x97,(byte)0xE8,(byte)0x99,(byte)0xA0,(byte)0x25,(byte)0x5D,(byte)0xC1, -(byte)0x64,(byte)0xF3,(byte)0x1C,(byte)0xC5,(byte)0x08,(byte)0x46,(byte)0x85,(byte)0x1D, -(byte)0xF9,(byte)0xAB,(byte)0x48,(byte)0x19,(byte)0x5D,(byte)0xED,(byte)0x7E,(byte)0xA1, -(byte)0xB1,(byte)0xD5,(byte)0x10,(byte)0xBD,(byte)0x7E,(byte)0xE7,(byte)0x4D,(byte)0x73, -(byte)0xFA,(byte)0xF3,(byte)0x6B,(byte)0xC3,(byte)0x1E,(byte)0xCF,(byte)0xA2,(byte)0x68, -(byte)0x35,(byte)0x90,(byte)0x46,(byte)0xF4,(byte)0xEB,(byte)0x87,(byte)0x9F,(byte)0x92, -(byte)0x40,(byte)0x09,(byte)0x43,(byte)0x8B,(byte)0x48,(byte)0x1C,(byte)0x6C,(byte)0xD7, -(byte)0x88,(byte)0x9A,(byte)0x00,(byte)0x2E,(byte)0xD5,(byte)0xEE,(byte)0x38,(byte)0x2B, -(byte)0xC9,(byte)0x19,(byte)0x0D,(byte)0xA6,(byte)0xFC,(byte)0x02,(byte)0x6E,(byte)0x47, -(byte)0x95,(byte)0x58,(byte)0xE4,(byte)0x47,(byte)0x56,(byte)0x77,(byte)0xE9,(byte)0xAA, -(byte)0x9E,(byte)0x30,(byte)0x50,(byte)0xE2,(byte)0x76,(byte)0x56,(byte)0x94,(byte)0xDF, -(byte)0xC8,(byte)0x1F,(byte)0x56,(byte)0xE8,(byte)0x80,(byte)0xB9,(byte)0x6E,(byte)0x71, -(byte)0x60,(byte)0xC9,(byte)0x80,(byte)0xDD,(byte)0x98,(byte)0xED,(byte)0xD3,(byte)0xDF, -(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF -}; - - @Override - byte[] G(){ return g; } - @Override - byte[] P(){ return p; } - @Override - String sha_name(){ return "sha-512"; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX.java deleted file mode 100644 index 774ca6ca..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX.java +++ /dev/null @@ -1,237 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -abstract class DHGEX extends KeyExchange{ - - private static final int SSH_MSG_KEX_DH_GEX_GROUP= 31; - private static final int SSH_MSG_KEX_DH_GEX_INIT= 32; - private static final int SSH_MSG_KEX_DH_GEX_REPLY= 33; - private static final int SSH_MSG_KEX_DH_GEX_REQUEST= 34; - - int min; - int preferred; - int max; - - private int state; - - DH dh; - - byte[] V_S; - byte[] V_C; - byte[] I_S; - byte[] I_C; - - private Buffer buf; - private Packet packet; - - private byte[] p; - private byte[] g; - private byte[] e; - - protected String hash; - - @Override - public void init(Session session, - byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{ - this.V_S=V_S; - this.V_C=V_C; - this.I_S=I_S; - this.I_C=I_C; - - try{ - Class c=Class.forName(session.getConfig(hash)).asSubclass(HASH.class); - sha=c.getDeclaredConstructor().newInstance(); - sha.init(); - } - catch(Exception e){ - System.err.println(e); - } - - buf=new Buffer(); - packet=new Packet(buf); - - try{ - Class c=Class.forName(session.getConfig("dh")).asSubclass(DH.class); - min=Integer.parseInt(session.getConfig("dhgex_min")); - max=Integer.parseInt(session.getConfig("dhgex_max")); - preferred=Integer.parseInt(session.getConfig("dhgex_preferred")); - if(checkInvalidSize(min) || checkInvalidSize(max) || checkInvalidSize(preferred) || preferred < min || max < preferred){ - throw new JSchException("Invalid DHGEX sizes: min=" + min + " max=" + max + " preferred=" + preferred); - } - dh=c.getDeclaredConstructor().newInstance(); - dh.init(); - } - catch(Exception e){ - throw e; - } - - packet.reset(); - buf.putByte((byte)SSH_MSG_KEX_DH_GEX_REQUEST); - buf.putInt(min); - buf.putInt(preferred); - buf.putInt(max); - session.write(packet); - - if(session.getLogger().isEnabled(Logger.INFO)){ - session.getLogger().log(Logger.INFO, - "SSH_MSG_KEX_DH_GEX_REQUEST("+min+"<"+preferred+"<"+max+") sent"); - session.getLogger().log(Logger.INFO, - "expecting SSH_MSG_KEX_DH_GEX_GROUP"); - } - - state=SSH_MSG_KEX_DH_GEX_GROUP; - } - - @Override - public boolean next(Buffer _buf) throws Exception{ - int i,j; - switch(state){ - case SSH_MSG_KEX_DH_GEX_GROUP: - // byte SSH_MSG_KEX_DH_GEX_GROUP(31) - // mpint p, safe prime - // mpint g, generator for subgroup in GF (p) - _buf.getInt(); - _buf.getByte(); - j=_buf.getByte(); - if(j!=SSH_MSG_KEX_DH_GEX_GROUP){ - System.err.println("type: must be SSH_MSG_KEX_DH_GEX_GROUP "+j); - return false; - } - - p=_buf.getMPInt(); - g=_buf.getMPInt(); - - dh.setP(p); - dh.setG(g); - // The client responds with: - // byte SSH_MSG_KEX_DH_GEX_INIT(32) - // mpint e <- g^x mod p - // x is a random number (1 < x < (p-1)/2) - - e=dh.getE(); - - packet.reset(); - buf.putByte((byte)SSH_MSG_KEX_DH_GEX_INIT); - buf.putMPInt(e); - session.write(packet); - - if(session.getLogger().isEnabled(Logger.INFO)){ - session.getLogger().log(Logger.INFO, - "SSH_MSG_KEX_DH_GEX_INIT sent"); - session.getLogger().log(Logger.INFO, - "expecting SSH_MSG_KEX_DH_GEX_REPLY"); - } - - state=SSH_MSG_KEX_DH_GEX_REPLY; - return true; - //break; - - case SSH_MSG_KEX_DH_GEX_REPLY: - // The server responds with: - // byte SSH_MSG_KEX_DH_GEX_REPLY(33) - // string server public host key and certificates (K_S) - // mpint f - // string signature of H - j=_buf.getInt(); - j=_buf.getByte(); - j=_buf.getByte(); - if(j!=SSH_MSG_KEX_DH_GEX_REPLY){ - System.err.println("type: must be SSH_MSG_KEX_DH_GEX_REPLY "+j); - return false; - } - - K_S=_buf.getString(); - - byte[] f=_buf.getMPInt(); - byte[] sig_of_H=_buf.getString(); - - dh.setF(f); - - dh.checkRange(); - - K=normalize(dh.getK()); - - //The hash H is computed as the HASH hash of the concatenation of the - //following: - // string V_C, the client's version string (CR and NL excluded) - // string V_S, the server's version string (CR and NL excluded) - // string I_C, the payload of the client's SSH_MSG_KEXINIT - // string I_S, the payload of the server's SSH_MSG_KEXINIT - // string K_S, the host key - // uint32 min, minimal size in bits of an acceptable group - // uint32 n, preferred size in bits of the group the server should send - // uint32 max, maximal size in bits of an acceptable group - // mpint p, safe prime - // mpint g, generator for subgroup - // mpint e, exchange value sent by the client - // mpint f, exchange value sent by the server - // mpint K, the shared secret - // This value is called the exchange hash, and it is used to authenti- - // cate the key exchange. - - buf.reset(); - buf.putString(V_C); buf.putString(V_S); - buf.putString(I_C); buf.putString(I_S); - buf.putString(K_S); - buf.putInt(min); buf.putInt(preferred); buf.putInt(max); - buf.putMPInt(p); buf.putMPInt(g); buf.putMPInt(e); buf.putMPInt(f); - buf.putMPInt(K); - - byte[] foo=new byte[buf.getLength()]; - buf.getByte(foo); - sha.update(foo, 0, foo.length); - - H=sha.digest(); - - // System.err.print("H -> "); dump(H, 0, H.length); - - i=0; - j=0; - j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); - String alg=Util.byte2str(K_S, i, j); - i+=j; - - boolean result = verify(alg, K_S, i, sig_of_H); - - state=STATE_END; - return result; - } - return false; - } - - @Override - public int getState(){return state; } - - static boolean checkInvalidSize(int size) { - return (size < 1024 || size > 8192 || size % 1024 != 0); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX1.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX1.java deleted file mode 100644 index cb05879b..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX1.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class DHGEX1 extends DHGEX { - DHGEX1(){ - hash="sha-1"; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX224.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX224.java deleted file mode 100644 index f2dc989c..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX224.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class DHGEX224 extends DHGEX { - DHGEX224(){ - hash="sha-224"; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX256.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX256.java deleted file mode 100644 index 4c6be171..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX256.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class DHGEX256 extends DHGEX { - DHGEX256(){ - hash="sha-256"; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX384.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX384.java deleted file mode 100644 index 67c5b585..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX384.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class DHGEX384 extends DHGEX { - DHGEX384(){ - hash="sha-384"; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX512.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX512.java deleted file mode 100644 index 830a0bce..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX512.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class DHGEX512 extends DHGEX { - DHGEX512(){ - hash="sha-512"; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGN.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGN.java deleted file mode 100644 index fcaed930..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGN.java +++ /dev/null @@ -1,184 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -abstract class DHGN extends KeyExchange{ - - private static final int SSH_MSG_KEXDH_INIT= 30; - private static final int SSH_MSG_KEXDH_REPLY= 31; - - private int state; - - DH dh; - - byte[] V_S; - byte[] V_C; - byte[] I_S; - byte[] I_C; - - byte[] e; - - private Buffer buf; - private Packet packet; - - abstract byte[] G(); - abstract byte[] P(); - abstract String sha_name(); - - @Override - public void init(Session session, - byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{ - this.V_S=V_S; - this.V_C=V_C; - this.I_S=I_S; - this.I_C=I_C; - - try{ - Class c=Class.forName(session.getConfig(sha_name())).asSubclass(HASH.class); - sha=c.getDeclaredConstructor().newInstance(); - sha.init(); - } - catch(Exception e){ - System.err.println(e); - } - - buf=new Buffer(); - packet=new Packet(buf); - - try{ - Class c=Class.forName(session.getConfig("dh")).asSubclass(DH.class); - dh=c.getDeclaredConstructor().newInstance(); - dh.init(); - } - catch(Exception e){ - //System.err.println(e); - throw e; - } - - dh.setP(P()); - dh.setG(G()); - // The client responds with: - // byte SSH_MSG_KEXDH_INIT(30) - // mpint e <- g^x mod p - // x is a random number (1 < x < (p-1)/2) - - e=dh.getE(); - packet.reset(); - buf.putByte((byte)SSH_MSG_KEXDH_INIT); - buf.putMPInt(e); - - if(V_S==null){ // This is a really ugly hack for Session.checkKexes ;-( - return; - } - - session.write(packet); - - if(session.getLogger().isEnabled(Logger.INFO)){ - session.getLogger().log(Logger.INFO, - "SSH_MSG_KEXDH_INIT sent"); - session.getLogger().log(Logger.INFO, - "expecting SSH_MSG_KEXDH_REPLY"); - } - - state=SSH_MSG_KEXDH_REPLY; - } - - @Override - public boolean next(Buffer _buf) throws Exception{ - int i,j; - - switch(state){ - case SSH_MSG_KEXDH_REPLY: - // The server responds with: - // byte SSH_MSG_KEXDH_REPLY(31) - // string server public host key and certificates (K_S) - // mpint f - // string signature of H - j=_buf.getInt(); - j=_buf.getByte(); - j=_buf.getByte(); - if(j!=31){ - System.err.println("type: must be 31 "+j); - return false; - } - - K_S=_buf.getString(); - - byte[] f=_buf.getMPInt(); - byte[] sig_of_H=_buf.getString(); - - dh.setF(f); - - dh.checkRange(); - - K=normalize(dh.getK()); - - //The hash H is computed as the HASH hash of the concatenation of the - //following: - // string V_C, the client's version string (CR and NL excluded) - // string V_S, the server's version string (CR and NL excluded) - // string I_C, the payload of the client's SSH_MSG_KEXINIT - // string I_S, the payload of the server's SSH_MSG_KEXINIT - // string K_S, the host key - // mpint e, exchange value sent by the client - // mpint f, exchange value sent by the server - // mpint K, the shared secret - // This value is called the exchange hash, and it is used to authenti- - // cate the key exchange. - buf.reset(); - buf.putString(V_C); buf.putString(V_S); - buf.putString(I_C); buf.putString(I_S); - buf.putString(K_S); - buf.putMPInt(e); buf.putMPInt(f); - buf.putMPInt(K); - byte[] foo=new byte[buf.getLength()]; - buf.getByte(foo); - sha.update(foo, 0, foo.length); - H=sha.digest(); - //System.err.print("H -> "); //dump(H, 0, H.length); - - i=0; - j=0; - j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); - String alg=Util.byte2str(K_S, i, j); - i+=j; - - boolean result = verify(alg, K_S, i, sig_of_H); - - state=STATE_END; - return result; - } - return false; - } - - @Override - public int getState(){return state; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHXEC.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHXEC.java deleted file mode 100644 index eb6bd58a..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHXEC.java +++ /dev/null @@ -1,200 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -abstract class DHXEC extends KeyExchange{ - - private static final int SSH_MSG_KEX_ECDH_INIT = 30; - private static final int SSH_MSG_KEX_ECDH_REPLY= 31; - private int state; - - byte[] Q_C; - - byte[] V_S; - byte[] V_C; - byte[] I_S; - byte[] I_C; - - byte[] e; - - private Buffer buf; - private Packet packet; - - private XDH xdh; - - protected String sha_name; - protected String curve_name; - protected int key_len; - - @Override - public void init(Session session, - byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{ - this.V_S=V_S; - this.V_C=V_C; - this.I_S=I_S; - this.I_C=I_C; - - try{ - Class c=Class.forName(session.getConfig(sha_name)).asSubclass(HASH.class); - sha=c.getDeclaredConstructor().newInstance(); - sha.init(); - } - catch(Exception e){ - System.err.println(e); - } - - buf=new Buffer(); - packet=new Packet(buf); - - packet.reset(); - buf.putByte((byte)SSH_MSG_KEX_ECDH_INIT); - - try{ - Class c=Class.forName(session.getConfig("xdh")).asSubclass(XDH.class); - xdh=c.getDeclaredConstructor().newInstance(); - xdh.init(curve_name, key_len); - - Q_C = xdh.getQ(); - buf.putString(Q_C); - } - catch(Exception | NoClassDefFoundError e){ - throw new JSchException(e.toString(), e); - } - - if(V_S==null){ // This is a really ugly hack for Session.checkKexes ;-( - return; - } - - session.write(packet); - - if(session.getLogger().isEnabled(Logger.INFO)){ - session.getLogger().log(Logger.INFO, - "SSH_MSG_KEX_ECDH_INIT sent"); - session.getLogger().log(Logger.INFO, - "expecting SSH_MSG_KEX_ECDH_REPLY"); - } - - state=SSH_MSG_KEX_ECDH_REPLY; - } - - @Override - public boolean next(Buffer _buf) throws Exception{ - int i,j; - switch(state){ - case SSH_MSG_KEX_ECDH_REPLY: - // The server responds with: - // byte SSH_MSG_KEX_ECDH_REPLY - // string K_S, server's public host key - // string Q_S, server's ephemeral public key octet string - // string the signature on the exchange hash - j=_buf.getInt(); - j=_buf.getByte(); - j=_buf.getByte(); - if(j!=SSH_MSG_KEX_ECDH_REPLY){ - System.err.println("type: must be SSH_MSG_KEX_ECDH_REPLY "+j); - return false; - } - - K_S=_buf.getString(); - - byte[] Q_S=_buf.getString(); - - // RFC 5656, - // 4. ECDH Key Exchange - // All elliptic curve public keys MUST be validated after they are - // received. An example of a validation algorithm can be found in - // Section 3.2.2 of [SEC1]. If a key fails validation, - // the key exchange MUST fail. - if(!xdh.validate(Q_S)){ - return false; - } - - K = xdh.getSecret(Q_S); - K=normalize(K); - - byte[] sig_of_H=_buf.getString(); - - //The hash H is computed as the HASH hash of the concatenation of the - //following: - // string V_C, client's identification string (CR and LF excluded) - // string V_S, server's identification string (CR and LF excluded) - // string I_C, payload of the client's SSH_MSG_KEXINIT - // string I_S, payload of the server's SSH_MSG_KEXINIT - // string K_S, server's public host key - // string Q_C, client's ephemeral public key octet string - // string Q_S, server's ephemeral public key octet string - // mpint K, shared secret - - // This value is called the exchange hash, and it is used to authenti- - // cate the key exchange. - // RFC 8731, - // 3.1. Shared Secret Encoding - // The shared secret, K, is defined in [RFC4253] and [RFC5656] as an - // integer encoded as a multiple precision integer (mpint). - // Curve25519/448 outputs a binary string X, which is the 32- or 56-byte - // point obtained by scalar multiplication of the other side's public - // key and the local private key scalar. The 32 or 56 bytes of X are - // converted into K by interpreting the octets as an unsigned fixed- - // length integer encoded in network byte order. - // - // The mpint K is then encoded using the process described in Section 5 - // of [RFC4251], and the resulting bytes are fed as described in - // [RFC4253] to the key exchange method's hash function to generate - // encryption keys. - buf.reset(); - buf.putString(V_C); buf.putString(V_S); - buf.putString(I_C); buf.putString(I_S); - buf.putString(K_S); - buf.putString(Q_C); buf.putString(Q_S); - buf.putMPInt(K); - byte[] foo=new byte[buf.getLength()]; - buf.getByte(foo); - - sha.update(foo, 0, foo.length); - H=sha.digest(); - - i=0; - j=0; - j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); - String alg=Util.byte2str(K_S, i, j); - i+=j; - - boolean result = verify(alg, K_S, i, sig_of_H); - - state=STATE_END; - return result; - } - return false; - } - - @Override - public int getState(){return state; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ECDH.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ECDH.java deleted file mode 100644 index b92c31e5..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ECDH.java +++ /dev/null @@ -1,37 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -public interface ECDH { - void init(int size) throws Exception; - byte[] getSecret(byte[] r, byte[] s) throws Exception; - byte[] getQ() throws Exception; - boolean validate(byte[] r, byte[] s) throws Exception; -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ForwardedTCPIPDaemon.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ForwardedTCPIPDaemon.java deleted file mode 100644 index 2318c6c8..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ForwardedTCPIPDaemon.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; -import java.io.*; - -public interface ForwardedTCPIPDaemon extends Runnable{ - void setChannel(ChannelForwardedTCPIP channel, InputStream in, OutputStream out); - void setArg(Object[] arg); -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/GSSContext.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/GSSContext.java deleted file mode 100644 index 1c3864a5..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/GSSContext.java +++ /dev/null @@ -1,38 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2004-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -public interface GSSContext{ - public void create(String user, String host) throws JSchException; - public boolean isEstablished(); - public byte[] init(byte[] token, int s, int l) throws JSchException; - public byte[] getMIC(byte[] message, int s, int l); - public void dispose(); -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HASH.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HASH.java deleted file mode 100644 index 4a5ae817..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HASH.java +++ /dev/null @@ -1,38 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -public interface HASH{ - void init() throws Exception; - int getBlockSize(); - void update(byte[] foo, int start, int len) throws Exception; - byte[] digest() throws Exception; - default String name() {return "";} -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HostKey.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HostKey.java deleted file mode 100644 index c3d5ccd2..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HostKey.java +++ /dev/null @@ -1,150 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -public class HostKey{ - - private static final byte[][] names = { - Util.str2byte("ssh-dss"), - Util.str2byte("ssh-rsa"), - Util.str2byte("ecdsa-sha2-nistp256"), - Util.str2byte("ecdsa-sha2-nistp384"), - Util.str2byte("ecdsa-sha2-nistp521"), - Util.str2byte("ssh-ed25519"), - Util.str2byte("ssh-ed448") - }; - - public static final int UNKNOWN=-1; - public static final int GUESS=0; - public static final int SSHDSS=1; - public static final int SSHRSA=2; - public static final int ECDSA256=3; - public static final int ECDSA384=4; - public static final int ECDSA521=5; - public static final int ED25519=6; - public static final int ED448=7; - - protected String marker; - protected String host; - protected int type; - protected byte[] key; - protected String comment; - - public HostKey(String host, byte[] key) throws JSchException { - this(host, GUESS, key); - } - - public HostKey(String host, int type, byte[] key) throws JSchException { - this(host, type, key, null); - } - public HostKey(String host, int type, byte[] key, String comment) throws JSchException { - this("", host, type, key, comment); - } - public HostKey(String marker, String host, int type, byte[] key, String comment) throws JSchException { - this.marker=marker; - this.host=host; - if(type==GUESS){ - if(key[8]=='d'){ this.type=SSHDSS; } - else if(key[8]=='r'){ this.type=SSHRSA; } - else if(key[8]=='e' && key[10]=='2'){ this.type=ED25519; } - else if(key[8]=='e' && key[10]=='4'){ this.type=ED448; } - else if(key[8]=='a' && key[20]=='2'){ this.type=ECDSA256; } - else if(key[8]=='a' && key[20]=='3'){ this.type=ECDSA384; } - else if(key[8]=='a' && key[20]=='5'){ this.type=ECDSA521; } - else { throw new JSchException("invalid key type");} - } - else{ - this.type=type; - } - this.key=key; - this.comment=comment; - } - - public String getHost(){ return host; } - public String getType(){ - if(type==SSHDSS || - type==SSHRSA || - type==ED25519 || - type==ED448 || - type==ECDSA256 || - type==ECDSA384 || - type==ECDSA521){ - return Util.byte2str(names[type-1]); - } - return "UNKNOWN"; - } - protected static int name2type(String name){ - for(int i = 0; i < names.length; i++){ - if(Util.byte2str(names[i]).equals(name)){ - return i + 1; - } - } - return UNKNOWN; - } - public String getKey(){ - return Util.byte2str(Util.toBase64(key, 0, key.length, true)); - } - public String getFingerPrint(JSch jsch){ - HASH hash=null; - try{ - String _c=JSch.getConfig("FingerprintHash").toLowerCase(); - Class c=Class.forName(JSch.getConfig(_c)).asSubclass(HASH.class); - hash=c.getDeclaredConstructor().newInstance(); - } - catch(Exception e){ System.err.println("getFingerPrint: "+e); } - return Util.getFingerPrint(hash, key, false, true); - } - public String getComment(){ return comment; } - public String getMarker(){ return marker; } - - boolean isMatched(String _host){ - return isIncluded(_host); - } - - private boolean isIncluded(String _host){ - int i=0; - String hosts=this.host; - int hostslen=hosts.length(); - int hostlen=_host.length(); - int j; - while(ihost is included with the key. - * - * @return #NOT_INCLUDED, #OK or #CHANGED - * @see #NOT_INCLUDED - * @see #OK - * @see #CHANGED - */ - int check(String host, byte[] key); - - /** - * Adds a host key hostkey - * - * @param hostkey a host key to be added - * @param ui a user interface for showing messages or promping inputs. - * @see UserInfo - */ - void add(HostKey hostkey, UserInfo ui); - - /** - * Removes a host key if there exists mached key with - * host, type. - * - * @see #remove(String host, String type, byte[] key) - */ - void remove(String host, String type); - - /** - * Removes a host key if there exists a matched key with - * host, type and key. - */ - void remove(String host, String type, byte[] key); - - /** - * Returns id of this repository. - * - * @return identity in String - */ - String getKnownHostsRepositoryID(); - - /** - * Retuns a list for host keys managed in this repository. - * - * @see #getHostKey(String host, String type) - */ - HostKey[] getHostKey(); - - /** - * Retuns a list for host keys managed in this repository. - * - * @param host a hostname used in searching host keys. - * If null is given, every host key will be listed. - * @param type a key type used in searching host keys, - * and it should be "ssh-dss" or "ssh-rsa". - * If null is given, a key type type will not be ignored. - */ - HostKey[] getHostKey(String host, String type); -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IO.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IO.java deleted file mode 100644 index 8e63b46f..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IO.java +++ /dev/null @@ -1,133 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.io.*; -import java.net.SocketException; - -class IO{ - InputStream in; - OutputStream out; - OutputStream out_ext; - - private boolean in_dontclose=false; - private boolean out_dontclose=false; - private boolean out_ext_dontclose=false; - - void setOutputStream(OutputStream out){ this.out=out; } - void setOutputStream(OutputStream out, boolean dontclose){ - this.out_dontclose=dontclose; - setOutputStream(out); - } - void setExtOutputStream(OutputStream out){ this.out_ext=out; } - void setExtOutputStream(OutputStream out, boolean dontclose){ - this.out_ext_dontclose=dontclose; - setExtOutputStream(out); - } - void setInputStream(InputStream in){ this.in=in; } - void setInputStream(InputStream in, boolean dontclose){ - this.in_dontclose=dontclose; - setInputStream(in); - } - - void put(Packet p) throws IOException, SocketException { - out.write(p.buffer.buffer, 0, p.buffer.index); - out.flush(); - } - void put(byte[] array, int begin, int length) throws IOException { - out.write(array, begin, length); - out.flush(); - } - void put_ext(byte[] array, int begin, int length) throws IOException { - out_ext.write(array, begin, length); - out_ext.flush(); - } - - int getByte() throws IOException { - return in.read(); - } - - void getByte(byte[] array) throws IOException { - getByte(array, 0, array.length); - } - - void getByte(byte[] array, int begin, int length) throws IOException { - do{ - int completed = in.read(array, begin, length); - if(completed<0){ - throw new IOException("End of IO Stream Read"); - } - begin+=completed; - length-=completed; - } - while (length>0); - } - - void out_close(){ - try{ - if(out!=null && !out_dontclose) out.close(); - out=null; - } - catch(Exception ee){} - } - - void close(){ - try{ - if(in!=null && !in_dontclose) in.close(); - in=null; - } - catch(Exception ee){} - - out_close(); - - try{ - if(out_ext!=null && !out_ext_dontclose) out_ext.close(); - out_ext=null; - } - catch(Exception ee){} - } - - /* - void finalize() throws Throwable{ - try{ - if(in!=null) in.close(); - } - catch(Exception ee){} - try{ - if(out!=null) out.close(); - } - catch(Exception ee){} - try{ - if(out_ext!=null) out_ext.close(); - } - catch(Exception ee){} - } - */ -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Identity.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Identity.java deleted file mode 100644 index f42ad2ee..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Identity.java +++ /dev/null @@ -1,117 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -public interface Identity{ - - /** - * Decrypts this identity with the specified pass-phrase. - * @param passphrase the pass-phrase for this identity. - * @return true if the decryption is succeeded - * or this identity is not cyphered. - */ - public boolean setPassphrase(byte[] passphrase) throws JSchException; - - /** - * Returns the public-key blob. - * @return the public-key blob - */ - public byte[] getPublicKeyBlob(); - - /** - * Signs on data with this identity, and returns the result. - *

- * IMPORTANT NOTE: - *
- * The {@link #getSignature(byte[], String)} method should be overridden - * to ensure {@code ssh-rsa} type public keys function with the - * {@code rsa-sha2-256} or {@code rsa-sha2-512} signature algorithms. - *

- * @param data data to be signed - * @return the signature - * @see #getSignature(byte[], String) - */ - public byte[] getSignature(byte[] data); - - /** - * Signs on data with this identity, and returns the result. - *

- * IMPORTANT NOTE: - *
- * The default implementation of this method simply calls - * {@link #getSignature(byte[])}, which will fail with {@code ssh-rsa} - * type public keys when utilized with the {@code rsa-sha2-256} or - * {@code rsa-sha2-512} signature algorithms: - *
- * it exists only to maintain backwards compatibility of this interface. - *

- *

- * This default method should be overridden by implementations to - * ensure the {@code rsa-sha2-256} and {@code rsa-sha2-512} signature - * algorithms function correctly. - *

- * @param data data to be signed - * @param alg signature algorithm to use - * @return the signature - * @since 0.1.57 - * @see #getSignature(byte[]) - */ - public default byte[] getSignature(byte[] data, String alg) {return getSignature(data);} - - /** - * @deprecated The decryption should be done automatically in {@link #setPassphrase(byte[])} - * @see #setPassphrase(byte[]) - */ - @Deprecated - public boolean decrypt(); - - /** - * Returns the name of the key algorithm. - * @return "ssh-rsa" or "ssh-dss" - */ - public String getAlgName(); - - /** - * Returns the name of this identity. - * It will be useful to identify this object in the {@link IdentityRepository}. - */ - public String getName(); - - /** - * Returns true if this identity is cyphered. - * @return true if this identity is cyphered. - */ - public boolean isEncrypted(); - - /** - * Disposes internally allocated data, like byte array for the private key. - */ - public void clear(); -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityFile.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityFile.java deleted file mode 100644 index b46933b5..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityFile.java +++ /dev/null @@ -1,151 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.io.*; - -class IdentityFile implements Identity{ - private JSch jsch; - private KeyPair kpair; - private String identity; - - static IdentityFile newInstance(String prvfile, String pubfile, JSch jsch) throws JSchException{ - KeyPair kpair = KeyPair.load(jsch, prvfile, pubfile); - return new IdentityFile(jsch, prvfile, kpair); - } - - static IdentityFile newInstance(String name, byte[] prvkey, byte[] pubkey, JSch jsch) throws JSchException{ - - KeyPair kpair = KeyPair.load(jsch, prvkey, pubkey); - return new IdentityFile(jsch, name, kpair); - } - - private IdentityFile(JSch jsch, String name, KeyPair kpair) throws JSchException{ - this.jsch = jsch; - this.identity = name; - this.kpair = kpair; - } - - /** - * Decrypts this identity with the specified pass-phrase. - * @param passphrase the pass-phrase for this identity. - * @return true if the decryption is succeeded - * or this identity is not cyphered. - */ - @Override - public boolean setPassphrase(byte[] passphrase) throws JSchException{ - return kpair.decrypt(passphrase); - } - - /** - * Returns the public-key blob. - * @return the public-key blob - */ - @Override - public byte[] getPublicKeyBlob(){ - return kpair.getPublicKeyBlob(); - } - - /** - * Signs on data with this identity, and returns the result. - * @param data data to be signed - * @return the signature - */ - @Override - public byte[] getSignature(byte[] data){ - return kpair.getSignature(data); - } - - /** - * Signs on data with this identity, and returns the result. - * @param data data to be signed - * @param alg signature algorithm to use - * @return the signature - */ - @Override - public byte[] getSignature(byte[] data, String alg){ - return kpair.getSignature(data, alg); - } - - /** - * @deprecated This method should not be invoked. - * @see #setPassphrase(byte[] passphrase) - */ - @Override - @Deprecated - public boolean decrypt(){ - throw new RuntimeException("not implemented"); - } - - /** - * Returns the name of the key algorithm. - * @return "ssh-rsa" or "ssh-dss" - */ - @Override - public String getAlgName(){ - byte[] name = kpair.getKeyTypeName(); - return Util.byte2str(name); - } - - /** - * Returns the name of this identity. - * It will be useful to identify this object in the {@link IdentityRepository}. - */ - @Override - public String getName(){ - return identity; - } - - /** - * Returns true if this identity is cyphered. - * @return true if this identity is cyphered. - */ - @Override - public boolean isEncrypted(){ - return kpair.isEncrypted(); - } - - /** - * Disposes internally allocated data, like byte array for the private key. - */ - @Override - public void clear(){ - kpair.dispose(); - kpair = null; - } - - /** - * Returns an instance of {@link KeyPair} used in this {@link Identity}. - * @return an instance of {@link KeyPair} used in this {@link Identity}. - */ - public KeyPair getKeyPair(){ - return kpair; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityRepository.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityRepository.java deleted file mode 100644 index 895b0226..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityRepository.java +++ /dev/null @@ -1,44 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.util.Vector; - -public interface IdentityRepository { - public static final int UNAVAILABLE=0; - public static final int NOTRUNNING=1; - public static final int RUNNING=2; - public String getName(); - public int getStatus(); - public Vector getIdentities(); - public boolean add(byte[] identity); - public boolean remove(byte[] blob); - public void removeAll(); -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityRepositoryWrapper.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityRepositoryWrapper.java deleted file mode 100644 index 8ce08b4b..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityRepositoryWrapper.java +++ /dev/null @@ -1,109 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.util.Vector; - -/** - * JSch will accept ciphered keys, but some implementations of - * IdentityRepository can not. For example, IdentityRepository for - * ssh-agent and pageant only accept plain keys. The following class has - * been introduced to cache ciphered keys for them, and pass them - * whenever they are de-ciphered. - */ -class IdentityRepositoryWrapper implements IdentityRepository { - private IdentityRepository ir; - private Vector cache = new Vector<>(); - private boolean keep_in_cache = false; - IdentityRepositoryWrapper(IdentityRepository ir){ - this(ir, false); - } - IdentityRepositoryWrapper(IdentityRepository ir, boolean keep_in_cache){ - this.ir = ir; - this.keep_in_cache = keep_in_cache; - } - @Override - public String getName() { - return ir.getName(); - } - @Override - public int getStatus() { - return ir.getStatus(); - } - @Override - public boolean add(byte[] identity) { - return ir.add(identity); - } - @Override - public boolean remove(byte[] blob) { - return ir.remove(blob); - } - @Override - public void removeAll() { - cache.removeAllElements(); - ir.removeAll(); - } - @Override - public Vector getIdentities() { - Vector result = new Vector<>(); - for(int i = 0; i< cache.size(); i++){ - Identity identity = cache.elementAt(i); - result.add(identity); - } - Vector tmp = ir.getIdentities(); - for(int i = 0; i< tmp.size(); i++){ - result.add(tmp.elementAt(i)); - } - return result; - } - void add(Identity identity) { - if(!keep_in_cache && - !identity.isEncrypted() && (identity instanceof IdentityFile)) { - try { - ir.add(((IdentityFile)identity).getKeyPair().forSSHAgent()); - } - catch(JSchException e){ - // an exception will not be thrown. - } - } - else - cache.addElement(identity); - } - void check() { - if(cache.size() > 0){ - Object[] identities = cache.toArray(); - for(int i = 0; i < identities.length; i++){ - Identity identity = (Identity)(identities[i]); - cache.removeElement(identity); - add(identity); - } - } - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSch.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSch.java deleted file mode 100644 index f053e233..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSch.java +++ /dev/null @@ -1,716 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.io.InputStream; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -public class JSch{ - /** - * The version number. - */ - public static final String VERSION = Version.getVersion(); - - static Hashtable config=new Hashtable<>(); - static{ - config.put("kex", Util.getSystemProperty("jsch.kex", "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256")); - config.put("server_host_key", Util.getSystemProperty("jsch.server_host_key", "ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256")); - config.put("prefer_known_host_key_types", Util.getSystemProperty("jsch.prefer_known_host_key_types", "yes")); - config.put("enable_server_sig_algs", Util.getSystemProperty("jsch.enable_server_sig_algs", "yes")); - config.put("cipher.s2c", Util.getSystemProperty("jsch.cipher", "aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com")); - config.put("cipher.c2s", Util.getSystemProperty("jsch.cipher", "aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com")); - config.put("mac.s2c", Util.getSystemProperty("jsch.mac", "hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1")); - config.put("mac.c2s", Util.getSystemProperty("jsch.mac", "hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1")); - config.put("compression.s2c", Util.getSystemProperty("jsch.compression", "none")); - config.put("compression.c2s", Util.getSystemProperty("jsch.compression", "none")); - - config.put("lang.s2c", Util.getSystemProperty("jsch.lang", "")); - config.put("lang.c2s", Util.getSystemProperty("jsch.lang", "")); - - config.put("dhgex_min", Util.getSystemProperty("jsch.dhgex_min", "2048")); - config.put("dhgex_max", Util.getSystemProperty("jsch.dhgex_max", "8192")); - config.put("dhgex_preferred", Util.getSystemProperty("jsch.dhgex_preferred", "3072")); - - config.put("compression_level", Util.getSystemProperty("jsch.compression_level", "6")); - - config.put("diffie-hellman-group-exchange-sha1", - "com.jcraft.jsch.DHGEX1"); - config.put("diffie-hellman-group1-sha1", - "com.jcraft.jsch.DHG1"); - config.put("diffie-hellman-group14-sha1", - "com.jcraft.jsch.DHG14"); - config.put("diffie-hellman-group-exchange-sha256", - "com.jcraft.jsch.DHGEX256"); - config.put("diffie-hellman-group-exchange-sha224@ssh.com", - "com.jcraft.jsch.DHGEX224"); - config.put("diffie-hellman-group-exchange-sha384@ssh.com", - "com.jcraft.jsch.DHGEX384"); - config.put("diffie-hellman-group-exchange-sha512@ssh.com", - "com.jcraft.jsch.DHGEX512"); - config.put("diffie-hellman-group14-sha256", - "com.jcraft.jsch.DHG14256"); - config.put("diffie-hellman-group15-sha512", - "com.jcraft.jsch.DHG15"); - config.put("diffie-hellman-group16-sha512", - "com.jcraft.jsch.DHG16"); - config.put("diffie-hellman-group17-sha512", - "com.jcraft.jsch.DHG17"); - config.put("diffie-hellman-group18-sha512", - "com.jcraft.jsch.DHG18"); - config.put("diffie-hellman-group14-sha256@ssh.com", - "com.jcraft.jsch.DHG14256"); - config.put("diffie-hellman-group14-sha224@ssh.com", - "com.jcraft.jsch.DHG14224"); - config.put("diffie-hellman-group15-sha256@ssh.com", - "com.jcraft.jsch.DHG15256"); - config.put("diffie-hellman-group15-sha384@ssh.com", - "com.jcraft.jsch.DHG15384"); - config.put("diffie-hellman-group16-sha512@ssh.com", - "com.jcraft.jsch.DHG16"); - config.put("diffie-hellman-group16-sha384@ssh.com", - "com.jcraft.jsch.DHG16384"); - config.put("diffie-hellman-group18-sha512@ssh.com", - "com.jcraft.jsch.DHG18"); - config.put("ecdsa-sha2-nistp256", "com.jcraft.jsch.jce.SignatureECDSA256"); - config.put("ecdsa-sha2-nistp384", "com.jcraft.jsch.jce.SignatureECDSA384"); - config.put("ecdsa-sha2-nistp521", "com.jcraft.jsch.jce.SignatureECDSA521"); - - config.put("ecdh-sha2-nistp256", "com.jcraft.jsch.DHEC256"); - config.put("ecdh-sha2-nistp384", "com.jcraft.jsch.DHEC384"); - config.put("ecdh-sha2-nistp521", "com.jcraft.jsch.DHEC521"); - - config.put("ecdh-sha2-nistp", "com.jcraft.jsch.jce.ECDHN"); - - config.put("curve25519-sha256", "com.jcraft.jsch.DH25519"); - config.put("curve25519-sha256@libssh.org", "com.jcraft.jsch.DH25519"); - config.put("curve448-sha512", "com.jcraft.jsch.DH448"); - - config.put("dh", "com.jcraft.jsch.jce.DH"); - config.put("3des-cbc", "com.jcraft.jsch.jce.TripleDESCBC"); - config.put("blowfish-cbc", "com.jcraft.jsch.jce.BlowfishCBC"); - config.put("hmac-sha1", "com.jcraft.jsch.jce.HMACSHA1"); - config.put("hmac-sha1-96", "com.jcraft.jsch.jce.HMACSHA196"); - config.put("hmac-sha2-256", "com.jcraft.jsch.jce.HMACSHA256"); - config.put("hmac-sha2-512", "com.jcraft.jsch.jce.HMACSHA512"); - config.put("hmac-md5", "com.jcraft.jsch.jce.HMACMD5"); - config.put("hmac-md5-96", "com.jcraft.jsch.jce.HMACMD596"); - config.put("hmac-sha1-etm@openssh.com", "com.jcraft.jsch.jce.HMACSHA1ETM"); - config.put("hmac-sha1-96-etm@openssh.com", "com.jcraft.jsch.jce.HMACSHA196ETM"); - config.put("hmac-sha2-256-etm@openssh.com", "com.jcraft.jsch.jce.HMACSHA256ETM"); - config.put("hmac-sha2-512-etm@openssh.com", "com.jcraft.jsch.jce.HMACSHA512ETM"); - config.put("hmac-md5-etm@openssh.com", "com.jcraft.jsch.jce.HMACMD5ETM"); - config.put("hmac-md5-96-etm@openssh.com", "com.jcraft.jsch.jce.HMACMD596ETM"); - config.put("hmac-sha256-2@ssh.com", "com.jcraft.jsch.jce.HMACSHA2562SSHCOM"); - config.put("hmac-sha224@ssh.com", "com.jcraft.jsch.jce.HMACSHA224SSHCOM"); - config.put("hmac-sha256@ssh.com", "com.jcraft.jsch.jce.HMACSHA256SSHCOM"); - config.put("hmac-sha384@ssh.com", "com.jcraft.jsch.jce.HMACSHA384SSHCOM"); - config.put("hmac-sha512@ssh.com", "com.jcraft.jsch.jce.HMACSHA512SSHCOM"); - config.put("sha-1", "com.jcraft.jsch.jce.SHA1"); - config.put("sha-224", "com.jcraft.jsch.jce.SHA224"); - config.put("sha-256", "com.jcraft.jsch.jce.SHA256"); - config.put("sha-384", "com.jcraft.jsch.jce.SHA384"); - config.put("sha-512", "com.jcraft.jsch.jce.SHA512"); - config.put("md5", "com.jcraft.jsch.jce.MD5"); - config.put("sha1", "com.jcraft.jsch.jce.SHA1"); - config.put("sha224", "com.jcraft.jsch.jce.SHA224"); - config.put("sha256", "com.jcraft.jsch.jce.SHA256"); - config.put("sha384", "com.jcraft.jsch.jce.SHA384"); - config.put("sha512", "com.jcraft.jsch.jce.SHA512"); - config.put("signature.dss", "com.jcraft.jsch.jce.SignatureDSA"); - config.put("ssh-rsa", "com.jcraft.jsch.jce.SignatureRSA"); - config.put("rsa-sha2-256", "com.jcraft.jsch.jce.SignatureRSASHA256"); - config.put("rsa-sha2-512", "com.jcraft.jsch.jce.SignatureRSASHA512"); - config.put("ssh-rsa-sha224@ssh.com", "com.jcraft.jsch.jce.SignatureRSASHA224SSHCOM"); - config.put("ssh-rsa-sha256@ssh.com", "com.jcraft.jsch.jce.SignatureRSASHA256SSHCOM"); - config.put("ssh-rsa-sha384@ssh.com", "com.jcraft.jsch.jce.SignatureRSASHA384SSHCOM"); - config.put("ssh-rsa-sha512@ssh.com", "com.jcraft.jsch.jce.SignatureRSASHA512SSHCOM"); - config.put("keypairgen.dsa", "com.jcraft.jsch.jce.KeyPairGenDSA"); - config.put("keypairgen.rsa", "com.jcraft.jsch.jce.KeyPairGenRSA"); - config.put("keypairgen.ecdsa", "com.jcraft.jsch.jce.KeyPairGenECDSA"); - config.put("random", "com.jcraft.jsch.jce.Random"); - - config.put("hmac-ripemd160", "com.jcraft.jsch.bc.HMACRIPEMD160"); - config.put("hmac-ripemd160@openssh.com", "com.jcraft.jsch.bc.HMACRIPEMD160OpenSSH"); - config.put("hmac-ripemd160-etm@openssh.com", "com.jcraft.jsch.bc.HMACRIPEMD160ETM"); - - config.put("none", "com.jcraft.jsch.CipherNone"); - - config.put("aes128-gcm@openssh.com", "com.jcraft.jsch.jce.AES128GCM"); - config.put("aes256-gcm@openssh.com", "com.jcraft.jsch.jce.AES256GCM"); - - config.put("aes128-cbc", "com.jcraft.jsch.jce.AES128CBC"); - config.put("aes192-cbc", "com.jcraft.jsch.jce.AES192CBC"); - config.put("aes256-cbc", "com.jcraft.jsch.jce.AES256CBC"); - config.put("rijndael-cbc@lysator.liu.se", "com.jcraft.jsch.jce.AES256CBC"); - - config.put("chacha20-poly1305@openssh.com", "com.jcraft.jsch.bc.ChaCha20Poly1305"); - config.put("cast128-cbc", "com.jcraft.jsch.bc.CAST128CBC"); - config.put("cast128-ctr", "com.jcraft.jsch.bc.CAST128CTR"); - config.put("twofish128-cbc", "com.jcraft.jsch.bc.Twofish128CBC"); - config.put("twofish192-cbc", "com.jcraft.jsch.bc.Twofish192CBC"); - config.put("twofish256-cbc", "com.jcraft.jsch.bc.Twofish256CBC"); - config.put("twofish-cbc", "com.jcraft.jsch.bc.Twofish256CBC"); - config.put("twofish128-ctr", "com.jcraft.jsch.bc.Twofish128CTR"); - config.put("twofish192-ctr", "com.jcraft.jsch.bc.Twofish192CTR"); - config.put("twofish256-ctr", "com.jcraft.jsch.bc.Twofish256CTR"); - config.put("seed-cbc@ssh.com", "com.jcraft.jsch.bc.SEEDCBC"); - - config.put("aes128-ctr", "com.jcraft.jsch.jce.AES128CTR"); - config.put("aes192-ctr", "com.jcraft.jsch.jce.AES192CTR"); - config.put("aes256-ctr", "com.jcraft.jsch.jce.AES256CTR"); - config.put("3des-ctr", "com.jcraft.jsch.jce.TripleDESCTR"); - config.put("blowfish-ctr", "com.jcraft.jsch.jce.BlowfishCTR"); - config.put("arcfour", "com.jcraft.jsch.jce.ARCFOUR"); - config.put("arcfour128", "com.jcraft.jsch.jce.ARCFOUR128"); - config.put("arcfour256", "com.jcraft.jsch.jce.ARCFOUR256"); - - config.put("userauth.none", "com.jcraft.jsch.UserAuthNone"); - config.put("userauth.password", "com.jcraft.jsch.UserAuthPassword"); - config.put("userauth.keyboard-interactive", "com.jcraft.jsch.UserAuthKeyboardInteractive"); - config.put("userauth.publickey", "com.jcraft.jsch.UserAuthPublicKey"); - config.put("userauth.gssapi-with-mic", "com.jcraft.jsch.UserAuthGSSAPIWithMIC"); - config.put("gssapi-with-mic.krb5", "com.jcraft.jsch.jgss.GSSContextKrb5"); - - config.put("zlib", "com.jcraft.jsch.jzlib.Compression"); - config.put("zlib@openssh.com", "com.jcraft.jsch.jzlib.Compression"); - - config.put("pbkdf", "com.jcraft.jsch.jce.PBKDF"); - - if(JavaVersion.getVersion()>=11){ - config.put("xdh", "com.jcraft.jsch.jce.XDH"); - } - else{ - config.put("xdh", "com.jcraft.jsch.bc.XDH"); - } - - if(JavaVersion.getVersion()>=15){ - config.put("keypairgen.eddsa", "com.jcraft.jsch.jce.KeyPairGenEdDSA"); - config.put("ssh-ed25519", "com.jcraft.jsch.jce.SignatureEd25519"); - config.put("ssh-ed448", "com.jcraft.jsch.jce.SignatureEd448"); - } - else{ - config.put("keypairgen.eddsa", "com.jcraft.jsch.bc.KeyPairGenEdDSA"); - config.put("ssh-ed25519", "com.jcraft.jsch.bc.SignatureEd25519"); - config.put("ssh-ed448", "com.jcraft.jsch.bc.SignatureEd448"); - } - - config.put("StrictHostKeyChecking", "ask"); - config.put("HashKnownHosts", "no"); - - config.put("PreferredAuthentications", Util.getSystemProperty("jsch.preferred_authentications", "gssapi-with-mic,publickey,keyboard-interactive,password")); - config.put("PubkeyAcceptedAlgorithms", Util.getSystemProperty("jsch.client_pubkey", "ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256")); - - config.put("CheckCiphers", Util.getSystemProperty("jsch.check_ciphers", "chacha20-poly1305@openssh.com")); - config.put("CheckMacs", Util.getSystemProperty("jsch.check_macs", "")); - config.put("CheckKexes", Util.getSystemProperty("jsch.check_kexes", "curve25519-sha256,curve25519-sha256@libssh.org,curve448-sha512")); - config.put("CheckSignatures", Util.getSystemProperty("jsch.check_signatures", "ssh-ed25519,ssh-ed448")); - config.put("FingerprintHash", Util.getSystemProperty("jsch.fingerprint_hash", "sha256")); - - config.put("MaxAuthTries", Util.getSystemProperty("jsch.max_auth_tries", "6")); - config.put("ClearAllForwardings", "no"); - } - - private Vector sessionPool = new Vector<>(); - - private IdentityRepository defaultIdentityRepository = - new LocalIdentityRepository(this); - - private IdentityRepository identityRepository = defaultIdentityRepository; - - private ConfigRepository configRepository = null; - - /** - * Sets the identityRepository, which will be referred - * in the public key authentication. - * - * @param identityRepository if null is given, - * the default repository, which usually refers to ~/.ssh/, will be used. - * - * @see #getIdentityRepository() - */ - public synchronized void setIdentityRepository(IdentityRepository identityRepository){ - if(identityRepository == null){ - this.identityRepository = defaultIdentityRepository; - } - else{ - this.identityRepository = identityRepository; - } - } - - public synchronized IdentityRepository getIdentityRepository(){ - return this.identityRepository; - } - - public ConfigRepository getConfigRepository() { - return this.configRepository; - } - - public void setConfigRepository(ConfigRepository configRepository) { - this.configRepository = configRepository; - } - - private HostKeyRepository known_hosts=null; - - static final Logger DEVNULL=new Logger(){ - @Override - public boolean isEnabled(int level){return false;} - @Override - public void log(int level, String message){} - }; - static Logger logger=DEVNULL; - private Logger instLogger; - - public JSch(){ - } - - /** - * Instantiates the Session object with - * host. The user name and port number will be retrieved from - * ConfigRepository. If user name is not given, - * the system property "user.name" will be referred. - * - * @param host hostname - * - * @throws JSchException - * if username or host are invalid. - * - * @return the instance of Session class. - * - * @see #getSession(String username, String host, int port) - * @see com.jcraft.jsch.Session - * @see com.jcraft.jsch.ConfigRepository - */ - public Session getSession(String host) - throws JSchException { - return getSession(null, host, 22); - } - - /** - * Instantiates the Session object with - * username and host. - * The TCP port 22 will be used in making the connection. - * Note that the TCP connection must not be established - * until Session#connect(). - * - * @param username user name - * @param host hostname - * - * @throws JSchException - * if username or host are invalid. - * - * @return the instance of Session class. - * - * @see #getSession(String username, String host, int port) - * @see com.jcraft.jsch.Session - */ - public Session getSession(String username, String host) - throws JSchException { - return getSession(username, host, 22); - } - - /** - * Instantiates the Session object with given - * username, host and port. - * Note that the TCP connection must not be established - * until Session#connect(). - * - * @param username user name - * @param host hostname - * @param port port number - * - * @throws JSchException - * if username or host are invalid. - * - * @return the instance of Session class. - * - * @see #getSession(String username, String host, int port) - * @see com.jcraft.jsch.Session - */ - public Session getSession(String username, String host, int port) throws JSchException { - if(host==null){ - throw new JSchException("host must not be null."); - } - Session s = new Session(this, username, host, port); - return s; - } - - protected void addSession(Session session){ - synchronized(sessionPool){ - sessionPool.addElement(session); - } - } - - protected boolean removeSession(Session session){ - synchronized(sessionPool){ - return sessionPool.remove(session); - } - } - - /** - * Sets the hostkey repository. - * - * @param hkrepo - * - * @see com.jcraft.jsch.HostKeyRepository - * @see com.jcraft.jsch.KnownHosts - */ - public void setHostKeyRepository(HostKeyRepository hkrepo){ - known_hosts=hkrepo; - } - - /** - * Sets the instance of KnownHosts, which refers - * to filename. - * - * @param filename filename of known_hosts file. - * - * @throws JSchException - * if the given filename is invalid. - * - * @see com.jcraft.jsch.KnownHosts - */ - public void setKnownHosts(String filename) throws JSchException{ - if(known_hosts==null) known_hosts=new KnownHosts(this); - if(known_hosts instanceof KnownHosts){ - synchronized(known_hosts){ - ((KnownHosts)known_hosts).setKnownHosts(filename); - } - } - } - - /** - * Sets the instance of KnownHosts generated with - * stream. - * - * @param stream the instance of InputStream from known_hosts file. - * - * @throws JSchException - * if an I/O error occurs. - * - * @see com.jcraft.jsch.KnownHosts - */ - public void setKnownHosts(InputStream stream) throws JSchException{ - if(known_hosts==null) known_hosts=new KnownHosts(this); - if(known_hosts instanceof KnownHosts){ - synchronized(known_hosts){ - ((KnownHosts)known_hosts).setKnownHosts(stream); - } - } - } - - /** - * Returns the current hostkey repository. - * By the default, this method will the instance of KnownHosts. - * - * @return current hostkey repository. - * - * @see com.jcraft.jsch.HostKeyRepository - * @see com.jcraft.jsch.KnownHosts - */ - public HostKeyRepository getHostKeyRepository(){ - if(known_hosts==null) known_hosts=new KnownHosts(this); - return known_hosts; - } - - /** - * Sets the private key, which will be referred in - * the public key authentication. - * - * @param prvkey filename of the private key. - * - * @throws JSchException if prvkey is invalid. - * - * @see #addIdentity(String prvkey, String passphrase) - */ - public void addIdentity(String prvkey) throws JSchException{ - addIdentity(prvkey, (byte[])null); - } - - /** - * Sets the private key, which will be referred in - * the public key authentication. - * Before registering it into identityRepository, - * it will be deciphered with passphrase. - * - * @param prvkey filename of the private key. - * @param passphrase passphrase for prvkey. - * - * @throws JSchException if passphrase is not right. - * - * @see #addIdentity(String prvkey, byte[] passphrase) - */ - public void addIdentity(String prvkey, String passphrase) throws JSchException{ - byte[] _passphrase=null; - if(passphrase!=null){ - _passphrase=Util.str2byte(passphrase); - } - addIdentity(prvkey, _passphrase); - if(_passphrase!=null) - Util.bzero(_passphrase); - } - - /** - * Sets the private key, which will be referred in - * the public key authentication. - * Before registering it into identityRepository, - * it will be deciphered with passphrase. - * - * @param prvkey filename of the private key. - * @param passphrase passphrase for prvkey. - * - * @throws JSchException if passphrase is not right. - * - * @see #addIdentity(String prvkey, String pubkey, byte[] passphrase) - */ - public void addIdentity(String prvkey, byte[] passphrase) throws JSchException{ - Identity identity=IdentityFile.newInstance(prvkey, null, this); - addIdentity(identity, passphrase); - } - - /** - * Sets the private key, which will be referred in - * the public key authentication. - * Before registering it into identityRepository, - * it will be deciphered with passphrase. - * - * @param prvkey filename of the private key. - * @param pubkey filename of the public key. - * @param passphrase passphrase for prvkey. - * - * @throws JSchException if passphrase is not right. - */ - public void addIdentity(String prvkey, String pubkey, byte[] passphrase) throws JSchException{ - Identity identity=IdentityFile.newInstance(prvkey, pubkey, this); - addIdentity(identity, passphrase); - } - - /** - * Sets the private key, which will be referred in - * the public key authentication. - * Before registering it into identityRepository, - * it will be deciphered with passphrase. - * - * @param name name of the identity to be used to - retrieve it in the identityRepository. - * @param prvkey private key in byte array. - * @param pubkey public key in byte array. - * @param passphrase passphrase for prvkey. - * - */ - public void addIdentity(String name, byte[]prvkey, byte[]pubkey, byte[] passphrase) throws JSchException{ - Identity identity=IdentityFile.newInstance(name, prvkey, pubkey, this); - addIdentity(identity, passphrase); - } - - /** - * Sets the private key, which will be referred in - * the public key authentication. - * Before registering it into identityRepository, - * it will be deciphered with passphrase. - * - * @param identity private key. - * @param passphrase passphrase for identity. - * - * @throws JSchException if passphrase is not right. - */ - public void addIdentity(Identity identity, byte[] passphrase) throws JSchException{ - if(passphrase!=null){ - try{ - byte[] goo=new byte[passphrase.length]; - System.arraycopy(passphrase, 0, goo, 0, passphrase.length); - passphrase=goo; - identity.setPassphrase(passphrase); - } - finally{ - Util.bzero(passphrase); - } - } - - if(identityRepository instanceof LocalIdentityRepository){ - ((LocalIdentityRepository)identityRepository).add(identity); - } - else if(identity instanceof IdentityFile && !identity.isEncrypted()) { - identityRepository.add(((IdentityFile)identity).getKeyPair().forSSHAgent()); - } - else { - synchronized(this){ - if(!(identityRepository instanceof IdentityRepositoryWrapper)){ - setIdentityRepository(new IdentityRepositoryWrapper(identityRepository)); - } - } - ((IdentityRepositoryWrapper)identityRepository).add(identity); - } - } - - /** - * @deprecated use #removeIdentity(Identity identity) - */ - @Deprecated - public void removeIdentity(String name) throws JSchException{ - Vector identities = identityRepository.getIdentities(); - for(int i=0; iidentity is invalid. - */ - public void removeIdentity(Identity identity) throws JSchException{ - identityRepository.remove(identity.getPublicKeyBlob()); - } - - /** - * Lists names of identities included in the identityRepository. - * - * @return names of identities - * - * @throws JSchException if identityReposory has problems. - */ - public Vector getIdentityNames() throws JSchException{ - Vector foo=new Vector<>(); - Vector identities = identityRepository.getIdentities(); - for(int i=0; i newconf){ - synchronized(config){ - for(Enumeration e=newconf.keys() ; e.hasMoreElements() ;) { - String newkey=e.nextElement(); - String key=(newkey.equals("PubkeyAcceptedKeyTypes") ? "PubkeyAcceptedAlgorithms" : newkey); - config.put(key, newconf.get(newkey)); - } - } - } - - /** - * Sets or Overrides the configuration. - * - * @param key key for the configuration - * @param value value for the configuration - */ - public static void setConfig(String key, String value){ - if(key.equals("PubkeyAcceptedKeyTypes")){ - config.put("PubkeyAcceptedAlgorithms", value); - } - else{ - config.put(key, value); - } - } - - /** - * Sets the logger - * - * @param logger logger or null if no logging - * should take place - * - * @see com.jcraft.jsch.Logger - */ - public static void setLogger(Logger logger){ - if(logger==null) logger=DEVNULL; - JSch.logger=logger; - } - - /** - * Returns a logger to be used for this particular instance of JSch - * @return The logger that is used by this instance. If no particular - * logger has been set, the statically set logger is returned. - */ - public Logger getInstanceLogger() { - if (this.instLogger == null) { - return logger; - } - return instLogger; - } - - /** - * Sets a logger to be used for this particular instance of JSch - * @param logger The logger to be used or null if - * the statically set logger should be used - */ - public void setInstanceLogger(Logger logger) { - this.instLogger = logger; - } - - /** - * Returns the statically set logger, i.e. the logger being - * used by all JSch instances without explicitly set logger. - * @return The logger - */ - public static Logger getLogger(){ - return logger; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchAlgoNegoFailException.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchAlgoNegoFailException.java deleted file mode 100644 index fbdbf446..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchAlgoNegoFailException.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.jcraft.jsch; - -/** - * Extension of {@link JSchException} to indicate when a connection fails during algorithm - * negotiation. - */ -public class JSchAlgoNegoFailException extends JSchException { - - private static final long serialVersionUID = -1L; - - private final String algorithmName; - private final String jschProposal; - private final String serverProposal; - - JSchAlgoNegoFailException(int algorithmIndex, String jschProposal, String serverProposal) { - super(failString(algorithmIndex, jschProposal, serverProposal)); - algorithmName = algorithmNameFromIndex(algorithmIndex); - this.jschProposal = jschProposal; - this.serverProposal = serverProposal; - } - - /** Get the algorithm name. */ - public String getAlgorithmName() { - return algorithmName; - } - - /** Get the JSch algorithm proposal. */ - public String getJSchProposal() { - return jschProposal; - } - - /** Get the server algorithm proposal. */ - public String getServerProposal() { - return serverProposal; - } - - private static String failString(int algorithmIndex, String jschProposal, String serverProposal) { - return String.format( - "Algorithm negotiation fail: algorithmName=\"%s\" jschProposal=\"%s\" serverProposal=\"%s\"", - algorithmNameFromIndex(algorithmIndex), jschProposal, serverProposal); - } - - private static String algorithmNameFromIndex(int algorithmIndex) { - switch (algorithmIndex) { - case KeyExchange.PROPOSAL_KEX_ALGS: - return "kex"; - case KeyExchange.PROPOSAL_SERVER_HOST_KEY_ALGS: - return "server_host_key"; - case KeyExchange.PROPOSAL_ENC_ALGS_CTOS: - return "cipher.c2s"; - case KeyExchange.PROPOSAL_ENC_ALGS_STOC: - return "cipher.s2c"; - case KeyExchange.PROPOSAL_MAC_ALGS_CTOS: - return "mac.c2s"; - case KeyExchange.PROPOSAL_MAC_ALGS_STOC: - return "mac.s2c"; - case KeyExchange.PROPOSAL_COMP_ALGS_CTOS: - return "compression.c2s"; - case KeyExchange.PROPOSAL_COMP_ALGS_STOC: - return "compression.s2c"; - case KeyExchange.PROPOSAL_LANG_CTOS: - return "lang.c2s"; - case KeyExchange.PROPOSAL_LANG_STOC: - return "lang.s2c"; - default: - return ""; - } - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchAuthCancelException.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchAuthCancelException.java deleted file mode 100644 index 288f4b51..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchAuthCancelException.java +++ /dev/null @@ -1,45 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class JSchAuthCancelException extends JSchException{ - private static final long serialVersionUID=-1L; - String method; - JSchAuthCancelException () { - super(); - } - JSchAuthCancelException (String s) { - super(s); - this.method=s; - } - public String getMethod(){ - return method; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchException.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchException.java deleted file mode 100644 index c55b4f16..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -public class JSchException extends Exception{ - private static final long serialVersionUID=-1L; - public JSchException () { - super(); - } - public JSchException (String s) { - super(s); - } - public JSchException (String s, Throwable e) { - super(s, e); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchPartialAuthException.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchPartialAuthException.java deleted file mode 100644 index ce5c29a6..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchPartialAuthException.java +++ /dev/null @@ -1,45 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class JSchPartialAuthException extends JSchException{ - private static final long serialVersionUID=-1L; - String methods; - public JSchPartialAuthException () { - super(); - } - public JSchPartialAuthException (String s) { - super(s); - this.methods=s; - } - public String getMethods(){ - return methods; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JavaVersion.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JavaVersion.java deleted file mode 100644 index b6184b14..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JavaVersion.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.jcraft.jsch; - -final class JavaVersion { - - static int getVersion() { - return 8; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JulLogger.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JulLogger.java deleted file mode 100644 index 9316d2fa..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JulLogger.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.jcraft.jsch; - -import java.util.logging.Level; -import java.util.logging.Logger; - -public class JulLogger implements com.jcraft.jsch.Logger { - - private static final Logger stlogger = Logger.getLogger(JSch.class.getName()); - private final Logger logger; - - public JulLogger() { - this(stlogger); - } - - JulLogger(Logger logger) { - this.logger = logger; - } - - @Override - public boolean isEnabled(int level) { - return logger.isLoggable(getLevel(level)); - } - - @Override - public void log(int level, String message) { - log(level, message, null); - } - - @Override - public void log(int level, String message, Throwable cause) { - if (cause == null) { - logger.log(getLevel(level), message); - return; - } - logger.log(getLevel(level), message, cause); - } - - static Level getLevel(int level) { - switch (level) { - case com.jcraft.jsch.Logger.DEBUG: - return Level.FINE; - case com.jcraft.jsch.Logger.INFO: - return Level.INFO; - case com.jcraft.jsch.Logger.WARN: - return Level.WARNING; - case com.jcraft.jsch.Logger.ERROR: - case com.jcraft.jsch.Logger.FATAL: - return Level.SEVERE; - default: - return Level.FINER; - } - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyExchange.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyExchange.java deleted file mode 100644 index 251b312d..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyExchange.java +++ /dev/null @@ -1,398 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -public abstract class KeyExchange{ - - static final int PROPOSAL_KEX_ALGS=0; - static final int PROPOSAL_SERVER_HOST_KEY_ALGS=1; - static final int PROPOSAL_ENC_ALGS_CTOS=2; - static final int PROPOSAL_ENC_ALGS_STOC=3; - static final int PROPOSAL_MAC_ALGS_CTOS=4; - static final int PROPOSAL_MAC_ALGS_STOC=5; - static final int PROPOSAL_COMP_ALGS_CTOS=6; - static final int PROPOSAL_COMP_ALGS_STOC=7; - static final int PROPOSAL_LANG_CTOS=8; - static final int PROPOSAL_LANG_STOC=9; - static final int PROPOSAL_MAX=10; - - //static String kex_algs="diffie-hellman-group-exchange-sha1"+ - // ",diffie-hellman-group1-sha1"; - -//static String kex="diffie-hellman-group-exchange-sha1"; - static String kex="diffie-hellman-group1-sha1"; - static String server_host_key="ssh-rsa,ssh-dss"; - static String enc_c2s="blowfish-cbc"; - static String enc_s2c="blowfish-cbc"; - static String mac_c2s="hmac-md5"; // hmac-md5,hmac-sha1,hmac-ripemd160, - // hmac-sha1-96,hmac-md5-96 - static String mac_s2c="hmac-md5"; -//static String comp_c2s="none"; // zlib -//static String comp_s2c="none"; - static String lang_c2s=""; - static String lang_s2c=""; - - public static final int STATE_END=0; - - protected Session session=null; - protected HASH sha=null; - protected byte[] K=null; - protected byte[] H=null; - protected byte[] K_S=null; - - public abstract void init(Session session, - byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception; - void doInit(Session session, - byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception { - this.session = session; - init(session, V_S, V_C, I_S, I_C); - } - public abstract boolean next(Buffer buf) throws Exception; - - public abstract int getState(); - - protected final int RSA=0; - protected final int DSS=1; - protected final int ECDSA=2; - protected final int EDDSA=3; - private int type=0; - private String key_alg_name = ""; - - public String getKeyType() { - if(type==DSS) return "DSA"; - if(type==RSA) return "RSA"; - if(type==EDDSA) return "EDDSA"; - return "ECDSA"; - } - - public String getKeyAlgorithName() { - return key_alg_name; - } - - protected static String[] guess(Session session, byte[]I_S, byte[]I_C) throws Exception{ - String[] guess=new String[PROPOSAL_MAX]; - Buffer sb=new Buffer(I_S); sb.setOffSet(17); - Buffer cb=new Buffer(I_C); cb.setOffSet(17); - - if(session.getLogger().isEnabled(Logger.INFO)){ - for(int i=0; i _s2cclazz=Class.forName(session.getConfig(guess[PROPOSAL_ENC_ALGS_STOC])).asSubclass(Cipher.class); - Cipher _s2ccipher=_s2cclazz.getDeclaredConstructor().newInstance(); - _s2cAEAD=_s2ccipher.isAEAD(); - if(_s2cAEAD){ - guess[PROPOSAL_MAC_ALGS_STOC]=null; - } - - Class _c2sclazz=Class.forName(session.getConfig(guess[PROPOSAL_ENC_ALGS_CTOS])).asSubclass(Cipher.class); - Cipher _c2scipher=_c2sclazz.getDeclaredConstructor().newInstance(); - _c2sAEAD=_c2scipher.isAEAD(); - if(_c2sAEAD){ - guess[PROPOSAL_MAC_ALGS_CTOS]=null; - } - } - catch(Exception | NoClassDefFoundError e){ - throw new JSchException(e.toString(), e); - } - - if(session.getLogger().isEnabled(Logger.INFO)){ - session.getLogger().log(Logger.INFO, - "kex: algorithm: "+guess[PROPOSAL_KEX_ALGS]); - session.getLogger().log(Logger.INFO, - "kex: host key algorithm: "+guess[PROPOSAL_SERVER_HOST_KEY_ALGS]); - session.getLogger().log(Logger.INFO, - "kex: server->client"+ - " cipher: "+guess[PROPOSAL_ENC_ALGS_STOC]+ - " MAC: "+(_s2cAEAD?(""):(guess[PROPOSAL_MAC_ALGS_STOC]))+ - " compression: "+guess[PROPOSAL_COMP_ALGS_STOC]); - session.getLogger().log(Logger.INFO, - "kex: client->server"+ - " cipher: "+guess[PROPOSAL_ENC_ALGS_CTOS]+ - " MAC: "+(_c2sAEAD?(""):(guess[PROPOSAL_MAC_ALGS_CTOS]))+ - " compression: "+guess[PROPOSAL_COMP_ALGS_CTOS]); - } - - return guess; - } - - public String getFingerPrint(){ - HASH hash=null; - try{ - String _c=session.getConfig("FingerprintHash").toLowerCase(); - Class c=Class.forName(session.getConfig(_c)).asSubclass(HASH.class); - hash=c.getDeclaredConstructor().newInstance(); - } - catch(Exception e){ System.err.println("getFingerPrint: "+e); } - return Util.getFingerPrint(hash, getHostKey(), true, false); - } - byte[] getK(){ return K; } - byte[] getH(){ return H; } - HASH getHash(){ return sha; } - byte[] getHostKey(){ return K_S; } - - /* - * It seems JCE included in Oracle's Java7u6(and later) has suddenly changed - * its behavior. The secrete generated by KeyAgreement#generateSecret() - * may start with 0, even if it is a positive value. - */ - protected byte[] normalize(byte[] secret) { - if(secret.length > 1 && - secret[0] == 0 && (secret[1]&0x80) == 0) { - byte[] tmp=new byte[secret.length-1]; - System.arraycopy(secret, 1, tmp, 0, tmp.length); - return normalize(tmp); - } - else { - return secret; - } - } - - protected boolean verify(String alg, byte[] K_S, int index, - byte[] sig_of_H) throws Exception { - int i,j; - - i=index; - boolean result=false; - - if(alg.equals("ssh-rsa")){ - byte[] tmp; - byte[] ee; - byte[] n; - - type=RSA; - key_alg_name=alg; - - j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); - tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j; - ee=tmp; - j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); - tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j; - n=tmp; - - SignatureRSA sig=null; - Buffer buf=new Buffer(sig_of_H); - String foo=Util.byte2str(buf.getString()); - try{ - Class c=Class.forName(session.getConfig(foo)).asSubclass(SignatureRSA.class); - sig=c.getDeclaredConstructor().newInstance(); - sig.init(); - } - catch(Exception e){ - System.err.println(e); - } - sig.setPubKey(ee, n); - sig.update(H); - result=sig.verify(sig_of_H); - - if(session.getLogger().isEnabled(Logger.INFO)){ - session.getLogger().log(Logger.INFO, - "ssh_rsa_verify: "+foo+" signature "+result); - } - } - else if(alg.equals("ssh-dss")){ - byte[] q=null; - byte[] tmp; - byte[] p; - byte[] g; - byte[] f; - - type=DSS; - key_alg_name=alg; - - j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); - tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j; - p=tmp; - j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); - tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j; - q=tmp; - j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); - tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j; - g=tmp; - j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); - tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j; - f=tmp; - - SignatureDSA sig=null; - try{ - Class c=Class.forName(session.getConfig("signature.dss")).asSubclass(SignatureDSA.class); - sig=c.getDeclaredConstructor().newInstance(); - sig.init(); - } - catch(Exception e){ - System.err.println(e); - } - sig.setPubKey(f, p, q, g); - sig.update(H); - result=sig.verify(sig_of_H); - - if(session.getLogger().isEnabled(Logger.INFO)){ - session.getLogger().log(Logger.INFO, - "ssh_dss_verify: signature "+result); - } - } - else if(alg.equals("ecdsa-sha2-nistp256") || - alg.equals("ecdsa-sha2-nistp384") || - alg.equals("ecdsa-sha2-nistp521")) { - byte[] tmp; - byte[] r; - byte[] s; - - // RFC 5656, - type=ECDSA; - key_alg_name=alg; - - j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); - tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j; - j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); - i++; - tmp=new byte[(j-1)/2]; - System.arraycopy(K_S, i, tmp, 0, tmp.length); i+=(j-1)/2; - r=tmp; - tmp=new byte[(j-1)/2]; - System.arraycopy(K_S, i, tmp, 0, tmp.length); i+=(j-1)/2; - s=tmp; - - SignatureECDSA sig=null; - try{ - Class c=Class.forName(session.getConfig(alg)).asSubclass(SignatureECDSA.class); - sig=c.getDeclaredConstructor().newInstance(); - sig.init(); - } - catch(Exception e){ - System.err.println(e); - } - - sig.setPubKey(r, s); - - sig.update(H); - - result=sig.verify(sig_of_H); - - if(session.getLogger().isEnabled(Logger.INFO)){ - session.getLogger().log(Logger.INFO, - "ssh_ecdsa_verify: "+alg+" signature "+result); - } - } - else if(alg.equals("ssh-ed25519") || - alg.equals("ssh-ed448")) { - byte[] tmp; - - // RFC 8709, - type=EDDSA; - key_alg_name=alg; - - j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); - tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j; - - SignatureEdDSA sig=null; - try{ - Class c=Class.forName(session.getConfig(alg)).asSubclass(SignatureEdDSA.class); - sig=c.getDeclaredConstructor().newInstance(); - sig.init(); - } - catch(Exception | NoClassDefFoundError e){ - System.err.println(e); - } - - sig.setPubKey(tmp); - - sig.update(H); - - result=sig.verify(sig_of_H); - - if(session.getLogger().isEnabled(Logger.INFO)){ - session.getLogger().log(Logger.INFO, - "ssh_eddsa_verify: "+alg+" signature "+result); - } - } - else{ - System.err.println("unknown alg"); - } - - return result; - } - -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPair.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPair.java deleted file mode 100644 index 39423875..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPair.java +++ /dev/null @@ -1,1371 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.io.*; -import java.util.Arrays; -import java.util.Hashtable; -import java.util.Vector; - -public abstract class KeyPair{ - - public static final int DEFERRED = -1; - public static final int ERROR=0; - public static final int DSA=1; - public static final int RSA=2; - public static final int ECDSA=3; - public static final int UNKNOWN=4; - public static final int ED25519=5; - public static final int ED448=6; - - static final int VENDOR_OPENSSH=0; - static final int VENDOR_FSECURE=1; - static final int VENDOR_PUTTY=2; - static final int VENDOR_PKCS8=3; - static final int VENDOR_OPENSSH_V1 = 4; - - int vendor=VENDOR_OPENSSH; - - private static final byte[] AUTH_MAGIC = Util.str2byte("openssh-key-v1\0"); - private static final byte[] cr=Util.str2byte("\n"); - - public static KeyPair genKeyPair(JSch jsch, int type) throws JSchException{ - return genKeyPair(jsch, type, 1024); - } - public static KeyPair genKeyPair(JSch jsch, int type, int key_size) throws JSchException{ - KeyPair kpair=null; - if(type==DSA){ kpair=new KeyPairDSA(jsch); } - else if(type==RSA){ kpair=new KeyPairRSA(jsch); } - else if(type==ECDSA){ kpair=new KeyPairECDSA(jsch); } - else if(type==ED25519){ kpair=new KeyPairEd25519(jsch); } - else if(type==ED448){ kpair=new KeyPairEd448(jsch); } - if(kpair!=null){ - kpair.generate(key_size); - } - return kpair; - } - - abstract void generate(int key_size) throws JSchException; - - abstract byte[] getBegin(); - abstract byte[] getEnd(); - public abstract int getKeySize(); - - public abstract byte[] getSignature(byte[] data); - public abstract byte[] getSignature(byte[] data, String alg); - public abstract Signature getVerifier(); - public abstract Signature getVerifier(String alg); - - public abstract byte[] forSSHAgent() throws JSchException; - - public String getPublicKeyComment(){ - return publicKeyComment; - } - - public void setPublicKeyComment(String publicKeyComment){ - this.publicKeyComment = publicKeyComment; - } - - protected String publicKeyComment = "no comment"; - - JSch jsch=null; - protected Cipher cipher; - private HASH hash; - private Random random; - - private byte[] passphrase; - - protected String kdfName; - protected byte[] kdfOptions; - - public KeyPair(JSch jsch){ - this.jsch=jsch; - } - - static byte[][] header={Util.str2byte("Proc-Type: 4,ENCRYPTED"), - Util.str2byte("DEK-Info: DES-EDE3-CBC,")}; - - abstract byte[] getPrivateKey(); - - /** - * Writes the plain private key to the given output stream. - * @param out output stream - * @see #writePrivateKey(OutputStream out, byte[] passphrase) - */ - public void writePrivateKey(OutputStream out){ - this.writePrivateKey(out, null); - } - - /** - * Writes the cyphered private key to the given output stream. - * @param out output stream - * @param passphrase a passphrase to encrypt the private key - */ - public void writePrivateKey(OutputStream out, byte[] passphrase){ - if(passphrase == null) - passphrase = this.passphrase; - - byte[] plain=getPrivateKey(); - byte[][] _iv=new byte[1][]; - byte[] encoded=encrypt(plain, _iv, passphrase); - if(encoded!=plain) - Util.bzero(plain); - byte[] iv=_iv[0]; - byte[] prv=Util.toBase64(encoded, 0, encoded.length, true); - - try{ - out.write(getBegin()); out.write(cr); - if(passphrase!=null){ - out.write(header[0]); out.write(cr); - out.write(header[1]); - for(int i=0; i>>4)&0x0f))); - out.write(b2a((byte)(iv[i]&0x0f))); - } - out.write(cr); - out.write(cr); - } - int i=0; - while(i0){ - len>>>=8; - i++; - } - return i; - } - - int writeLength(byte[] data, int index, int len){ - int i=countLength(len)-1; - if(i==0){ - data[index++]=(byte)len; - return index; - } - data[index++]=(byte)(0x80|i); - int j=index+i; - while(i>0){ - data[index+i-1]=(byte)(len&0xff); - len>>>=8; - i--; - } - return j; - } - - private Random genRandom(){ - if(random==null){ - try{ - Class c=Class.forName(JSch.getConfig("random")).asSubclass(Random.class); - random=c.getDeclaredConstructor().newInstance(); - } - catch(Exception e){ System.err.println("connect: random "+e); } - } - return random; - } - - private HASH genHash(){ - try{ - Class c=Class.forName(JSch.getConfig("md5")).asSubclass(HASH.class); - hash=c.getDeclaredConstructor().newInstance(); - hash.init(); - } - catch(Exception e){ - } - return hash; - } - private Cipher genCipher(){ - try{ - Class c=Class.forName(JSch.getConfig("3des-cbc")).asSubclass(Cipher.class); - cipher=c.getDeclaredConstructor().newInstance(); - } - catch(Exception e){ - } - return cipher; - } - - /* - hash is MD5 - h(0) <- hash(passphrase, iv); - h(n) <- hash(h(n-1), passphrase, iv); - key <- (h(0),...,h(n))[0,..,key.length]; - */ - synchronized byte[] genKey(byte[] passphrase, byte[] iv){ - if(cipher==null) cipher=genCipher(); - if(hash==null) hash=genHash(); - - byte[] key=new byte[cipher.getBlockSize()]; - int hsize=hash.getBlockSize(); - byte[] hn=new byte[key.length/hsize*hsize+ - (key.length%hsize==0?0:hsize)]; - try{ - byte[] tmp=null; - if(vendor==VENDOR_OPENSSH){ - for(int index=0; index+hsize<=hn.length;){ - if(tmp!=null){ hash.update(tmp, 0, tmp.length); } - hash.update(passphrase, 0, passphrase.length); - hash.update(iv, 0, iv.length > 8 ? 8: iv.length); - tmp=hash.digest(); - System.arraycopy(tmp, 0, hn, index, tmp.length); - index+=tmp.length; - } - System.arraycopy(hn, 0, key, 0, key.length); - } - else if(vendor==VENDOR_FSECURE){ - for(int index=0; index+hsize<=hn.length;){ - if(tmp!=null){ hash.update(tmp, 0, tmp.length); } - hash.update(passphrase, 0, passphrase.length); - tmp=hash.digest(); - System.arraycopy(tmp, 0, hn, index, tmp.length); - index+=tmp.length; - } - System.arraycopy(hn, 0, key, 0, key.length); - } - else if(vendor==VENDOR_PUTTY){ - Class c=Class.forName(JSch.getConfig("sha-1")).asSubclass(HASH.class); - HASH sha1=c.getDeclaredConstructor().newInstance(); - tmp = new byte[4]; - key = new byte[20*2]; - for(int i = 0; i < 2; i++){ - sha1.init(); - tmp[3]=(byte)i; - sha1.update(tmp, 0, tmp.length); - sha1.update(passphrase, 0, passphrase.length); - System.arraycopy(sha1.digest(), 0, key, i*20, 20); - } - } - } - catch(Exception e){ - System.err.println(e); - } - return key; - } - - /** - * @deprecated use #writePrivateKey(OutputStream out, byte[] passphrase) - */ - @Deprecated - public void setPassphrase(String passphrase){ - if(passphrase==null || passphrase.length()==0){ - setPassphrase((byte[])null); - } - else{ - setPassphrase(Util.str2byte(passphrase)); - } - } - - /** - * @deprecated use #writePrivateKey(String name, byte[] passphrase) - */ - @Deprecated - public void setPassphrase(byte[] passphrase){ - if(passphrase!=null && passphrase.length==0) - passphrase=null; - this.passphrase=passphrase; - } - - protected boolean encrypted=false; - protected byte[] data=null; - private byte[] iv=null; - private byte[] publickeyblob=null; - - public boolean isEncrypted(){ return encrypted; } - public boolean decrypt(String _passphrase){ - if(_passphrase==null || _passphrase.length()==0){ - return !encrypted; - } - return decrypt(Util.str2byte(_passphrase)); - } - public boolean decrypt(byte[] _passphrase){ - - if(!encrypted){ - return true; - } - if(_passphrase==null){ - return !encrypted; - } - byte[] bar=new byte[_passphrase.length]; - System.arraycopy(_passphrase, 0, bar, 0, bar.length); - _passphrase=bar; - byte[] foo=decrypt(data, _passphrase, iv); - Util.bzero(_passphrase); - if(parse(foo)){ - encrypted=false; - } - return !encrypted; - } - - public static KeyPair load(JSch jsch, String prvkey) throws JSchException{ - String pubkey=prvkey+".pub"; - if(!new File(pubkey).exists()){ - pubkey=null; - } - return load(jsch, prvkey, pubkey); - } - public static KeyPair load(JSch jsch, String prvfile, String pubfile) throws JSchException{ - - byte[] prvkey=null; - byte[] pubkey=null; - - try{ - prvkey = Util.fromFile(prvfile); - } - catch(IOException e){ - throw new JSchException(e.toString(), e); - } - - String _pubfile=pubfile; - if(pubfile==null){ - _pubfile=prvfile+".pub"; - } - - try{ - pubkey = Util.fromFile(_pubfile); - } - catch(IOException e){ - if(pubfile!=null){ - throw new JSchException(e.toString(), e); - } - } - - try { - return load(jsch, prvkey, pubkey); - } - finally { - Util.bzero(prvkey); - } - } - - public static KeyPair load(JSch jsch, byte[] prvkey, byte[] pubkey) throws JSchException{ - - byte[] iv=new byte[8]; // 8 - boolean encrypted=true; - byte[] data=null; - - byte[] publickeyblob=null; - - int type=ERROR; - int vendor=VENDOR_OPENSSH; - String publicKeyComment = ""; - Cipher cipher=null; - String kdfName = null; - byte[] kdfOptions = null; - - // prvkey from "ssh-add" command on the remote. - if(pubkey==null && - prvkey!=null && - (prvkey.length>11 && - prvkey[0]==0 && prvkey[1]==0 && prvkey[2]==0 && - // length of key type string - (prvkey[3]==7 || prvkey[3]==9 || prvkey[3]==11 || prvkey[3]==19))){ - - Buffer buf=new Buffer(prvkey); - buf.skip(prvkey.length); // for using Buffer#available() - String _type = Util.byte2str(buf.getString()); // ssh-rsa or ssh-dss - buf.rewind(); - - KeyPair kpair=null; - if(_type.equals("ssh-rsa")){ - kpair=KeyPairRSA.fromSSHAgent(jsch, buf); - } - else if(_type.equals("ssh-dss")){ - kpair=KeyPairDSA.fromSSHAgent(jsch, buf); - } - else if(_type.equals("ecdsa-sha2-nistp256") || - _type.equals("ecdsa-sha2-nistp384") || - _type.equals("ecdsa-sha2-nistp521")){ - kpair=KeyPairECDSA.fromSSHAgent(jsch, buf); - } - else if(_type.equals("ssh-ed25519")){ - kpair=KeyPairEd25519.fromSSHAgent(jsch, buf); - } - else if(_type.equals("ssh-ed448")){ - kpair=KeyPairEd448.fromSSHAgent(jsch, buf); - } - else{ - throw new JSchException("privatekey: invalid key "+Util.byte2str(prvkey, 4, 7)); - } - return kpair; - } - - try{ - byte[] buf=prvkey; - - if(buf!=null){ - KeyPair ppk = loadPPK(jsch, buf); - if(ppk !=null) - return ppk; - } - - int len = (buf!=null ? buf.length : 0); - int i=0; - - // skip garbage lines. - while(i= len) - throw new JSchException("invalid privatekey"); - if(buf[i]=='D'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=DSA; } - else if(buf[i]=='R'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=RSA; } - else if(buf[i]=='E'&& buf[i+1]=='C'){ type=ECDSA; } - else if(buf[i]=='S'&& buf[i+1]=='S'&& buf[i+2]=='H'){ // FSecure - type=UNKNOWN; - vendor=VENDOR_FSECURE; - } - else if(i+6 < len && - buf[i]=='P' && buf[i+1]=='R' && - buf[i+2]=='I' && buf[i+3]=='V' && - buf[i+4]=='A' && buf[i+5]=='T' && buf[i+6]=='E'){ - type=UNKNOWN; - vendor=VENDOR_PKCS8; - encrypted=false; - i+=3; - } - else if(i+8 < len && - buf[i]=='E' && buf[i+1]=='N' && - buf[i+2]=='C' && buf[i+3]=='R' && - buf[i+4]=='Y' && buf[i+5]=='P' && buf[i+6]=='T' && - buf[i+7]=='E' && buf[i+8]=='D'){ - type=UNKNOWN; - vendor=VENDOR_PKCS8; - i+=5; - - } else if (isOpenSSHPrivateKey(buf, i, len)) { - type = UNKNOWN; - vendor = VENDOR_OPENSSH_V1; - } else { - throw new JSchException("invalid privatekey"); - } - i+=3; - continue; - } - if(buf[i]=='A'&& i+7 c=Class.forName(JSch.getConfig("aes256-cbc")).asSubclass(Cipher.class); - cipher=c.getDeclaredConstructor().newInstance(); - // key=new byte[cipher.getBlockSize()]; - iv=new byte[cipher.getIVSize()]; - } - else{ - throw new JSchException("privatekey: aes256-cbc is not available"); - } - continue; - } - if(buf[i]=='A'&& i+7 c=Class.forName(JSch.getConfig("aes192-cbc")).asSubclass(Cipher.class); - cipher=c.getDeclaredConstructor().newInstance(); - // key=new byte[cipher.getBlockSize()]; - iv=new byte[cipher.getIVSize()]; - } - else{ - throw new JSchException("privatekey: aes192-cbc is not available"); - } - continue; - } - if(buf[i]=='A'&& i+7 c=Class.forName(JSch.getConfig("aes128-cbc")).asSubclass(Cipher.class); - cipher=c.getDeclaredConstructor().newInstance(); - // key=new byte[cipher.getBlockSize()]; - iv=new byte[cipher.getIVSize()]; - } - else{ - throw new JSchException("privatekey: aes128-cbc is not available"); - } - continue; - } - if(buf[i]=='C'&& i+3 0) - data=Util.fromBase64(_buf, start, i-start); - - Util.bzero(_buf); - } - - if(data!=null && - data.length>4 && // FSecure - data[0]==(byte)0x3f && - data[1]==(byte)0x6f && - data[2]==(byte)0xf9 && - data[3]==(byte)0xeb){ - - Buffer _buf=new Buffer(data); - _buf.getInt(); // 0x3f6ff9be - _buf.getInt(); - byte[]_type=_buf.getString(); - //System.err.println("type: "+Util.byte2str(_type)); - String _cipher=Util.byte2str(_buf.getString()); - //System.err.println("cipher: "+_cipher); - if(_cipher.equals("3des-cbc")){ - _buf.getInt(); - byte[] foo=new byte[data.length-_buf.getOffSet()]; - _buf.getByte(foo); - data=foo; - encrypted=true; - throw new JSchException("unknown privatekey format"); - } - else if(_cipher.equals("none")){ - _buf.getInt(); - _buf.getInt(); - - encrypted=false; - - byte[] foo=new byte[data.length-_buf.getOffSet()]; - _buf.getByte(foo); - data=foo; - } - } - // OPENSSH V1 PRIVATE KEY - else if (data != null && - Util.array_equals(AUTH_MAGIC, Arrays.copyOfRange(data, 0, AUTH_MAGIC.length))) { - - vendor = VENDOR_OPENSSH_V1; - Buffer buffer = new Buffer(data); - byte[] magic = new byte[AUTH_MAGIC.length]; - buffer.getByte(magic); - - String cipherName = Util.byte2str(buffer.getString()); - kdfName = Util.byte2str(buffer.getString()); // string kdfname - kdfOptions = buffer.getString(); // string kdfoptions - - int nrKeys = buffer.getInt(); // int number of keys N; Should be 1 - if (nrKeys != 1) { - throw new IOException("We don't support having more than 1 key in the file (yet)."); - } - - pubkey = buffer.getString(); - - if ("none".equals(cipherName)) { - encrypted = false; - data = buffer.getString(); - type = readOpenSSHKeyv1(data); - } else if (Session.checkCipher(JSch.getConfig(cipherName))) { - encrypted = true; - Class c = Class.forName(JSch.getConfig(cipherName)).asSubclass(Cipher.class); - cipher = c.getDeclaredConstructor().newInstance(); - data = buffer.getString(); - // the type can only be determined after encryption, so we take this intermediate here: - type = DEFERRED; - } else { - throw new JSchException("cipher " + cipherName + " is not available"); - } - } - - if(pubkey!=null){ - try{ - buf=pubkey; - len=buf.length; - if(buf.length>4 && // FSecure's public key - buf[0]=='-' && buf[1]=='-' && buf[2]=='-' && buf[3]=='-'){ - - boolean valid=true; - i=0; - do{i++;}while(buf.length>i && buf[i]!=0x0a); - if(buf.length<=i) {valid=false;} - - while(valid){ - if(buf[i]==0x0a){ - boolean inheader=false; - for(int j=i+1; j7){ - if(buf[4]=='d'){ type=DSA; } - else if(buf[4]=='r'){ type=RSA; } - else if(buf[4]=='e' && buf[6]=='2'){ type=ED25519; } - else if(buf[4]=='e' && buf[6]=='4'){ type=ED448; } - } - i=0; - while(i0 && buf[i-1]==0x0d) i--; - if(start7){ - type=ECDSA; - } - i=0; - while(i0 && buf[i-1]==0x0d) i--; - if(start v = new Hashtable<>(); - - while(true){ - if(!parseHeader(buffer, v)) - break; - } - - String typ = v.get("PuTTY-User-Key-File-2"); - if(typ == null){ - return null; - } - - lines = Integer.parseInt(v.get("Public-Lines")); - pubkey = parseLines(buffer, lines); - - while(true){ - if(!parseHeader(buffer, v)) - break; - } - - lines = Integer.parseInt(v.get("Private-Lines")); - prvkey = parseLines(buffer, lines); - - while(true){ - if(!parseHeader(buffer, v)) - break; - } - - prvkey = Util.fromBase64(prvkey, 0, prvkey.length); - pubkey = Util.fromBase64(pubkey, 0, pubkey.length); - - KeyPair kpair = null; - - if(typ.equals("ssh-rsa")) { - - Buffer _buf = new Buffer(pubkey); - _buf.skip(pubkey.length); - - int len = _buf.getInt(); - _buf.getByte(new byte[len]); // ssh-rsa - byte[] pub_array = new byte[_buf.getInt()]; - _buf.getByte(pub_array); - byte[] n_array = new byte[_buf.getInt()]; - _buf.getByte(n_array); - - kpair = new KeyPairRSA(jsch, n_array, pub_array, null); - } - else if(typ.equals("ssh-dss")){ - Buffer _buf = new Buffer(pubkey); - _buf.skip(pubkey.length); - - int len = _buf.getInt(); - _buf.getByte(new byte[len]); // ssh-dss - - byte[] p_array = new byte[_buf.getInt()]; - _buf.getByte(p_array); - byte[] q_array = new byte[_buf.getInt()]; - _buf.getByte(q_array); - byte[] g_array = new byte[_buf.getInt()]; - _buf.getByte(g_array); - byte[] y_array = new byte[_buf.getInt()]; - _buf.getByte(y_array); - - kpair = new KeyPairDSA(jsch, p_array, q_array, g_array, y_array, null); - } - else { - return null; - } - - if(kpair == null) - return null; - - kpair.encrypted = !v.get("Encryption").equals("none"); - kpair.vendor = VENDOR_PUTTY; - kpair.publicKeyComment = v.get("Comment"); - if(kpair.encrypted){ - if(Session.checkCipher(JSch.getConfig("aes256-cbc"))){ - try { - Class c=Class.forName(JSch.getConfig("aes256-cbc")).asSubclass(Cipher.class); - kpair.cipher=c.getDeclaredConstructor().newInstance(); - kpair.iv=new byte[kpair.cipher.getIVSize()]; - } - catch(Exception e){ - throw new JSchException("The cipher 'aes256-cbc' is required, but it is not available."); - } - } - else { - throw new JSchException("The cipher 'aes256-cbc' is required, but it is not available."); - } - kpair.data = prvkey; - } - else { - kpair.data = prvkey; - kpair.parse(prvkey); - } - return kpair; - } - - private static byte[] parseLines(Buffer buffer, int lines){ - byte[] buf = buffer.buffer; - int index = buffer.index; - byte[] data = null; - - int i = index; - while(lines-->0){ - while(buf.length > i){ - if(buf[i++] == 0x0d){ - if(data == null){ - data = new byte[i - index - 1]; - System.arraycopy(buf, index, data, 0, i - index - 1); - } - else { - byte[] tmp = new byte[data.length + i - index - 1]; - System.arraycopy(data, 0, tmp, 0, data.length); - System.arraycopy(buf, index, tmp, data.length, i - index -1); - for(int j = 0; j < data.length; j++) data[j] = 0; // clear - data = tmp; - } - break; - } - } - if(buf[i]==0x0a) - i++; - index=i; - } - - if(data != null) - buffer.index = index; - - return data; - } - - private static boolean parseHeader(Buffer buffer, Hashtable v){ - byte[] buf = buffer.buffer; - int index = buffer.index; - String key = null; - String value = null; - for(int i = index; i < buf.length; i++){ - if(buf[i] == 0x0d){ - break; - } - if(buf[i] == ':'){ - key = Util.byte2str(buf, index, i - index); - i++; - if(i < buf.length && buf[i] == ' '){ - i++; - } - index = i; - break; - } - } - - if(key == null) - return false; - - for(int i = index; i < buf.length; i++){ - if(buf[i] == 0x0d){ - value = Util.byte2str(buf, index, i - index); - i++; - if(i < buf.length && buf[i] == 0x0a){ - i++; - } - index = i; - break; - } - } - - if(value != null){ - v.put(key, value); - buffer.index = index; - } - - return (key != null && value != null); - } - - void copy(KeyPair kpair){ - this.publickeyblob=kpair.publickeyblob; - this.vendor=kpair.vendor; - this.publicKeyComment=kpair.publicKeyComment; - this.cipher=kpair.cipher; - } - - static class ASN1Exception extends Exception { - private static final long serialVersionUID=-1L; - } - - class ASN1 { - byte[] buf; - int start; - int length; - ASN1(byte[] buf) throws ASN1Exception { - this(buf, 0, buf.length); - } - ASN1(byte[] buf, int start, int length) throws ASN1Exception { - this.buf = buf; - this.start = start; - this.length = length; - if(start+length>buf.length) - throw new ASN1Exception(); - } - int getType() { - return buf[start]&0xff; - } - boolean isSEQUENCE() { - return getType()==(0x30&0xff); - } - boolean isINTEGER() { - return getType()==(0x02&0xff); - } - boolean isOBJECT() { - return getType()==(0x06&0xff); - } - boolean isOCTETSTRING() { - return getType()==(0x04&0xff); - } - private int getLength(int[] indexp) { - int index=indexp[0]; - int length=buf[index++]&0xff; - if((length&0x80)!=0) { - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(buf[index++]&0xff); } - } - indexp[0]=index; - return length; - } - byte[] getContent() { - int[] indexp=new int[1]; - indexp[0]=start+1; - int length = getLength(indexp); - int index=indexp[0]; - byte[] tmp = new byte[length]; - System.arraycopy(buf, index, tmp, 0, tmp.length); - return tmp; - } - ASN1[] getContents() throws ASN1Exception { - int typ = buf[start]; - int[] indexp=new int[1]; - indexp[0]=start+1; - int length = getLength(indexp); - if(typ == 0x05){ - return new ASN1[0]; - } - int index=indexp[0]; - Vector values = new Vector<>(); - while(length>0) { - index++; length--; - int tmp=index; - indexp[0]=index; - int l=getLength(indexp); - index=indexp[0]; - length-=(index-tmp); - values.addElement(new ASN1(buf, tmp-1, 1+(index-tmp)+l)); - index+=l; - length-=l; - } - ASN1[] result = new ASN1[values.size()]; - for(int i = 0; i c=Class.forName(JSch.getConfig("keypairgen.dsa")).asSubclass(KeyPairGenDSA.class); - KeyPairGenDSA keypairgen=c.getDeclaredConstructor().newInstance(); - keypairgen.init(key_size); - P_array=keypairgen.getP(); - Q_array=keypairgen.getQ(); - G_array=keypairgen.getG(); - pub_array=keypairgen.getY(); - prv_array=keypairgen.getX(); - - keypairgen=null; - } - catch(Exception e){ - //System.err.println("KeyPairDSA: "+e); - throw new JSchException(e.toString(), e); - } - } - - private static final byte[] begin=Util.str2byte("-----BEGIN DSA PRIVATE KEY-----"); - private static final byte[] end=Util.str2byte("-----END DSA PRIVATE KEY-----"); - - @Override - byte[] getBegin(){ return begin; } - @Override - byte[] getEnd(){ return end; } - - @Override - byte[] getPrivateKey(){ - int content= - 1+countLength(1) + 1 + // INTEGER - 1+countLength(P_array.length) + P_array.length + // INTEGER P - 1+countLength(Q_array.length) + Q_array.length + // INTEGER Q - 1+countLength(G_array.length) + G_array.length + // INTEGER G - 1+countLength(pub_array.length) + pub_array.length + // INTEGER pub - 1+countLength(prv_array.length) + prv_array.length; // INTEGER prv - - int total= - 1+countLength(content)+content; // SEQUENCE - - byte[] plain=new byte[total]; - int index=0; - index=writeSEQUENCE(plain, index, content); - index=writeINTEGER(plain, index, new byte[1]); // 0 - index=writeINTEGER(plain, index, P_array); - index=writeINTEGER(plain, index, Q_array); - index=writeINTEGER(plain, index, G_array); - index=writeINTEGER(plain, index, pub_array); - index=writeINTEGER(plain, index, prv_array); - return plain; - } - - @Override - boolean parse(byte[] plain){ - try{ - - if(vendor==VENDOR_FSECURE){ - if(plain[0]!=0x30){ // FSecure - Buffer buf=new Buffer(plain); - buf.getInt(); - P_array=buf.getMPIntBits(); - G_array=buf.getMPIntBits(); - Q_array=buf.getMPIntBits(); - pub_array=buf.getMPIntBits(); - prv_array=buf.getMPIntBits(); - if(P_array!=null) - key_size = (new BigInteger(P_array)).bitLength(); - return true; - } - return false; - } - else if(vendor==VENDOR_PUTTY){ - Buffer buf=new Buffer(plain); - buf.skip(plain.length); - - try { - byte[][] tmp = buf.getBytes(1, ""); - prv_array = tmp[0]; - } - catch(JSchException e){ - return false; - } - - return true; - } - - // OPENSSH Key v1 Format - else if (vendor == VENDOR_OPENSSH_V1) { - - final Buffer prvKEyBuffer = new Buffer(plain); - int checkInt1 = prvKEyBuffer.getInt(); // uint32 checkint1 - int checkInt2 = prvKEyBuffer.getInt(); // uint32 checkint2 - if (checkInt1 != checkInt2) { - throw new JSchException("check failed"); - } - // The private key section contains both the public key and the private key - String keyType = Util.byte2str(prvKEyBuffer.getString()); // string keytype - - P_array=prvKEyBuffer.getMPInt(); - Q_array=prvKEyBuffer.getMPInt(); - G_array= prvKEyBuffer.getMPInt(); - pub_array=prvKEyBuffer.getMPInt(); - prv_array=prvKEyBuffer.getMPInt(); - publicKeyComment=Util.byte2str(prvKEyBuffer.getString()); - //if(P_array!=null) key_size = (new BigInteger(P_array)).bitLength(); - return true; - - } - - int index=0; - int length=0; - - if(plain[index]!=0x30)return false; - index++; // SEQUENCE - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - - if(plain[index]!=0x02)return false; - index++; // INTEGER - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - index+=length; - - index++; - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - P_array=new byte[length]; - System.arraycopy(plain, index, P_array, 0, length); - index+=length; - - index++; - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - Q_array=new byte[length]; - System.arraycopy(plain, index, Q_array, 0, length); - index+=length; - - index++; - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - G_array=new byte[length]; - System.arraycopy(plain, index, G_array, 0, length); - index+=length; - - index++; - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - pub_array=new byte[length]; - System.arraycopy(plain, index, pub_array, 0, length); - index+=length; - - index++; - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - prv_array=new byte[length]; - System.arraycopy(plain, index, prv_array, 0, length); - index+=length; - - if(P_array!=null) - key_size = (new BigInteger(P_array)).bitLength(); - } - catch(Exception e){ - //System.err.println(e); - //e.printStackTrace(); - return false; - } - return true; - } - - @Override - public byte[] getPublicKeyBlob(){ - byte[] foo=super.getPublicKeyBlob(); - if(foo!=null) return foo; - - if(P_array==null) return null; - byte[][] tmp = new byte[5][]; - tmp[0] = sshdss; - tmp[1] = P_array; - tmp[2] = Q_array; - tmp[3] = G_array; - tmp[4] = pub_array; - return Buffer.fromBytes(tmp).buffer; - } - - private static final byte[] sshdss=Util.str2byte("ssh-dss"); - @Override - byte[] getKeyTypeName(){return sshdss;} - @Override - public int getKeyType(){return DSA;} - - @Override - public int getKeySize(){ - return key_size; - } - - @Override - public byte[] getSignature(byte[] data){ - try{ - Class c=Class.forName(JSch.getConfig("signature.dss")).asSubclass(SignatureDSA.class); - SignatureDSA dsa=c.getDeclaredConstructor().newInstance(); - dsa.init(); - dsa.setPrvKey(prv_array, P_array, Q_array, G_array); - - dsa.update(data); - byte[] sig = dsa.sign(); - byte[][] tmp = new byte[2][]; - tmp[0] = sshdss; - tmp[1] = sig; - return Buffer.fromBytes(tmp).buffer; - } - catch(Exception e){ - //System.err.println("e "+e); - } - return null; - } - - @Override - public byte[] getSignature(byte[] data, String alg){ - return getSignature(data); - } - - @Override - public Signature getVerifier(){ - try{ - Class c=Class.forName(JSch.getConfig("signature.dss")).asSubclass(SignatureDSA.class); - SignatureDSA dsa=c.getDeclaredConstructor().newInstance(); - dsa.init(); - - if(pub_array == null && P_array == null && getPublicKeyBlob()!=null){ - Buffer buf = new Buffer(getPublicKeyBlob()); - buf.getString(); - P_array = buf.getString(); - Q_array = buf.getString(); - G_array = buf.getString(); - pub_array = buf.getString(); - } - - dsa.setPubKey(pub_array, P_array, Q_array, G_array); - return dsa; - } - catch(Exception e){ - //System.err.println("e "+e); - } - return null; - } - - @Override - public Signature getVerifier(String alg){ - return getVerifier(); - } - - static KeyPair fromSSHAgent(JSch jsch, Buffer buf) throws JSchException { - - byte[][] tmp = buf.getBytes(7, "invalid key format"); - - byte[] P_array = tmp[1]; - byte[] Q_array = tmp[2]; - byte[] G_array = tmp[3]; - byte[] pub_array = tmp[4]; - byte[] prv_array = tmp[5]; - KeyPairDSA kpair = new KeyPairDSA(jsch, - P_array, Q_array, G_array, - pub_array, prv_array); - kpair.publicKeyComment = Util.byte2str(tmp[6]); - kpair.vendor=VENDOR_OPENSSH; - return kpair; - } - - @Override - public byte[] forSSHAgent() throws JSchException { - if(isEncrypted()){ - throw new JSchException("key is encrypted."); - } - Buffer buf = new Buffer(); - buf.putString(sshdss); - buf.putString(P_array); - buf.putString(Q_array); - buf.putString(G_array); - buf.putString(pub_array); - buf.putString(prv_array); - buf.putString(Util.str2byte(publicKeyComment)); - byte[] result = new byte[buf.getLength()]; - buf.getByte(result, 0, result.length); - return result; - } - - @Override - public void dispose(){ - super.dispose(); - Util.bzero(prv_array); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairDeferred.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairDeferred.java deleted file mode 100644 index d4f5aaba..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairDeferred.java +++ /dev/null @@ -1,163 +0,0 @@ -package com.jcraft.jsch; - -import com.jcraft.jsch.jbcrypt.BCrypt; - -import java.util.Arrays; - -/** - * A {@link KeyPair} which can only reveal its type and content after it was decrypted using {@link com.jcraft.jsch.KeyPairDeferred#decrypt(byte[])}. - * This is needed for openssh-v1-private-key format. - */ -class KeyPairDeferred extends KeyPair { - - private KeyPair delegate; - - KeyPairDeferred(JSch jsch) { - super(jsch); - } - - @Override - public boolean decrypt(String _passphrase) { - return decrypt(Util.str2byte(_passphrase)); - } - - @Override - public boolean decrypt(byte[] _passphrase) { - try { - if (!isEncrypted()) { - return true; - } - if (_passphrase == null) { - jsch.getInstanceLogger().log(Logger.ERROR, "no passphrase set."); - return false; - } - - initCipher(_passphrase); - - byte[] plain = new byte[data.length]; - cipher.update(data, 0, data.length, plain, 0); - - // now we have decrypted key and can determine type - int type = readOpenSSHKeyv1(plain); - - delegate = getKeyPair(jsch, null, null, null, false, plain, getPublicKeyBlob(), type, VENDOR_OPENSSH_V1, publicKeyComment, cipher, null, null); - - return delegate != null; - - - } catch (Exception e) { - throw new IllegalArgumentException("Could not sucessfully decrypt openssh v1 key", e); - } - - } - - private void initCipher(byte[] _passphrase) throws Exception { - - // the encrypted private key is here: - if ("bcrypt".equals(kdfName)) { - Buffer opts = new Buffer(kdfOptions); - - byte[] keyiv = new byte[48]; - - new BCrypt().pbkdf(_passphrase, opts.getString(), opts.getInt(), keyiv); - - Arrays.fill(_passphrase, (byte) 0); - byte[] key = Arrays.copyOfRange(keyiv, 0, 32); - byte[] iv = Arrays.copyOfRange(keyiv, 32, 48); - cipher.init(Cipher.DECRYPT_MODE, key, iv); - } else { - throw new IllegalStateException("No support for KDF '" + kdfName + "'."); - } - } - - @Override - void generate(int key_size) throws JSchException { - throw new UnsupportedOperationException(); - } - - @Override - byte[] getBegin() { - return requireDecrypted(delegate).getBegin(); - } - - @Override - byte[] getEnd() { - return requireDecrypted(delegate).getEnd(); - } - - @Override - public int getKeySize() { - return requireDecrypted(delegate).getKeySize(); - } - - @Override - public byte[] getSignature(byte[] data) { - return requireDecrypted(delegate).getSignature(data); - } - - @Override - public byte[] getSignature(byte[] data, String alg) { - return requireDecrypted(delegate).getSignature(data, alg); - } - - @Override - public Signature getVerifier() { - return requireDecrypted(delegate).getVerifier(); - } - - @Override - public Signature getVerifier(String alg) { - return requireDecrypted(delegate).getVerifier(alg); - } - - @Override - public byte[] forSSHAgent() throws JSchException { - return requireDecrypted(delegate).forSSHAgent(); - } - - @Override - byte[] getPrivateKey() { - return requireDecrypted(delegate).getPrivateKey(); - } - - @Override - byte[] getKeyTypeName() { - return requireDecrypted(delegate).getKeyTypeName(); - } - - @Override - public int getKeyType() { - return requireDecrypted(delegate).getKeyType(); - } - - @Override - boolean parse(byte[] data) { - return requireDecrypted(delegate).parse(data); - } - - @Override - public byte[] getPublicKeyBlob() { - return delegate != null ? delegate.getPublicKeyBlob() : null; - } - - @Override - public String getPublicKeyComment() { - return requireDecrypted(delegate).getPublicKeyComment(); - } - - @Override - public String getFingerPrint() { - return requireDecrypted(delegate).getFingerPrint(); - } - - @Override - public boolean isEncrypted() { - return delegate != null ? delegate.isEncrypted() : super.isEncrypted(); - } - - private T requireDecrypted(T obj) { - if (obj == null) - throw new IllegalStateException("encrypted key has not been decrypted yet."); - return obj; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairECDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairECDSA.java deleted file mode 100644 index 283e520b..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairECDSA.java +++ /dev/null @@ -1,467 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.util.Arrays; - -class KeyPairECDSA extends KeyPair{ - - private static byte[][] oids = { - {(byte)0x06, (byte)0x08, (byte)0x2a, (byte)0x86, (byte)0x48, // 256 - (byte)0xce, (byte)0x3d, (byte)0x03, (byte)0x01, (byte)0x07}, - {(byte)0x06, (byte)0x05, (byte)0x2b, (byte)0x81, (byte)0x04, // 384 - (byte)0x00, (byte)0x22}, - {(byte)0x06, (byte)0x05, (byte)0x2b, (byte)0x81, (byte)0x04, //521 - (byte)0x00, (byte)0x23}, - }; - - private static String[] names = { - "nistp256", "nistp384", "nistp521" - }; - - private byte[] name=Util.str2byte(names[0]); - private byte[] r_array; - private byte[] s_array; - private byte[] prv_array; - - private int key_size=256; - - KeyPairECDSA(JSch jsch){ - this(jsch, null, null, null, null); - } - - KeyPairECDSA(JSch jsch , byte[] pubkey){ - this(jsch, null, null, null, null); - - if(pubkey!=null){ - byte[] name = new byte[8]; - System.arraycopy(pubkey, 11, name, 0, 8); - if(Util.array_equals(name, Util.str2byte("nistp384"))){ - key_size=384; - this.name=name; - } - if(Util.array_equals(name, Util.str2byte("nistp521"))){ - key_size=521; - this.name=name; - } - } - } - - KeyPairECDSA(JSch jsch, - byte[] name, - byte[] r_array, - byte[] s_array, - byte[] prv_array){ - super(jsch); - if(name!=null) - this.name = name; - this.r_array = r_array; - this.s_array = s_array; - this.prv_array = prv_array; - if(prv_array!=null) - key_size = prv_array.length>=64 ? 521 : - (prv_array.length>=48 ? 384 : 256); - } - - @Override - void generate(int key_size) throws JSchException{ - this.key_size=key_size; - try{ - Class c=Class.forName(JSch.getConfig("keypairgen.ecdsa")).asSubclass(KeyPairGenECDSA.class); - KeyPairGenECDSA keypairgen=c.getDeclaredConstructor().newInstance(); - keypairgen.init(key_size); - prv_array=keypairgen.getD(); - r_array=keypairgen.getR(); - s_array=keypairgen.getS(); - name=Util.str2byte(names[prv_array.length>=64 ? 2 : - (prv_array.length>=48 ? 1 : 0)]); - keypairgen=null; - } - catch(Exception e){ - throw new JSchException(e.toString(), e); - } - } - - private static final byte[] begin = - Util.str2byte("-----BEGIN EC PRIVATE KEY-----"); - private static final byte[] end = - Util.str2byte("-----END EC PRIVATE KEY-----"); - - @Override - byte[] getBegin(){ return begin; } - @Override - byte[] getEnd(){ return end; } - - @Override - byte[] getPrivateKey(){ - - byte[] tmp = new byte[1]; tmp[0]=1; - - byte[] oid = oids[ - (r_array.length>=64) ? 2 : - ((r_array.length>=48) ? 1 : 0) - ]; - - byte[] point = toPoint(r_array, s_array); - - int bar = ((point.length+1)&0x80)==0 ? 3 : 4; - byte[] foo = new byte[point.length+bar]; - System.arraycopy(point, 0, foo, bar, point.length); - foo[0]=0x03; // BITSTRING - if(bar==3){ - foo[1]=(byte)(point.length+1); - } - else { - foo[1]=(byte)0x81; - foo[2]=(byte)(point.length+1); - } - point = foo; - - int content= - 1+countLength(tmp.length) + tmp.length + - 1+countLength(prv_array.length) + prv_array.length + - 1+countLength(oid.length) + oid.length + - 1+countLength(point.length) + point.length; - - int total= - 1+countLength(content)+content; // SEQUENCE - - byte[] plain=new byte[total]; - int index=0; - index=writeSEQUENCE(plain, index, content); - index=writeINTEGER(plain, index, tmp); - index=writeOCTETSTRING(plain, index, prv_array); - index=writeDATA(plain, (byte)0xa0, index, oid); - index=writeDATA(plain, (byte)0xa1, index, point); - - return plain; - } - - @Override - boolean parse(byte[] plain){ - try{ - - if(vendor==VENDOR_FSECURE){ - /* - if(plain[0]!=0x30){ // FSecure - return true; - } - return false; - */ - return false; - } - else if(vendor==VENDOR_PUTTY){ - /* - Buffer buf=new Buffer(plain); - buf.skip(plain.length); - - try { - byte[][] tmp = buf.getBytes(1, ""); - prv_array = tmp[0]; - } - catch(JSchException e){ - return false; - } - - return true; - */ - return false; - } - - // OPENSSH Key v1 Format - if (vendor == VENDOR_OPENSSH_V1) { - - final Buffer prvKeyBuffer = new Buffer(plain); - int checkInt1 = prvKeyBuffer.getInt(); // uint32 checkint1 - int checkInt2 = prvKeyBuffer.getInt(); // uint32 checkint2 - if (checkInt1 != checkInt2) { - throw new JSchException("check failed"); - } - - String keyType = Util.byte2str(prvKeyBuffer.getString()); // string keytype - - name = prvKeyBuffer.getString(); - if(!Arrays.asList(names).contains(Util.byte2str(name))){ - throw new IllegalArgumentException("unknown curve name "+Util.byte2str(name)); - } - - final int keyLen = prvKeyBuffer.getInt(); - final int x04 = prvKeyBuffer.getByte(); // in case of x04 it is uncompressed https://tools.ietf.org/html/rfc5480#page-7 - final byte[] x = new byte[(keyLen - 1) / 2]; - final byte[] y = new byte[(keyLen - 1) / 2]; - prvKeyBuffer.getByte(x); - prvKeyBuffer.getByte(y); - - - prv_array=prvKeyBuffer.getString(); - publicKeyComment=Util.byte2str(prvKeyBuffer.getString()); - r_array = x; - s_array = y; - key_size = x.length>=64 ? 521 : - (x.length>=48 ? 384 : 256); - - return true; - - } - - int index=0; - int length=0; - - if(plain[index]!=0x30)return false; - index++; // SEQUENCE - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - - if(plain[index]!=0x02)return false; - index++; // INTEGER - - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - - index+=length; - index++; // 0x04 - - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - - prv_array=new byte[length]; - System.arraycopy(plain, index, prv_array, 0, length); - - index+=length; - - index++; // 0xa0 - - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - - byte[] oid_array=new byte[length]; - System.arraycopy(plain, index, oid_array, 0, length); - index+=length; - - for(int i = 0; i0){ length=(length<<8)+(plain[index++]&0xff); } - } - - byte[] Q_array=new byte[length]; - System.arraycopy(plain, index, Q_array, 0, length); - index+=length; - - byte[][] tmp = fromPoint(Q_array); - r_array = tmp[0]; - s_array = tmp[1]; - - if(prv_array!=null) - key_size = prv_array.length>=64 ? 521 : - (prv_array.length>=48 ? 384 : 256); - } - catch(Exception e){ - //System.err.println(e); - //e.printStackTrace(); - return false; - } - return true; - } - - @Override - public byte[] getPublicKeyBlob(){ - byte[] foo = super.getPublicKeyBlob(); - - if(foo!=null) return foo; - - if(r_array==null) return null; - - byte[][] tmp = new byte[3][]; - tmp[0] = Util.str2byte("ecdsa-sha2-"+Util.byte2str(name)); - tmp[1] = name; - tmp[2] = new byte[1+r_array.length+s_array.length]; - tmp[2][0] = 4; // POINT_CONVERSION_UNCOMPRESSED - System.arraycopy(r_array, 0, tmp[2], 1, r_array.length); - System.arraycopy(s_array, 0, tmp[2], 1+r_array.length, s_array.length); - - return Buffer.fromBytes(tmp).buffer; - } - - @Override - byte[] getKeyTypeName(){ - return Util.str2byte("ecdsa-sha2-"+Util.byte2str(name)); - } - @Override - public int getKeyType(){ - return ECDSA; - } - @Override - public int getKeySize(){ - return key_size; - } - - @Override - public byte[] getSignature(byte[] data){ - try{ - Class c=Class.forName(JSch.getConfig("ecdsa-sha2-"+Util.byte2str(name))).asSubclass(SignatureECDSA.class); - SignatureECDSA ecdsa=c.getDeclaredConstructor().newInstance(); - ecdsa.init(); - ecdsa.setPrvKey(prv_array); - - ecdsa.update(data); - byte[] sig = ecdsa.sign(); - - byte[][] tmp = new byte[2][]; - tmp[0] = Util.str2byte("ecdsa-sha2-"+Util.byte2str(name)); - tmp[1] = sig; - return Buffer.fromBytes(tmp).buffer; - } - catch(Exception e){ - //System.err.println("e "+e); - } - return null; - } - - @Override - public byte[] getSignature(byte[] data, String al){ - return getSignature(data); - } - - @Override - public Signature getVerifier(){ - try{ - Class c=Class.forName(JSch.getConfig("ecdsa-sha2-"+Util.byte2str(name))).asSubclass(SignatureECDSA.class); - final SignatureECDSA ecdsa=c.getDeclaredConstructor().newInstance(); - ecdsa.init(); - - if(r_array == null && s_array == null && getPublicKeyBlob()!=null){ - Buffer buf = new Buffer(getPublicKeyBlob()); - buf.getString(); // ecdsa-sha2-nistp256 - buf.getString(); // nistp256 - byte[][] tmp = fromPoint(buf.getString()); - r_array = tmp[0]; - s_array = tmp[1]; - } - ecdsa.setPubKey(r_array, s_array); - return ecdsa; - } - catch(Exception e){ - //System.err.println("e "+e); - } - return null; - } - - @Override - public Signature getVerifier(String alg){ - return getVerifier(); - } - - static KeyPair fromSSHAgent(JSch jsch, Buffer buf) throws JSchException { - - byte[][] tmp = buf.getBytes(5, "invalid key format"); - - byte[] name = tmp[1]; // nistp256 - byte[][] foo = fromPoint(tmp[2]); - byte[] r_array = foo[0]; - byte[] s_array = foo[1]; - - byte[] prv_array = tmp[3]; - KeyPairECDSA kpair = new KeyPairECDSA(jsch, - name, - r_array, s_array, - prv_array); - kpair.publicKeyComment = Util.byte2str(tmp[4]); - kpair.vendor=VENDOR_OPENSSH; - return kpair; - } - - @Override - public byte[] forSSHAgent() throws JSchException { - if(isEncrypted()){ - throw new JSchException("key is encrypted."); - } - Buffer buf = new Buffer(); - buf.putString(Util.str2byte("ecdsa-sha2-"+Util.byte2str(name))); - buf.putString(name); - buf.putString(toPoint(r_array, s_array)); - buf.putString(prv_array); - buf.putString(Util.str2byte(publicKeyComment)); - byte[] result = new byte[buf.getLength()]; - buf.getByte(result, 0, result.length); - return result; - } - - static byte[] toPoint(byte[] r_array, byte[] s_array) { - byte[] tmp = new byte[1+r_array.length+s_array.length]; - tmp[0]=0x04; - System.arraycopy(r_array, 0, tmp, 1, r_array.length); - System.arraycopy(s_array, 0, tmp, 1+r_array.length, s_array.length); - return tmp; - } - - static byte[][] fromPoint(byte[] point) { - int i = 0; - while(point[i]!=4) i++; - i++; - byte[][] tmp = new byte[2][]; - byte[] r_array = new byte[(point.length-i)/2]; - byte[] s_array = new byte[(point.length-i)/2]; - // point[0] == 0x04 == POINT_CONVERSION_UNCOMPRESSED - System.arraycopy(point, i, r_array, 0, r_array.length); - System.arraycopy(point, i+r_array.length, s_array, 0, s_array.length); - tmp[0] = r_array; - tmp[1] = s_array; - - return tmp; - } - - @Override - public void dispose(){ - super.dispose(); - Util.bzero(prv_array); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEd25519.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEd25519.java deleted file mode 100644 index fed75354..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEd25519.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.util.Arrays; - -class KeyPairEd25519 extends KeyPairEdDSA{ - - private static int keySize = 32; - - KeyPairEd25519(JSch jsch){ - this(jsch, null, null); - } - - KeyPairEd25519(JSch jsch, - byte[] pub_array, - byte[] prv_array){ - super(jsch, pub_array, prv_array); - } - - @Override - public int getKeyType(){ return ED25519; } - @Override - public int getKeySize(){ return keySize; } - @Override - String getSshName(){ return "ssh-ed25519"; } - @Override - String getJceName(){ return "Ed25519"; } - - static KeyPair fromSSHAgent(JSch jsch, Buffer buf) throws JSchException { - - byte[][] tmp = buf.getBytes(4, "invalid key format"); - - byte[] pub_array = tmp[1]; - byte[] prv_array = Arrays.copyOf(tmp[2], keySize); - KeyPairEd25519 kpair = new KeyPairEd25519(jsch, pub_array, prv_array); - kpair.publicKeyComment = Util.byte2str(tmp[3]); - kpair.vendor=VENDOR_OPENSSH; - return kpair; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEd448.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEd448.java deleted file mode 100644 index ad68fb07..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEd448.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.util.Arrays; - -class KeyPairEd448 extends KeyPairEdDSA{ - - private static int keySize = 57; - - KeyPairEd448(JSch jsch){ - this(jsch, null, null); - } - - KeyPairEd448(JSch jsch, - byte[] pub_array, - byte[] prv_array){ - super(jsch, pub_array, prv_array); - } - - @Override - public int getKeyType(){ return ED448; } - @Override - public int getKeySize(){ return keySize; } - @Override - String getSshName(){ return "ssh-ed448"; } - @Override - String getJceName(){ return "Ed448"; } - - static KeyPair fromSSHAgent(JSch jsch, Buffer buf) throws JSchException { - - byte[][] tmp = buf.getBytes(4, "invalid key format"); - - byte[] pub_array = tmp[1]; - byte[] prv_array = Arrays.copyOf(tmp[2], keySize); - KeyPairEd448 kpair = new KeyPairEd448(jsch, pub_array, prv_array); - kpair.publicKeyComment = Util.byte2str(tmp[3]); - kpair.vendor=VENDOR_OPENSSH; - return kpair; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEdDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEdDSA.java deleted file mode 100644 index 48246d40..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEdDSA.java +++ /dev/null @@ -1,191 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.util.Arrays; - -abstract class KeyPairEdDSA extends KeyPair{ - private byte[] pub_array; - private byte[] prv_array; - - KeyPairEdDSA(JSch jsch, - byte[] pub_array, - byte[] prv_array){ - super(jsch); - this.pub_array = pub_array; - this.prv_array = prv_array; - } - - abstract String getSshName(); - abstract String getJceName(); - - @Override - void generate(int key_size) throws JSchException{ - try{ - Class c=Class.forName(JSch.getConfig("keypairgen.eddsa")).asSubclass(KeyPairGenEdDSA.class); - KeyPairGenEdDSA keypairgen=c.getDeclaredConstructor().newInstance(); - keypairgen.init(getJceName(), getKeySize()); - pub_array=keypairgen.getPub(); - prv_array=keypairgen.getPrv(); - - keypairgen=null; - } - catch(Exception | NoClassDefFoundError e){ - //System.err.println("KeyPairEdDSA: "+e); - throw new JSchException(e.toString(), e); - } - } - - // These methods appear to be for writing keys to a file. - // And since writing VENDOR_OPENSSH_V1 isn't supported yet, have these methods fail. - @Override - byte[] getBegin(){ throw new UnsupportedOperationException(); } - @Override - byte[] getEnd(){ throw new UnsupportedOperationException(); } - @Override - byte[] getPrivateKey(){ throw new UnsupportedOperationException(); } - - @Override - boolean parse(byte [] plain){ - - // Only OPENSSH Key v1 Format supported for EdDSA keys - if(vendor != VENDOR_OPENSSH_V1) return false; - try{ - // OPENSSH Key v1 Format - final Buffer buf = new Buffer(plain); - int checkInt1 = buf.getInt(); // uint32 checkint1 - int checkInt2 = buf.getInt(); // uint32 checkint2 - if (checkInt1 != checkInt2) { - throw new JSchException("check failed"); - } - String keyType = Util.byte2str(buf.getString()); // string keytype - pub_array = buf.getString(); // public key - // OpenSSH stores private key in first half of string and duplicate copy of public key in second half of string - byte[] tmp = buf.getString(); // secret key (private key + public key) - prv_array = Arrays.copyOf(tmp, getKeySize()); - publicKeyComment = Util.byte2str(buf.getString()); - return true; - } - catch(Exception e){ - //System.err.println(e); - return false; - } - } - - @Override - public byte[] getPublicKeyBlob(){ - byte[] foo=super.getPublicKeyBlob(); - if(foo!=null) return foo; - - if(pub_array==null) return null; - byte[][] tmp = new byte[2][]; - tmp[0] = getKeyTypeName(); - tmp[1] = pub_array; - return Buffer.fromBytes(tmp).buffer; - } - - @Override - byte[] getKeyTypeName(){ return Util.str2byte(getSshName()); } - - @Override - public byte[] getSignature(byte[] data){ - return getSignature(data, getSshName()); - } - - @Override - public byte[] getSignature(byte[] data, String alg){ - try{ - Class c=Class.forName(JSch.getConfig(alg)).asSubclass(SignatureEdDSA.class); - SignatureEdDSA eddsa=c.getDeclaredConstructor().newInstance(); - eddsa.init(); - eddsa.setPrvKey(prv_array); - - eddsa.update(data); - byte[] sig = eddsa.sign(); - byte[][] tmp = new byte[2][]; - tmp[0] = Util.str2byte(alg); - tmp[1] = sig; - return Buffer.fromBytes(tmp).buffer; - } - catch(Exception | NoClassDefFoundError e){ - } - return null; - } - - @Override - public Signature getVerifier(){ - return getVerifier(getSshName()); - } - - @Override - public Signature getVerifier(String alg){ - try{ - Class c=Class.forName(JSch.getConfig(alg)).asSubclass(SignatureEdDSA.class); - SignatureEdDSA eddsa=c.getDeclaredConstructor().newInstance(); - eddsa.init(); - - if(pub_array == null && getPublicKeyBlob()!=null){ - Buffer buf = new Buffer(getPublicKeyBlob()); - buf.getString(); - pub_array = buf.getString(); - } - - eddsa.setPubKey(pub_array); - return eddsa; - } - catch(Exception | NoClassDefFoundError e){ - } - return null; - } - - @Override - public byte[] forSSHAgent() throws JSchException { - if(isEncrypted()){ - throw new JSchException("key is encrypted."); - } - Buffer buf = new Buffer(); - buf.putString(getKeyTypeName()); - buf.putString(pub_array); - byte[] tmp = new byte[prv_array.length + pub_array.length]; - System.arraycopy(prv_array, 0, tmp, 0, prv_array.length); - System.arraycopy(pub_array, 0, tmp, prv_array.length, pub_array.length); - buf.putString(tmp); - buf.putString(Util.str2byte(publicKeyComment)); - byte[] result = new byte[buf.getLength()]; - buf.getByte(result, 0, result.length); - return result; - } - - @Override - public void dispose(){ - super.dispose(); - Util.bzero(prv_array); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenDSA.java deleted file mode 100644 index 2c7ee097..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenDSA.java +++ /dev/null @@ -1,39 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -public interface KeyPairGenDSA{ - void init(int key_size) throws Exception; - byte[] getX(); - byte[] getY(); - byte[] getP(); - byte[] getQ(); - byte[] getG(); -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenECDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenECDSA.java deleted file mode 100644 index 18369af5..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenECDSA.java +++ /dev/null @@ -1,37 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -public interface KeyPairGenECDSA{ - void init(int key_size) throws Exception; - byte[] getD(); - byte[] getR(); - byte[] getS(); -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenEdDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenEdDSA.java deleted file mode 100644 index e6983524..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenEdDSA.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -public interface KeyPairGenEdDSA{ - void init(String Name, int keylen) throws Exception; - byte[] getPub(); - byte[] getPrv(); -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenRSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenRSA.java deleted file mode 100644 index 78334f5a..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenRSA.java +++ /dev/null @@ -1,43 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -public interface KeyPairGenRSA{ - void init(int key_size) throws Exception; - byte[] getD(); - byte[] getE(); - byte[] getN(); - - byte[] getC(); - byte[] getEP(); - byte[] getEQ(); - byte[] getP(); - byte[] getQ(); -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenXEC.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenXEC.java deleted file mode 100644 index 2bb51f71..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenXEC.java +++ /dev/null @@ -1,34 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -public interface KeyPairGenXEC{ - void init(String name) throws Exception; -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairPKCS8.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairPKCS8.java deleted file mode 100644 index fa1f3f06..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairPKCS8.java +++ /dev/null @@ -1,386 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.util.Vector; -import java.math.BigInteger; - -class KeyPairPKCS8 extends KeyPair { - private static final byte[] rsaEncryption = { - (byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86, - (byte)0xf7, (byte)0x0d, (byte)0x01, (byte)0x01, (byte)0x01 - }; - - private static final byte[] dsaEncryption = { - (byte)0x2a, (byte)0x86, (byte)0x48, (byte)0xce, - (byte)0x38, (byte)0x04, (byte)0x1 - }; - - private static final byte[] pbes2 = { - (byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86, (byte)0xf7, - (byte)0x0d, (byte)0x01, (byte)0x05, (byte)0x0d - }; - - private static final byte[] pbkdf2 = { - (byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86, (byte)0xf7, - (byte)0x0d, (byte)0x01, (byte)0x05, (byte)0x0c - }; - - private static final byte[] aes128cbc = { - (byte)0x60, (byte)0x86, (byte)0x48, (byte)0x01, (byte)0x65, - (byte)0x03, (byte)0x04, (byte)0x01, (byte)0x02 - }; - - private static final byte[] aes192cbc = { - (byte)0x60, (byte)0x86, (byte)0x48, (byte)0x01, (byte)0x65, - (byte)0x03, (byte)0x04, (byte)0x01, (byte)0x16 - }; - - private static final byte[] aes256cbc = { - (byte)0x60, (byte)0x86, (byte)0x48, (byte)0x01, (byte)0x65, - (byte)0x03, (byte)0x04, (byte)0x01, (byte)0x2a - }; - - private static final byte[] pbeWithMD5AndDESCBC = { - (byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86, (byte)0xf7, - (byte)0x0d, (byte)0x01, (byte)0x05, (byte)0x03 - }; - - private KeyPair kpair = null; - - KeyPairPKCS8(JSch jsch){ - super(jsch); - } - - @Override - void generate(int key_size) throws JSchException{ - } - - private static final byte[] begin=Util.str2byte("-----BEGIN DSA PRIVATE KEY-----"); - private static final byte[] end=Util.str2byte("-----END DSA PRIVATE KEY-----"); - - @Override - byte[] getBegin(){ return begin; } - @Override - byte[] getEnd(){ return end; } - - @Override - byte[] getPrivateKey(){ - return null; - } - - @Override - boolean parse(byte[] plain){ - - /* from RFC5208 - PrivateKeyInfo ::= SEQUENCE { - version Version, - privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, - privateKey PrivateKey, - attributes [0] IMPLICIT Attributes OPTIONAL - } - Version ::= INTEGER - PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier - PrivateKey ::= OCTET STRING - Attributes ::= SET OF Attribute - } - */ - - try{ - Vector values = new Vector<>(); - - ASN1[] contents = null; - ASN1 asn1 = new ASN1(plain); - contents = asn1.getContents(); - - ASN1 privateKeyAlgorithm = contents[1]; - ASN1 privateKey = contents[2]; - - contents = privateKeyAlgorithm.getContents(); - byte[] privateKeyAlgorithmID = contents[0].getContent(); - contents = contents[1].getContents(); - if(contents.length>0){ - for(int i = 0; i < contents.length; i++){ - values.addElement(contents[i].getContent()); - } - } - - byte[] _data = privateKey.getContent(); - - KeyPair _kpair = null; - if(Util.array_equals(privateKeyAlgorithmID, rsaEncryption)){ - _kpair = new KeyPairRSA(jsch); - _kpair.copy(this); - if(_kpair.parse(_data)){ - kpair = _kpair; - } - } - else if(Util.array_equals(privateKeyAlgorithmID, dsaEncryption)){ - asn1 = new ASN1(_data); - if(values.size() == 0) { // embedded DSA parameters format - /* - SEQUENCE - SEQUENCE - INTEGER // P_array - INTEGER // Q_array - INTEGER // G_array - INTEGER // prv_array - */ - contents = asn1.getContents(); - byte[] bar = contents[1].getContent(); - contents = contents[0].getContents(); - for(int i = 0; i < contents.length; i++){ - values.addElement(contents[i].getContent()); - } - values.addElement(bar); - } - else { - /* - INTEGER // prv_array - */ - values.addElement(asn1.getContent()); - } - - byte[] P_array = values.elementAt(0); - byte[] Q_array = values.elementAt(1); - byte[] G_array = values.elementAt(2); - byte[] prv_array = values.elementAt(3); - // Y = g^X mode p - byte[] pub_array = - (new BigInteger(G_array)). - modPow(new BigInteger(prv_array), new BigInteger(P_array)). - toByteArray(); - - KeyPairDSA _key = new KeyPairDSA(jsch, - P_array, Q_array, G_array, - pub_array, prv_array); - plain = _key.getPrivateKey(); - - _kpair = new KeyPairDSA(jsch); - _kpair.copy(this); - if(_kpair.parse(plain)){ - kpair = _kpair; - } - } - } - catch(ASN1Exception e){ - return false; - } - catch(Exception e){ - //System.err.println(e); - return false; - } - return kpair != null; - } - - @Override - public byte[] getPublicKeyBlob(){ - return kpair.getPublicKeyBlob(); - } - - @Override - byte[] getKeyTypeName(){ return kpair.getKeyTypeName();} - @Override - public int getKeyType(){return kpair.getKeyType();} - - @Override - public int getKeySize(){ - return kpair.getKeySize(); - } - - @Override - public byte[] getSignature(byte[] data){ - return kpair.getSignature(data); - } - - @Override - public byte[] getSignature(byte[] data, String alg){ - return kpair.getSignature(data, alg); - } - - @Override - public Signature getVerifier(){ - return kpair.getVerifier(); - } - - @Override - public Signature getVerifier(String alg){ - return kpair.getVerifier(alg); - } - - @Override - public byte[] forSSHAgent() throws JSchException { - return kpair.forSSHAgent(); - } - - @Override - public boolean decrypt(byte[] _passphrase){ - if(!isEncrypted()){ - return true; - } - if(_passphrase==null){ - return !isEncrypted(); - } - - /* - SEQUENCE - SEQUENCE - OBJECT :PBES2 - SEQUENCE - SEQUENCE - OBJECT :PBKDF2 - SEQUENCE - OCTET STRING [HEX DUMP]:E4E24ADC9C00BD4D - INTEGER :0800 - SEQUENCE - OBJECT :aes-128-cbc - OCTET STRING [HEX DUMP]:5B66E6B3BF03944C92317BC370CC3AD0 - OCTET STRING [HEX DUMP]: - -or - - SEQUENCE - SEQUENCE - OBJECT :pbeWithMD5AndDES-CBC - SEQUENCE - OCTET STRING [HEX DUMP]:DBF75ECB69E3C0FC - INTEGER :0800 - OCTET STRING [HEX DUMP] - */ - - try{ - - ASN1[] contents = null; - ASN1 asn1 = new ASN1(data); - - contents = asn1.getContents(); - - byte[] _data = contents[1].getContent(); - - ASN1 pbes = contents[0]; - contents = pbes.getContents(); - byte[] pbesid = contents[0].getContent(); - ASN1 pbesparam = contents[1]; - - byte[] salt = null; - int iterations = 0; - byte[] iv = null; - byte[] encryptfuncid = null; - - if(Util.array_equals(pbesid, pbes2)){ - contents = pbesparam.getContents(); - ASN1 pbkdf = contents[0]; - ASN1 encryptfunc = contents[1]; - contents = pbkdf.getContents(); - byte[] pbkdfid = contents[0].getContent(); - ASN1 pbkdffunc = contents[1]; - contents = pbkdffunc.getContents(); - salt = contents[0].getContent(); - iterations = - Integer.parseInt((new BigInteger(contents[1].getContent())).toString()); - - contents = encryptfunc.getContents(); - encryptfuncid = contents[0].getContent(); - iv = contents[1].getContent(); - } - else if(Util.array_equals(pbesid, pbeWithMD5AndDESCBC)){ - // not supported - return false; - } - else { - return false; - } - - Cipher cipher=getCipher(encryptfuncid); - if(cipher==null) return false; - - byte[] key=null; - try{ - Class c=Class.forName(JSch.getConfig("pbkdf")).asSubclass(PBKDF.class); - PBKDF tmp=c.getDeclaredConstructor().newInstance(); - key = tmp.getKey(_passphrase, salt, iterations, cipher.getBlockSize()); - } - catch(Exception ee){ - } - - if(key==null){ - return false; - } - - cipher.init(Cipher.DECRYPT_MODE, key, iv); - Util.bzero(key); - byte[] plain=new byte[_data.length]; - cipher.update(_data, 0, _data.length, plain, 0); - if(parse(plain)){ - encrypted=false; - return true; - } - } - catch(ASN1Exception e){ - // System.err.println(e); - } - catch(Exception e){ - // System.err.println(e); - } - - return false; - } - - Cipher getCipher(byte[] id){ - Cipher cipher=null; - String name = null; - try{ - if(Util.array_equals(id, aes128cbc)){ - name="aes128-cbc"; - } - else if(Util.array_equals(id, aes192cbc)){ - name="aes192-cbc"; - } - else if(Util.array_equals(id, aes256cbc)){ - name="aes256-cbc"; - } - Class c=Class.forName(JSch.getConfig(name)).asSubclass(Cipher.class); - cipher=c.getDeclaredConstructor().newInstance(); - } - catch(Exception e){ - if(jsch.getInstanceLogger().isEnabled(Logger.FATAL)){ - String message=""; - if(name==null){ - message="unknown oid: "+Util.toHex(id); - } - else { - message="function "+name+" is not supported"; - } - jsch.getInstanceLogger().log(Logger.FATAL, "PKCS8: "+message); - } - } - return cipher; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairRSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairRSA.java deleted file mode 100644 index eef7ffa3..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairRSA.java +++ /dev/null @@ -1,461 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.math.BigInteger; - -class KeyPairRSA extends KeyPair{ - private byte[] n_array; // modulus p multiply q - private byte[] pub_array; // e - private byte[] prv_array; // d e^-1 mod (p-1)(q-1) - - private byte[] p_array; // prime p - private byte[] q_array; // prime q - private byte[] ep_array; // prime exponent p dmp1 == prv mod (p-1) - private byte[] eq_array; // prime exponent q dmq1 == prv mod (q-1) - private byte[] c_array; // coefficient iqmp == modinv(q, p) == q^-1 mod p - - private int key_size=1024; - - KeyPairRSA(JSch jsch){ - this(jsch, null, null, null); - } - - KeyPairRSA(JSch jsch, - byte[] n_array, - byte[] pub_array, - byte[] prv_array){ - super(jsch); - this.n_array = n_array; - this.pub_array = pub_array; - this.prv_array = prv_array; - if(n_array!=null){ - key_size = (new BigInteger(n_array)).bitLength(); - } - } - - @Override - void generate(int key_size) throws JSchException{ - this.key_size=key_size; - try{ - Class c=Class.forName(JSch.getConfig("keypairgen.rsa")).asSubclass(KeyPairGenRSA.class); - KeyPairGenRSA keypairgen=c.getDeclaredConstructor().newInstance(); - keypairgen.init(key_size); - pub_array=keypairgen.getE(); - prv_array=keypairgen.getD(); - n_array=keypairgen.getN(); - - p_array=keypairgen.getP(); - q_array=keypairgen.getQ(); - ep_array=keypairgen.getEP(); - eq_array=keypairgen.getEQ(); - c_array=keypairgen.getC(); - - keypairgen=null; - } - catch(Exception e){ - //System.err.println("KeyPairRSA: "+e); - throw new JSchException(e.toString(), e); - } - } - - private static final byte[] begin=Util.str2byte("-----BEGIN RSA PRIVATE KEY-----"); - private static final byte[] end=Util.str2byte("-----END RSA PRIVATE KEY-----"); - - @Override - byte[] getBegin(){ return begin; } - @Override - byte[] getEnd(){ return end; } - - @Override - byte[] getPrivateKey(){ - int content= - 1+countLength(1) + 1 + // INTEGER - 1+countLength(n_array.length) + n_array.length + // INTEGER N - 1+countLength(pub_array.length) + pub_array.length + // INTEGER pub - 1+countLength(prv_array.length) + prv_array.length+ // INTEGER prv - 1+countLength(p_array.length) + p_array.length+ // INTEGER p - 1+countLength(q_array.length) + q_array.length+ // INTEGER q - 1+countLength(ep_array.length) + ep_array.length+ // INTEGER ep - 1+countLength(eq_array.length) + eq_array.length+ // INTEGER eq - 1+countLength(c_array.length) + c_array.length; // INTEGER c - - int total= - 1+countLength(content)+content; // SEQUENCE - - byte[] plain=new byte[total]; - int index=0; - index=writeSEQUENCE(plain, index, content); - index=writeINTEGER(plain, index, new byte[1]); // 0 - index=writeINTEGER(plain, index, n_array); - index=writeINTEGER(plain, index, pub_array); - index=writeINTEGER(plain, index, prv_array); - index=writeINTEGER(plain, index, p_array); - index=writeINTEGER(plain, index, q_array); - index=writeINTEGER(plain, index, ep_array); - index=writeINTEGER(plain, index, eq_array); - index=writeINTEGER(plain, index, c_array); - return plain; - } - - @Override - boolean parse(byte [] plain){ - - try{ - int index=0; - int length=0; - - if(vendor==VENDOR_PUTTY){ - Buffer buf = new Buffer(plain); - buf.skip(plain.length); - - try { - byte[][] tmp = buf.getBytes(4, ""); - prv_array = tmp[0]; - p_array = tmp[1]; - q_array = tmp[2]; - c_array = tmp[3]; - } - catch(JSchException e){ - return false; - } - - getEPArray(); - getEQArray(); - - return true; - } - - if(vendor==VENDOR_FSECURE){ - if(plain[index]!=0x30){ // FSecure - Buffer buf=new Buffer(plain); - pub_array=buf.getMPIntBits(); - prv_array=buf.getMPIntBits(); - n_array=buf.getMPIntBits(); - byte[] u_array=buf.getMPIntBits(); - p_array=buf.getMPIntBits(); - q_array=buf.getMPIntBits(); - if(n_array!=null){ - key_size = (new BigInteger(n_array)).bitLength(); - } - - getEPArray(); - getEQArray(); - getCArray(); - - return true; - } - return false; - } - - // OPENSSH Key v1 Format - if (vendor == VENDOR_OPENSSH_V1) { - final Buffer prvKEyBuffer = new Buffer(plain); - int checkInt1 = prvKEyBuffer.getInt(); // uint32 checkint1 - int checkInt2 = prvKEyBuffer.getInt(); // uint32 checkint2 - if (checkInt1 != checkInt2) { - throw new JSchException("check failed"); - } - String keyType = Util.byte2str(prvKEyBuffer.getString()); // string keytype - n_array = prvKEyBuffer.getMPInt(); // Modulus - pub_array=prvKEyBuffer.getMPInt(); // Public Exponent - prv_array = prvKEyBuffer.getMPInt(); // Private Exponent - c_array= prvKEyBuffer.getMPInt(); // iqmp (q^-1 mod p) - p_array=prvKEyBuffer.getMPInt(); // p (Prime 1) - q_array=prvKEyBuffer.getMPInt(); // q (Prime 2) - - getEPArray(); - getEQArray(); - - return true; - } - - /* - Key must be in the following ASN.1 DER encoding, - RSAPrivateKey ::= SEQUENCE { - version Version, - modulus INTEGER, -- n - publicExponent INTEGER, -- e - privateExponent INTEGER, -- d - prime1 INTEGER, -- p - prime2 INTEGER, -- q - exponent1 INTEGER, -- d mod (p-1) - exponent2 INTEGER, -- d mod (q-1) - coefficient INTEGER, -- (inverse of q) mod p - otherPrimeInfos OtherPrimeInfos OPTIONAL - } - */ - - index++; // SEQUENCE - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - - if(plain[index]!=0x02)return false; - index++; // INTEGER - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - index+=length; - - index++; - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - n_array=new byte[length]; - System.arraycopy(plain, index, n_array, 0, length); - index+=length; - - index++; - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - pub_array=new byte[length]; - System.arraycopy(plain, index, pub_array, 0, length); - index+=length; - - index++; - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - prv_array=new byte[length]; - System.arraycopy(plain, index, prv_array, 0, length); - index+=length; - - index++; - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - p_array=new byte[length]; - System.arraycopy(plain, index, p_array, 0, length); - index+=length; - - index++; - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - q_array=new byte[length]; - System.arraycopy(plain, index, q_array, 0, length); - index+=length; - - index++; - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - ep_array=new byte[length]; - System.arraycopy(plain, index, ep_array, 0, length); - index+=length; - - index++; - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - eq_array=new byte[length]; - System.arraycopy(plain, index, eq_array, 0, length); - index+=length; - - index++; - length=plain[index++]&0xff; - if((length&0x80)!=0){ - int foo=length&0x7f; length=0; - while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); } - } - c_array=new byte[length]; - System.arraycopy(plain, index, c_array, 0, length); - index+=length; - - if(n_array!=null){ - key_size = (new BigInteger(n_array)).bitLength(); - } - - } - catch(Exception e){ - //System.err.println(e); - return false; - } - return true; - } - - @Override - public byte[] getPublicKeyBlob(){ - byte[] foo=super.getPublicKeyBlob(); - if(foo!=null) return foo; - - if(pub_array==null) return null; - byte[][] tmp = new byte[3][]; - tmp[0] = sshrsa; - tmp[1] = pub_array; - tmp[2] = n_array; - return Buffer.fromBytes(tmp).buffer; - } - - private static final byte[] sshrsa=Util.str2byte("ssh-rsa"); - @Override - byte[] getKeyTypeName(){return sshrsa;} - @Override - public int getKeyType(){return RSA;} - - @Override - public int getKeySize(){ - return key_size; - } - - @Override - public byte[] getSignature(byte[] data){ - return getSignature(data, "ssh-rsa"); - } - - @Override - public byte[] getSignature(byte[] data, String alg){ - try{ - Class c=Class.forName(JSch.getConfig(alg)).asSubclass(SignatureRSA.class); - SignatureRSA rsa=c.getDeclaredConstructor().newInstance(); - rsa.init(); - rsa.setPrvKey(prv_array, n_array); - - rsa.update(data); - byte[] sig = rsa.sign(); - byte[][] tmp = new byte[2][]; - tmp[0] = Util.str2byte(alg); - tmp[1] = sig; - return Buffer.fromBytes(tmp).buffer; - } - catch(Exception e){ - } - return null; - } - - @Override - public Signature getVerifier(){ - return getVerifier("ssh-rsa"); - } - - @Override - public Signature getVerifier(String alg){ - try{ - Class c=Class.forName(JSch.getConfig(alg)).asSubclass(SignatureRSA.class); - SignatureRSA rsa=c.getDeclaredConstructor().newInstance(); - rsa.init(); - - if(pub_array == null && n_array == null && getPublicKeyBlob()!=null){ - Buffer buf = new Buffer(getPublicKeyBlob()); - buf.getString(); - pub_array = buf.getString(); - n_array = buf.getString(); - } - - rsa.setPubKey(pub_array, n_array); - return rsa; - } - catch(Exception e){ - } - return null; - } - - static KeyPair fromSSHAgent(JSch jsch, Buffer buf) throws JSchException { - - byte[][] tmp = buf.getBytes(8, "invalid key format"); - - byte[] n_array = tmp[1]; - byte[] pub_array = tmp[2]; - byte[] prv_array = tmp[3]; - KeyPairRSA kpair = new KeyPairRSA(jsch, n_array, pub_array, prv_array); - kpair.c_array = tmp[4]; // iqmp - kpair.p_array = tmp[5]; - kpair.q_array = tmp[6]; - kpair.publicKeyComment = Util.byte2str(tmp[7]); - kpair.vendor=VENDOR_OPENSSH; - return kpair; - } - - @Override - public byte[] forSSHAgent() throws JSchException { - if(isEncrypted()){ - throw new JSchException("key is encrypted."); - } - Buffer buf = new Buffer(); - buf.putString(sshrsa); - buf.putString(n_array); - buf.putString(pub_array); - buf.putString(prv_array); - buf.putString(getCArray()); - buf.putString(p_array); - buf.putString(q_array); - buf.putString(Util.str2byte(publicKeyComment)); - byte[] result = new byte[buf.getLength()]; - buf.getByte(result, 0, result.length); - return result; - } - - private byte[] getEPArray(){ - if(ep_array==null){ - ep_array=(new BigInteger(prv_array)).mod(new BigInteger(p_array).subtract(BigInteger.ONE)).toByteArray(); - } - return ep_array; - } - - private byte[] getEQArray(){ - if(eq_array==null){ - eq_array=(new BigInteger(prv_array)).mod(new BigInteger(q_array).subtract(BigInteger.ONE)).toByteArray(); - } - return eq_array; - } - - private byte[] getCArray(){ - if(c_array==null){ - c_array=(new BigInteger(q_array)).modInverse(new BigInteger(p_array)).toByteArray(); - } - return c_array; - } - - @Override - public void dispose(){ - super.dispose(); - Util.bzero(prv_array); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KnownHosts.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KnownHosts.java deleted file mode 100644 index ae8f5f16..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KnownHosts.java +++ /dev/null @@ -1,622 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Vector; - -class KnownHosts implements HostKeyRepository{ - private JSch jsch=null; - private String known_hosts=null; - private Vector pool=null; - - MAC hmacsha1; - - KnownHosts(JSch jsch) { - super(); - this.jsch=jsch; - getHMACSHA1(); - pool=new Vector<>(); - } - - void setKnownHosts(String filename) throws JSchException{ - try{ - known_hosts = filename; - FileInputStream fis=new FileInputStream(Util.checkTilde(filename)); - setKnownHosts(fis); - } - catch(FileNotFoundException e){ - // The non-existing file should be allowed. - } - } - void setKnownHosts(InputStream input) throws JSchException{ - pool.removeAllElements(); - StringBuilder sb=new StringBuilder(); - byte i; - int j; - boolean error=false; - try{ - InputStream fis=input; - String host; - String key=null; - int type; - byte[] buf=new byte[1024]; - int bufl=0; -loop: - while(true){ - bufl=0; - while(true){ - j=fis.read(); - if(j==-1){ - if(bufl==0){ break loop; } - break; - } - if(j==0x0d){ continue; } - if(j==0x0a){ break; } - if(buf.length<=bufl){ - if(bufl>1024*10) break; // too long... - byte[] newbuf=new byte[buf.length*2]; - System.arraycopy(buf, 0, newbuf, 0, buf.length); - buf=newbuf; - } - buf[bufl++]=(byte)j; - } - - j=0; - while(j=bufl){ - addInvalidLine(Util.byte2str(buf, 0, bufl)); - continue loop; - } - - sb.setLength(0); - while(j=bufl || host.length()==0){ - addInvalidLine(Util.byte2str(buf, 0, bufl)); - continue loop; - } - - while(j=bufl || host.length()==0){ - addInvalidLine(Util.byte2str(buf, 0, bufl)); - continue loop; - } - - while(j=bufl){ - addInvalidLine(Util.byte2str(buf, 0, bufl)); - continue loop; - } - - while(j1 - ){ - return check(host.substring(1, host.indexOf("]:")), key); - } - - return result; - } - - @Override - public void add(HostKey hostkey, UserInfo userinfo){ - int type=hostkey.type; - String host=hostkey.getHost(); -// byte[] key=hostkey.key; - - HostKey hk=null; - synchronized(pool){ - for(int i=0; i v = new ArrayList<>(); - for(int i=0; i1){ - HostKey[] tmp = - getHostKey(host.substring(1, host.indexOf("]:")), type); - if(tmp.length > 0){ - HostKey[] bar = new HostKey[foo.length + tmp.length]; - System.arraycopy(foo, 0, bar, 0, foo.length); - System.arraycopy(tmp, 0, bar, foo.length, tmp.length); - foo = bar; - } - } - return foo; - } - } - @Override - public void remove(String host, String type){ - remove(host, type, null); - } - @Override - public void remove(String host, String type, byte[] key){ - boolean sync=false; - synchronized(pool){ - for(int i=0; i c=Class.forName(hmacClassname).asSubclass(MAC.class); - return c.getDeclaredConstructor().newInstance(); - } - catch(Exception e){ - jsch.getInstanceLogger().log(Logger.ERROR, "unable to instantiate HMAC-class " + hmacClassname, e); - throw new IllegalArgumentException("instantiation of " + hmacClassname + " lead to an error", e); - } - } - - HostKey createHashedHostKey(String host, byte[]key) throws JSchException { - HashedHostKey hhk=new HashedHostKey(host, key); - hhk.hash(); - return hhk; - } - class HashedHostKey extends HostKey{ - private static final String HASH_MAGIC="|1|"; - private static final String HASH_DELIM="|"; - - private boolean hashed=false; - byte[] salt=null; - byte[] hash=null; - - HashedHostKey(String host, byte[] key) throws JSchException { - this(host, GUESS, key); - } - HashedHostKey(String host, int type, byte[] key) throws JSchException { - this("", host, type, key, null); - } - HashedHostKey(String marker, String host, int type, byte[] key, String comment) throws JSchException { - super(marker, host, type, key, comment); - if(this.host.startsWith(HASH_MAGIC) && - this.host.substring(HASH_MAGIC.length()).indexOf(HASH_DELIM)>0){ - String data=this.host.substring(HASH_MAGIC.length()); - String _salt=data.substring(0, data.indexOf(HASH_DELIM)); - String _hash=data.substring(data.indexOf(HASH_DELIM)+1); - salt=Util.fromBase64(Util.str2byte(_salt), 0, _salt.length()); - hash=Util.fromBase64(Util.str2byte(_hash), 0, _hash.length()); - int blockSize = hmacsha1.getBlockSize(); - if (salt.length!=blockSize || hash.length!=blockSize) { - salt=null; - hash=null; - return; - } - hashed=true; - } - } - - @Override - boolean isMatched(String _host){ - if(!hashed){ - return super.isMatched(_host); - } - try{ - synchronized(hmacsha1){ - hmacsha1.init(salt); - byte[] foo=Util.str2byte(_host); - hmacsha1.update(foo, 0, foo.length); - byte[] bar=new byte[hmacsha1.getBlockSize()]; - hmacsha1.doFinal(bar, 0); - return Util.array_equals(hash, bar); - } - } - catch(Exception e){ - jsch.getInstanceLogger().log(Logger.ERROR, "an error occurred while trying to check hash for host " + _host, e); - } - return false; - } - - boolean isHashed(){ - return hashed; - } - - void hash(){ - if(hashed) - return; - if(salt==null){ - Random random=Session.random; - synchronized(random){ - salt=new byte[hmacsha1.getBlockSize()]; - random.fill(salt, 0, salt.length); - } - } - try{ - synchronized(hmacsha1){ - hmacsha1.init(salt); - byte[] foo=Util.str2byte(host); - hmacsha1.update(foo, 0, foo.length); - hash=new byte[hmacsha1.getBlockSize()]; - hmacsha1.doFinal(hash, 0); - } - } - catch(Exception e){ - jsch.getInstanceLogger().log(Logger.ERROR, "an error occurred while trying to calculate the hash for host " + host, e); - salt = null; - hash = null; - return; - } - host=HASH_MAGIC+Util.byte2str(Util.toBase64(salt, 0, salt.length, true))+ - HASH_DELIM+Util.byte2str(Util.toBase64(hash, 0, hash.length, true)); - hashed=true; - } - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/LocalIdentityRepository.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/LocalIdentityRepository.java deleted file mode 100644 index 82b9cbdd..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/LocalIdentityRepository.java +++ /dev/null @@ -1,157 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.util.Vector; - -class LocalIdentityRepository implements IdentityRepository { - private static final String name = "Local Identity Repository"; - - private Vector identities = new Vector<>(); - private JSch jsch; - - LocalIdentityRepository(JSch jsch){ - this.jsch = jsch; - } - - @Override - public String getName(){ - return name; - } - - @Override - public int getStatus(){ - return RUNNING; - } - - @Override - public synchronized Vector getIdentities() { - removeDupulicates(); - Vector v = new Vector<>(); - for(int i=0; i v = new Vector<>(); - int len = identities.size(); - if(len == 0) return; - for(int i=0; i - *
  • Host
  • - *
  • User
  • - *
  • Hostname
  • - *
  • Port
  • - *
  • PreferredAuthentications
  • - *
  • PubkeyAcceptedAlgorithms
  • - *
  • FingerprintHash
  • - *
  • IdentityFile
  • - *
  • NumberOfPasswordPrompts
  • - *
  • ConnectTimeout
  • - *
  • HostKeyAlias
  • - *
  • UserKnownHostsFile
  • - *
  • KexAlgorithms
  • - *
  • HostKeyAlgorithms
  • - *
  • Ciphers
  • - *
  • Macs
  • - *
  • Compression
  • - *
  • CompressionLevel
  • - *
  • ForwardAgent
  • - *
  • RequestTTY
  • - *
  • ServerAliveInterval
  • - *
  • LocalForward
  • - *
  • RemoteForward
  • - *
  • ClearAllForwardings
  • - * - * - * @see ConfigRepository - */ -public class OpenSSHConfig implements ConfigRepository { - - private static final Set keysWithListAdoption = Stream - .of("KexAlgorithms", "Ciphers","HostKeyAlgorithms", "MACs", "PubkeyAcceptedAlgorithms", "PubkeyAcceptedKeyTypes") - .map(String::toUpperCase).collect(Collectors.toSet()); - - /** - * Parses the given string, and returns an instance of ConfigRepository. - * - * @param conf string, which includes OpenSSH's config - * @return an instanceof OpenSSHConfig - */ - public static OpenSSHConfig parse(String conf) throws IOException { - try(Reader r = new StringReader(conf)) { - try(BufferedReader br = new BufferedReader(r)) { - return new OpenSSHConfig(br); - } - } - } - - /** - * Parses the given file, and returns an instance of ConfigRepository. - * - * @param file OpenSSH's config file - * @return an instanceof OpenSSHConfig - */ - public static OpenSSHConfig parseFile(String file) throws IOException { - try(BufferedReader br = Files.newBufferedReader(Paths.get(Util.checkTilde(file)), StandardCharsets.UTF_8)) { - return new OpenSSHConfig(br); - } - } - - OpenSSHConfig(BufferedReader br) throws IOException { - _parse(br); - } - - private final Hashtable> config = new Hashtable<>(); - private final Vector hosts = new Vector<>(); - - private void _parse(BufferedReader br) throws IOException { - String host = ""; - Vector kv = new Vector<>(); - String l = null; - - while((l = br.readLine()) != null){ - l = l.trim(); - if(l.length() == 0 || l.startsWith("#")) - continue; - - String[] key_value = l.split("[= \t]", 2); - for(int i = 0; i < key_value.length; i++) - key_value[i] = key_value[i].trim(); - - if(key_value.length <= 1) - continue; - - if(key_value[0].equalsIgnoreCase("Host")){ - config.put(host, kv); - hosts.addElement(host); - host = key_value[1]; - kv = new Vector<>(); - } - else { - kv.addElement(key_value); - } - } - config.put(host, kv); - hosts.addElement(host); - } - - @Override - public Config getConfig(String host) { - return new MyConfig(host); - } - - /** - * Returns mapping of jsch config property names to OpenSSH property names. - * - * @return map - */ - static Hashtable getKeymap() { - return keymap; - } - - private static final Hashtable keymap = new Hashtable<>(); - static { - keymap.put("kex", "KexAlgorithms"); - keymap.put("server_host_key", "HostKeyAlgorithms"); - keymap.put("cipher.c2s", "Ciphers"); - keymap.put("cipher.s2c", "Ciphers"); - keymap.put("mac.c2s", "Macs"); - keymap.put("mac.s2c", "Macs"); - keymap.put("compression.s2c", "Compression"); - keymap.put("compression.c2s", "Compression"); - keymap.put("compression_level", "CompressionLevel"); - keymap.put("MaxAuthTries", "NumberOfPasswordPrompts"); - } - - class MyConfig implements Config { - - private String host; - private Vector> _configs = new Vector<>(); - - MyConfig(String host){ - this.host = host; - - _configs.addElement(config.get("")); - - byte[] _host = Util.str2byte(host); - if(hosts.size() > 1){ - for(int i = 1; i < hosts.size(); i++){ - String patterns[] = hosts.elementAt(i).split("[ \t]"); - for(int j = 0; j < patterns.length; j++){ - boolean negate = false; - String foo = patterns[j].trim(); - if(foo.startsWith("!")){ - negate = true; - foo = foo.substring(1).trim(); - } - if(Util.glob(Util.str2byte(foo), _host)){ - if(!negate){ - _configs.addElement(config.get(hosts.elementAt(i))); - } - } - else if(negate){ - _configs.addElement(config.get(hosts.elementAt(i))); - } - } - } - } - } - - private String find(String key) { - String originalKey=key; - if(keymap.get(key)!=null) { - key = keymap.get(key); - } - key = key.toUpperCase(); - String value = null; - for(int i = 0; i < _configs.size(); i++) { - Vector v = _configs.elementAt(i); - for(int j = 0; j < v.size(); j++) { - String[] kv = v.elementAt(j); - if(kv[0].toUpperCase().equals(key)) { - value = kv[1]; - break; - } - } - if(value != null) - break; - } - // TODO: The following change should be applied, - // but it is breaking changes. - // The consensus is required to enable it. - /* - if(value!=null && - (key.equals("SERVERALIVEINTERVAL") || - key.equals("CONNECTTIMEOUT"))){ - try { - int timeout = Integer.parseInt(value); - value = Integer.toString(timeout*1000); - } catch (NumberFormatException e) { - } - } - */ - - if (keysWithListAdoption.contains(key) && value != null && (value.startsWith("+") || value.startsWith("-") || value.startsWith("^"))) { - - String origConfig = JSch.getConfig(originalKey).trim(); - - if (value.startsWith("+")) { - value=origConfig + "," + value.substring(1).trim(); - } else if (value.startsWith("-")) { - List algList = Arrays.stream(Util.split(origConfig,",")).collect(Collectors.toList()); - for (String alg : Util.split(value.substring(1).trim(),",")) { - algList.remove(alg.trim()); - } - value = String.join(",", algList); - } else if (value.startsWith("^")) { - value = value.substring(1).trim() + "," + origConfig; - } - } - - return value; - } - - private String[] multiFind(String key) { - key = key.toUpperCase(); - Vector value = new Vector<>(); - for(int i = 0; i < _configs.size(); i++) { - Vector v = _configs.elementAt(i); - for(int j = 0; j < v.size(); j++) { - String[] kv = v.elementAt(j); - if(kv[0].toUpperCase().equals(key)) { - String foo = kv[1]; - if(foo != null) { - value.remove(foo); - value.addElement(foo); - } - } - } - } - String[] result = new String[value.size()]; - value.toArray(result); - return result; - } - - @Override - public String getHostname(){ return find("Hostname"); } - @Override - public String getUser(){ return find("User"); } - @Override - public int getPort(){ - String foo = find("Port"); - int port = -1; - try { - port = Integer.parseInt(foo); - } - catch(NumberFormatException e){ - // wrong format - } - return port; - } - @Override - public String getValue(String key){ - if(key.equals("compression.s2c") || - key.equals("compression.c2s")) { - String foo = find(key); - if(foo == null || foo.equals("no")) - return "none,zlib@openssh.com,zlib"; - return "zlib@openssh.com,zlib,none"; - } - return find(key); - } - @Override - public String[] getValues(String key){ return multiFind(key); } - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/PBKDF.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/PBKDF.java deleted file mode 100644 index 44619a37..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/PBKDF.java +++ /dev/null @@ -1,34 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -public interface PBKDF { - byte[] getKey(byte[] pass, byte[] salt, int iteration, int size); -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Packet.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Packet.java deleted file mode 100644 index cd477fb3..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Packet.java +++ /dev/null @@ -1,121 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class Packet{ - - private static Random random=null; - static void setRandom(Random foo){ random=foo;} - - Buffer buffer; - byte[] ba4=new byte[4]; - Packet(Buffer buffer){ - this.buffer=buffer; - } - void reset(){ - buffer.index=5; - } - void padding(int bsize, boolean includePktLen){ - int len=buffer.index; - if(!includePktLen){ - len-=4; - } - int pad=(-len)&(bsize-1); - if(pad>>24); - ba4[1]=(byte)(len>>>16); - ba4[2]=(byte)(len>>>8); - ba4[3]=(byte)(len); - System.arraycopy(ba4, 0, buffer.buffer, 0, 4); - buffer.buffer[4]=(byte)pad; - synchronized(random){ - random.fill(buffer.buffer, buffer.index, pad); - } - buffer.skip(pad); - //buffer.putPad(pad); -/* -for(int i=0; i foo=new Vector<>(); - synchronized(pool){ - for(int i=0; i0){ - ChannelDirectStreamLocal channel = new ChannelDirectStreamLocal(); - channel.setSession(session); - channel.init(); - channel.setInputStream(in); - channel.setOutputStream(out); - session.addChannel(channel); - channel.setSocketPath(socketPath); - channel.setOrgIPAddress(socket.getInetAddress().getHostAddress()); - channel.setOrgPort(socket.getPort()); - channel.connect(connectTimeout); - } else { - ChannelDirectTCPIP channel = new ChannelDirectTCPIP(); - channel.setSession(session); - channel.init(); - channel.setInputStream(in); - channel.setOutputStream(out); - session.addChannel(channel); - channel.setHost(host); - channel.setPort(rport); - channel.setOrgIPAddress(socket.getInetAddress().getHostAddress()); - channel.setOrgPort(socket.getPort()); - channel.connect(connectTimeout); - if (channel.exitstatus != -1) { - } - } - } - } - catch(Exception e){ - //System.err.println("! "+e); - } - delete(); - } - - void delete(){ - thread=null; - try{ - if(ss!=null)ss.close(); - ss=null; - } - catch(Exception e){ - } - } - - void setConnectTimeout(int connectTimeout){ - this.connectTimeout=connectTimeout; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Proxy.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Proxy.java deleted file mode 100644 index e2bd09db..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Proxy.java +++ /dev/null @@ -1,40 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.io.*; -import java.net.Socket; -public interface Proxy{ - void connect(SocketFactory socket_factory, String host, int port, int timeout) throws Exception; - InputStream getInputStream(); - OutputStream getOutputStream(); - Socket getSocket(); - void close(); -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxyHTTP.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxyHTTP.java deleted file mode 100644 index f5b5994b..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxyHTTP.java +++ /dev/null @@ -1,183 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.io.*; -import java.net.*; - -public class ProxyHTTP implements Proxy{ - private static int DEFAULTPORT=80; - private String proxy_host; - private int proxy_port; - private InputStream in; - private OutputStream out; - private Socket socket; - - private String user; - private String passwd; - - public ProxyHTTP(String proxy_host){ - int port=DEFAULTPORT; - String host=proxy_host; - if(proxy_host.indexOf(':')!=-1){ - try{ - host=proxy_host.substring(0, proxy_host.indexOf(':')); - port=Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':')+1)); - } - catch(Exception e){ - } - } - this.proxy_host=host; - this.proxy_port=port; - } - public ProxyHTTP(String proxy_host, int proxy_port){ - this.proxy_host=proxy_host; - this.proxy_port=proxy_port; - } - public void setUserPasswd(String user, String passwd){ - this.user=user; - this.passwd=passwd; - } - @Override - public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws JSchException{ - try{ - if(socket_factory==null){ - socket=Util.createSocket(proxy_host, proxy_port, timeout); - in=socket.getInputStream(); - out=socket.getOutputStream(); - } - else{ - socket=socket_factory.createSocket(proxy_host, proxy_port); - in=socket_factory.getInputStream(socket); - out=socket_factory.getOutputStream(socket); - } - if(timeout>0){ - socket.setSoTimeout(timeout); - } - socket.setTcpNoDelay(true); - - out.write(Util.str2byte("CONNECT "+host+":"+port+" HTTP/1.0\r\n")); - - if(user!=null && passwd!=null){ - byte[] code=Util.str2byte(user+":"+passwd); - code=Util.toBase64(code, 0, code.length, true); - out.write(Util.str2byte("Proxy-Authorization: Basic ")); - out.write(code); - out.write(Util.str2byte("\r\n")); - } - - out.write(Util.str2byte("\r\n")); - out.flush(); - - int foo=0; - - StringBuilder sb=new StringBuilder(); - while(foo>=0){ - foo=in.read(); if(foo!=13){sb.append((char)foo); continue;} - foo=in.read(); if(foo!=10){continue;} - break; - } - if(foo<0){ - throw new IOException(); - } - - String response=sb.toString(); - String reason="Unknow reason"; - int code=-1; - try{ - foo=response.indexOf(' '); - int bar=response.indexOf(' ', foo+1); - code=Integer.parseInt(response.substring(foo+1, bar)); - reason=response.substring(bar+1); - } - catch(Exception e){ - } - if(code!=200){ - throw new IOException("proxy error: "+reason); - } - - /* - while(foo>=0){ - foo=in.read(); if(foo!=13) continue; - foo=in.read(); if(foo!=10) continue; - foo=in.read(); if(foo!=13) continue; - foo=in.read(); if(foo!=10) continue; - break; - } - */ - - int count=0; - while(true){ - count=0; - while(foo>=0){ - foo=in.read(); if(foo!=13){count++; continue;} - foo=in.read(); if(foo!=10){continue;} - break; - } - if(foo<0){ - throw new IOException(); - } - if(count==0)break; - } - } - catch(RuntimeException e){ - throw e; - } - catch(Exception e){ - try{ if(socket!=null)socket.close(); } - catch(Exception eee){ - } - String message="ProxyHTTP: "+e.toString(); - throw new JSchException(message, e); - } - } - @Override - public InputStream getInputStream(){ return in; } - @Override - public OutputStream getOutputStream(){ return out; } - @Override - public Socket getSocket(){ return socket; } - @Override - public void close(){ - try{ - if(in!=null)in.close(); - if(out!=null)out.close(); - if(socket!=null)socket.close(); - } - catch(Exception e){ - } - in=null; - out=null; - socket=null; - } - public static int getDefaultPort(){ - return DEFAULTPORT; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxySOCKS4.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxySOCKS4.java deleted file mode 100644 index 1c0d6e36..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxySOCKS4.java +++ /dev/null @@ -1,217 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2006-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - This file depends on following documents, - - SOCKS: A protocol for TCP proxy across firewalls, Ying-Da Lee - http://www.socks.nec.com/protocol/socks4.protocol - */ - -package com.jcraft.jsch; - -import java.io.*; -import java.net.*; - -public class ProxySOCKS4 implements Proxy{ - private static int DEFAULTPORT=1080; - private String proxy_host; - private int proxy_port; - private InputStream in; - private OutputStream out; - private Socket socket; - private String user; - private String passwd; - - public ProxySOCKS4(String proxy_host){ - int port=DEFAULTPORT; - String host=proxy_host; - if(proxy_host.indexOf(':')!=-1){ - try{ - host=proxy_host.substring(0, proxy_host.indexOf(':')); - port=Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':')+1)); - } - catch(Exception e){ - } - } - this.proxy_host=host; - this.proxy_port=port; - } - public ProxySOCKS4(String proxy_host, int proxy_port){ - this.proxy_host=proxy_host; - this.proxy_port=proxy_port; - } - public void setUserPasswd(String user, String passwd){ - this.user=user; - this.passwd=passwd; - } - @Override - public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws JSchException{ - try{ - if(socket_factory==null){ - socket=Util.createSocket(proxy_host, proxy_port, timeout); - //socket=new Socket(proxy_host, proxy_port); - in=socket.getInputStream(); - out=socket.getOutputStream(); - } - else{ - socket=socket_factory.createSocket(proxy_host, proxy_port); - in=socket_factory.getInputStream(socket); - out=socket_factory.getOutputStream(socket); - } - if(timeout>0){ - socket.setSoTimeout(timeout); - } - socket.setTcpNoDelay(true); - - byte[] buf=new byte[1024]; - int index=0; - -/* - 1) CONNECT - - The client connects to the SOCKS server and sends a CONNECT request when - it wants to establish a connection to an application server. The client - includes in the request packet the IP address and the port number of the - destination host, and userid, in the following format. - - +----+----+----+----+----+----+----+----+----+----+....+----+ - | VN | CD | DSTPORT | DSTIP | USERID |NULL| - +----+----+----+----+----+----+----+----+----+----+....+----+ - # of bytes: 1 1 2 4 variable 1 - - VN is the SOCKS protocol version number and should be 4. CD is the - SOCKS command code and should be 1 for CONNECT request. NULL is a byte - of all zero bits. -*/ - - index=0; - buf[index++]=4; - buf[index++]=1; - - buf[index++]=(byte)(port>>>8); - buf[index++]=(byte)(port&0xff); - - try{ - InetAddress addr=InetAddress.getByName(host); - byte[] byteAddress = addr.getAddress(); - for (int i = 0; i < byteAddress.length; i++) { - buf[index++]=byteAddress[i]; - } - } - catch(UnknownHostException uhe){ - throw new JSchException("ProxySOCKS4: "+uhe.toString(), uhe); - } - - if(user!=null){ - System.arraycopy(Util.str2byte(user), 0, buf, index, user.length()); - index+=user.length(); - } - buf[index++]=0; - out.write(buf, 0, index); - -/* - The SOCKS server checks to see whether such a request should be granted - based on any combination of source IP address, destination IP address, - destination port number, the userid, and information it may obtain by - consulting IDENT, cf. RFC 1413. If the request is granted, the SOCKS - server makes a connection to the specified port of the destination host. - A reply packet is sent to the client when this connection is established, - or when the request is rejected or the operation fails. - - +----+----+----+----+----+----+----+----+ - | VN | CD | DSTPORT | DSTIP | - +----+----+----+----+----+----+----+----+ - # of bytes: 1 1 2 4 - - VN is the version of the reply code and should be 0. CD is the result - code with one of the following values: - - 90: request granted - 91: request rejected or failed - 92: request rejected becasue SOCKS server cannot connect to - identd on the client - 93: request rejected because the client program and identd - report different user-ids - - The remaining fields are ignored. -*/ - - int len=8; - int s=0; - while(s0){ - socket.setSoTimeout(timeout); - } - socket.setTcpNoDelay(true); - - byte[] buf=new byte[1024]; - int index=0; - -/* - +----+----------+----------+ - |VER | NMETHODS | METHODS | - +----+----------+----------+ - | 1 | 1 | 1 to 255 | - +----+----------+----------+ - - The VER field is set to X'05' for this version of the protocol. The - NMETHODS field contains the number of method identifier octets that - appear in the METHODS field. - - The values currently defined for METHOD are: - - o X'00' NO AUTHENTICATION REQUIRED - o X'01' GSSAPI - o X'02' USERNAME/PASSWORD - o X'03' to X'7F' IANA ASSIGNED - o X'80' to X'FE' RESERVED FOR PRIVATE METHODS - o X'FF' NO ACCEPTABLE METHODS -*/ - - buf[index++]=5; - - buf[index++]=2; - buf[index++]=0; // NO AUTHENTICATION REQUIRED - buf[index++]=2; // USERNAME/PASSWORD - - out.write(buf, 0, index); - -/* - The server selects from one of the methods given in METHODS, and - sends a METHOD selection message: - - +----+--------+ - |VER | METHOD | - +----+--------+ - | 1 | 1 | - +----+--------+ -*/ - //in.read(buf, 0, 2); - fill(in, buf, 2); - - boolean check=false; - switch((buf[1])&0xff){ - case 0: // NO AUTHENTICATION REQUIRED - check=true; - break; - case 2: // USERNAME/PASSWORD - if(user==null || passwd==null)break; - -/* - Once the SOCKS V5 server has started, and the client has selected the - Username/Password Authentication protocol, the Username/Password - subnegotiation begins. This begins with the client producing a - Username/Password request: - - +----+------+----------+------+----------+ - |VER | ULEN | UNAME | PLEN | PASSWD | - +----+------+----------+------+----------+ - | 1 | 1 | 1 to 255 | 1 | 1 to 255 | - +----+------+----------+------+----------+ - - The VER field contains the current version of the subnegotiation, - which is X'01'. The ULEN field contains the length of the UNAME field - that follows. The UNAME field contains the username as known to the - source operating system. The PLEN field contains the length of the - PASSWD field that follows. The PASSWD field contains the password - association with the given UNAME. -*/ - index=0; - buf[index++]=1; - buf[index++]=(byte)(user.length()); - System.arraycopy(Util.str2byte(user), 0, buf, index, user.length()); - index+=user.length(); - buf[index++]=(byte)(passwd.length()); - System.arraycopy(Util.str2byte(passwd), 0, buf, index, passwd.length()); - index+=passwd.length(); - - out.write(buf, 0, index); - -/* - The server verifies the supplied UNAME and PASSWD, and sends the - following response: - - +----+--------+ - |VER | STATUS | - +----+--------+ - | 1 | 1 | - +----+--------+ - - A STATUS field of X'00' indicates success. If the server returns a - `failure' (STATUS value other than X'00') status, it MUST close the - connection. -*/ - //in.read(buf, 0, 2); - fill(in, buf, 2); - if(buf[1]==0) - check=true; - break; - default: - } - - if(!check){ - try{ socket.close(); } - catch(Exception eee){ - } - throw new JSchException("fail in SOCKS5 proxy"); - } - -/* - The SOCKS request is formed as follows: - - +----+-----+-------+------+----------+----------+ - |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT | - +----+-----+-------+------+----------+----------+ - | 1 | 1 | X'00' | 1 | Variable | 2 | - +----+-----+-------+------+----------+----------+ - - Where: - - o VER protocol version: X'05' - o CMD - o CONNECT X'01' - o BIND X'02' - o UDP ASSOCIATE X'03' - o RSV RESERVED - o ATYP address type of following address - o IP V4 address: X'01' - o DOMAINNAME: X'03' - o IP V6 address: X'04' - o DST.ADDR desired destination address - o DST.PORT desired destination port in network octet - order -*/ - - index=0; - buf[index++]=5; - buf[index++]=1; // CONNECT - buf[index++]=0; - - byte[] hostb=Util.str2byte(host); - int len=hostb.length; - buf[index++]=3; // DOMAINNAME - buf[index++]=(byte)(len); - System.arraycopy(hostb, 0, buf, index, len); - index+=len; - buf[index++]=(byte)(port>>>8); - buf[index++]=(byte)(port&0xff); - - out.write(buf, 0, index); - -/* - The SOCKS request information is sent by the client as soon as it has - established a connection to the SOCKS server, and completed the - authentication negotiations. The server evaluates the request, and - returns a reply formed as follows: - - +----+-----+-------+------+----------+----------+ - |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | - +----+-----+-------+------+----------+----------+ - | 1 | 1 | X'00' | 1 | Variable | 2 | - +----+-----+-------+------+----------+----------+ - - Where: - - o VER protocol version: X'05' - o REP Reply field: - o X'00' succeeded - o X'01' general SOCKS server failure - o X'02' connection not allowed by ruleset - o X'03' Network unreachable - o X'04' Host unreachable - o X'05' Connection refused - o X'06' TTL expired - o X'07' Command not supported - o X'08' Address type not supported - o X'09' to X'FF' unassigned - o RSV RESERVED - o ATYP address type of following address - o IP V4 address: X'01' - o DOMAINNAME: X'03' - o IP V6 address: X'04' - o BND.ADDR server bound address - o BND.PORT server bound port in network octet order -*/ - - //in.read(buf, 0, 4); - fill(in, buf, 4); - - if(buf[1]!=0){ - try{ socket.close(); } - catch(Exception eee){ - } - throw new JSchException("ProxySOCKS5: server returns "+buf[1]); - } - - switch(buf[3]&0xff){ - case 1: - //in.read(buf, 0, 6); - fill(in, buf, 6); - break; - case 3: - //in.read(buf, 0, 1); - fill(in, buf, 1); - //in.read(buf, 0, buf[0]+2); - fill(in, buf, (buf[0]&0xff)+2); - break; - case 4: - //in.read(buf, 0, 18); - fill(in, buf, 18); - break; - default: - } - } - catch(RuntimeException e){ - throw e; - } - catch(Exception e){ - try{ if(socket!=null)socket.close(); } - catch(Exception eee){ - } - String message="ProxySOCKS5: "+e.toString(); - throw new JSchException(message, e); - } - } - @Override - public InputStream getInputStream(){ return in; } - @Override - public OutputStream getOutputStream(){ return out; } - @Override - public Socket getSocket(){ return socket; } - @Override - public void close(){ - try{ - if(in!=null)in.close(); - if(out!=null)out.close(); - if(socket!=null)socket.close(); - } - catch(Exception e){ - } - in=null; - out=null; - socket=null; - } - public static int getDefaultPort(){ - return DEFAULTPORT; - } - private void fill(InputStream in, byte[] buf, int len) throws JSchException, IOException{ - int s=0; - while(s0){ - setReply(true); - } - } - boolean waitForReply(){ return reply; } - void setReply(boolean reply){ this.reply=reply; } - void write(Packet packet) throws Exception{ - if(reply){ - channel.reply=-1; - } - session.write(packet); - if(reply){ - long start=System.currentTimeMillis(); - long timeout=channel.connectTimeout; - while(channel.isConnected() && channel.reply==-1){ - try{Thread.sleep(10);} - catch(Exception ee){ - } - if(timeout>0L && - (System.currentTimeMillis()-start)>timeout){ - channel.reply=0; - throw new JSchException("channel request: timeout"); - } - } - - if(channel.reply==0){ - throw new JSchException("failed to send channel request"); - } - } - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestAgentForwarding.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestAgentForwarding.java deleted file mode 100644 index d8834c53..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestAgentForwarding.java +++ /dev/null @@ -1,54 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2006-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class RequestAgentForwarding extends Request{ - @Override - public void request(Session session, Channel channel) throws Exception{ - super.request(session, channel); - - setReply(false); - - Buffer buf=new Buffer(); - Packet packet=new Packet(buf); - - // byte SSH_MSG_CHANNEL_REQUEST(98) - // uint32 recipient channel - // string request type // "auth-agent-req@openssh.com" - // boolean want reply // 0 - packet.reset(); - buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); - buf.putInt(channel.getRecipient()); - buf.putString(Util.str2byte("auth-agent-req@openssh.com")); - buf.putByte((byte)(waitForReply() ? 1 : 0)); - write(packet); - session.agent_forwarding=true; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestEnv.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestEnv.java deleted file mode 100644 index ad4afca4..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestEnv.java +++ /dev/null @@ -1,56 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class RequestEnv extends Request{ - byte[] name=new byte[0]; - byte[] value=new byte[0]; - void setEnv(byte[] name, byte[] value){ - this.name=name; - this.value=value; - } - @Override - public void request(Session session, Channel channel) throws Exception{ - super.request(session, channel); - setReply(false); - - Buffer buf=new Buffer(); - Packet packet=new Packet(buf); - - packet.reset(); - buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); - buf.putInt(channel.getRecipient()); - buf.putString(Util.str2byte("env")); - buf.putByte((byte) 0); - buf.putString(name); - buf.putString(value); - write(packet); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestExec.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestExec.java deleted file mode 100644 index bd7eefe4..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestExec.java +++ /dev/null @@ -1,59 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class RequestExec extends Request{ - private byte[] command=new byte[0]; - RequestExec(byte[] command){ - this.command=command; - } - @Override - public void request(Session session, Channel channel) throws Exception{ - super.request(session, channel); - - Buffer buf=new Buffer(); - Packet packet=new Packet(buf); - - // send - // byte SSH_MSG_CHANNEL_REQUEST(98) - // uint32 recipient channel - // string request type // "exec" - // boolean want reply // 0 - // string command - packet.reset(); - buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); - buf.putInt(channel.getRecipient()); - buf.putString(Util.str2byte("exec")); - buf.putByte((byte)(waitForReply() ? 1 : 0)); - buf.checkFreeSize(4+command.length); - buf.putString(command); - write(packet); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestPtyReq.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestPtyReq.java deleted file mode 100644 index b4975438..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestPtyReq.java +++ /dev/null @@ -1,79 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class RequestPtyReq extends Request{ - private String ttype="vt100"; - private int tcol=80; - private int trow=24; - private int twp=640; - private int thp=480; - - private byte[] terminal_mode=Util.empty; - - void setCode(String cookie){ - } - - void setTType(String ttype){ - this.ttype=ttype; - } - - void setTerminalMode(byte[] terminal_mode){ - this.terminal_mode=terminal_mode; - } - - void setTSize(int tcol, int trow, int twp, int thp){ - this.tcol=tcol; - this.trow=trow; - this.twp=twp; - this.thp=thp; - } - - @Override - public void request(Session session, Channel channel) throws Exception{ - super.request(session, channel); - - Buffer buf=new Buffer(); - Packet packet=new Packet(buf); - - packet.reset(); - buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); - buf.putInt(channel.getRecipient()); - buf.putString(Util.str2byte("pty-req")); - buf.putByte((byte)(waitForReply() ? 1 : 0)); - buf.putString(Util.str2byte(ttype)); - buf.putInt(tcol); - buf.putInt(trow); - buf.putInt(twp); - buf.putInt(thp); - buf.putString(terminal_mode); - write(packet); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSftp.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSftp.java deleted file mode 100644 index 481cef48..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSftp.java +++ /dev/null @@ -1,50 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class RequestSftp extends Request{ - RequestSftp(){ - setReply(true); - } - @Override - public void request(Session session, Channel channel) throws Exception{ - super.request(session, channel); - - Buffer buf=new Buffer(); - Packet packet=new Packet(buf); - packet.reset(); - buf.putByte((byte)Session.SSH_MSG_CHANNEL_REQUEST); - buf.putInt(channel.getRecipient()); - buf.putString(Util.str2byte("subsystem")); - buf.putByte((byte)(waitForReply() ? 1 : 0)); - buf.putString(Util.str2byte("sftp")); - write(packet); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestShell.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestShell.java deleted file mode 100644 index 699636d0..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestShell.java +++ /dev/null @@ -1,52 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class RequestShell extends Request{ - @Override - public void request(Session session, Channel channel) throws Exception{ - super.request(session, channel); - - Buffer buf=new Buffer(); - Packet packet=new Packet(buf); - - // send - // byte SSH_MSG_CHANNEL_REQUEST(98) - // uint32 recipient channel - // string request type // "shell" - // boolean want reply // 0 - packet.reset(); - buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); - buf.putInt(channel.getRecipient()); - buf.putString(Util.str2byte("shell")); - buf.putByte((byte)(waitForReply() ? 1 : 0)); - write(packet); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSignal.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSignal.java deleted file mode 100644 index 7814c442..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSignal.java +++ /dev/null @@ -1,50 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class RequestSignal extends Request{ - private String signal="KILL"; - public void setSignal(String foo){ signal=foo; } - @Override - public void request(Session session, Channel channel) throws Exception{ - super.request(session, channel); - - Buffer buf=new Buffer(); - Packet packet=new Packet(buf); - - packet.reset(); - buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); - buf.putInt(channel.getRecipient()); - buf.putString(Util.str2byte("signal")); - buf.putByte((byte)(waitForReply() ? 1 : 0)); - buf.putString(Util.str2byte(signal)); - write(packet); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSubsystem.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSubsystem.java deleted file mode 100644 index c766a52d..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSubsystem.java +++ /dev/null @@ -1,54 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class RequestSubsystem extends Request{ - private String subsystem=null; - public void request(Session session, Channel channel, String subsystem, boolean want_reply) throws Exception{ - setReply(want_reply); - this.subsystem=subsystem; - this.request(session, channel); - } - @Override - public void request(Session session, Channel channel) throws Exception{ - super.request(session, channel); - - Buffer buf=new Buffer(); - Packet packet=new Packet(buf); - - packet.reset(); - buf.putByte((byte)Session.SSH_MSG_CHANNEL_REQUEST); - buf.putInt(channel.getRecipient()); - buf.putString(Util.str2byte("subsystem")); - buf.putByte((byte)(waitForReply() ? 1 : 0)); - buf.putString(Util.str2byte(subsystem)); - write(packet); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestWindowChange.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestWindowChange.java deleted file mode 100644 index 8e4a2084..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestWindowChange.java +++ /dev/null @@ -1,69 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class RequestWindowChange extends Request{ - int width_columns=80; - int height_rows=24; - int width_pixels=640; - int height_pixels=480; - void setSize(int col, int row, int wp, int hp){ - this.width_columns=col; - this.height_rows=row; - this.width_pixels=wp; - this.height_pixels=hp; - } - @Override - public void request(Session session, Channel channel) throws Exception{ - super.request(session, channel); - - Buffer buf=new Buffer(); - Packet packet=new Packet(buf); - - //byte SSH_MSG_CHANNEL_REQUEST - //uint32 recipient_channel - //string "window-change" - //boolean FALSE - //uint32 terminal width, columns - //uint32 terminal height, rows - //uint32 terminal width, pixels - //uint32 terminal height, pixels - packet.reset(); - buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); - buf.putInt(channel.getRecipient()); - buf.putString(Util.str2byte("window-change")); - buf.putByte((byte)(waitForReply() ? 1 : 0)); - buf.putInt(width_columns); - buf.putInt(height_rows); - buf.putInt(width_pixels); - buf.putInt(height_pixels); - write(packet); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestX11.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestX11.java deleted file mode 100644 index 74e2ea8a..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestX11.java +++ /dev/null @@ -1,64 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class RequestX11 extends Request{ - public void setCookie(String cookie){ - ChannelX11.cookie=Util.str2byte(cookie); - } - @Override - public void request(Session session, Channel channel) throws Exception{ - super.request(session, channel); - - Buffer buf=new Buffer(); - Packet packet=new Packet(buf); - - // byte SSH_MSG_CHANNEL_REQUEST(98) - // uint32 recipient channel - // string request type // "x11-req" - // boolean want reply // 0 - // boolean single connection - // string x11 authentication protocol // "MIT-MAGIC-COOKIE-1". - // string x11 authentication cookie - // uint32 x11 screen number - packet.reset(); - buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); - buf.putInt(channel.getRecipient()); - buf.putString(Util.str2byte("x11-req")); - buf.putByte((byte)(waitForReply() ? 1 : 0)); - buf.putByte((byte)0); - buf.putString(Util.str2byte("MIT-MAGIC-COOKIE-1")); - buf.putString(ChannelX11.getFakedCookie(session)); - buf.putInt(0); - write(packet); - - session.x11_forwarding=true; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ServerSocketFactory.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ServerSocketFactory.java deleted file mode 100644 index 7c0467ad..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ServerSocketFactory.java +++ /dev/null @@ -1,37 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.net.*; -import java.io.*; - -public interface ServerSocketFactory{ - public ServerSocket createServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException; -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Session.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Session.java deleted file mode 100644 index ceac6a62..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Session.java +++ /dev/null @@ -1,3290 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; -import java.io.OutputStream; -import java.net.Socket; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; -import java.util.Vector; - -import javax.crypto.AEADBadTagException; - -public class Session{ - - // http://ietf.org/internet-drafts/draft-ietf-secsh-assignednumbers-01.txt - static final int SSH_MSG_DISCONNECT= 1; - static final int SSH_MSG_IGNORE= 2; - static final int SSH_MSG_UNIMPLEMENTED= 3; - static final int SSH_MSG_DEBUG= 4; - static final int SSH_MSG_SERVICE_REQUEST= 5; - static final int SSH_MSG_SERVICE_ACCEPT= 6; - static final int SSH_MSG_EXT_INFO= 7; - static final int SSH_MSG_KEXINIT= 20; - static final int SSH_MSG_NEWKEYS= 21; - static final int SSH_MSG_KEXDH_INIT= 30; - static final int SSH_MSG_KEXDH_REPLY= 31; - static final int SSH_MSG_KEX_DH_GEX_GROUP= 31; - static final int SSH_MSG_KEX_DH_GEX_INIT= 32; - static final int SSH_MSG_KEX_DH_GEX_REPLY= 33; - static final int SSH_MSG_KEX_DH_GEX_REQUEST= 34; - static final int SSH_MSG_GLOBAL_REQUEST= 80; - static final int SSH_MSG_REQUEST_SUCCESS= 81; - static final int SSH_MSG_REQUEST_FAILURE= 82; - static final int SSH_MSG_CHANNEL_OPEN= 90; - static final int SSH_MSG_CHANNEL_OPEN_CONFIRMATION= 91; - static final int SSH_MSG_CHANNEL_OPEN_FAILURE= 92; - static final int SSH_MSG_CHANNEL_WINDOW_ADJUST= 93; - static final int SSH_MSG_CHANNEL_DATA= 94; - static final int SSH_MSG_CHANNEL_EXTENDED_DATA= 95; - static final int SSH_MSG_CHANNEL_EOF= 96; - static final int SSH_MSG_CHANNEL_CLOSE= 97; - static final int SSH_MSG_CHANNEL_REQUEST= 98; - static final int SSH_MSG_CHANNEL_SUCCESS= 99; - static final int SSH_MSG_CHANNEL_FAILURE= 100; - - private static final int PACKET_MAX_SIZE = 256 * 1024; - - private byte[] V_S; // server version - private byte[] V_C=Util.str2byte("SSH-2.0-JSCH_"+JSch.VERSION); // client version - - private byte[] I_C; // the payload of the client's SSH_MSG_KEXINIT - private byte[] I_S; // the payload of the server's SSH_MSG_KEXINIT - private byte[] K_S; // the host key - - private byte[] session_id; - - private byte[] IVc2s; - private byte[] IVs2c; - private byte[] Ec2s; - private byte[] Es2c; - private byte[] MACc2s; - private byte[] MACs2c; - - private int seqi=0; - private int seqo=0; - - String[] guess=null; - private Cipher s2ccipher; - private Cipher c2scipher; - private MAC s2cmac; - private MAC c2smac; - //private byte[] mac_buf; - private byte[] s2cmac_result1; - private byte[] s2cmac_result2; - - private Compression deflater; - private Compression inflater; - - private IO io; - private Socket socket; - private int timeout=0; - - private volatile boolean isConnected=false; - - private volatile boolean isAuthed=false; - - private Thread connectThread=null; - private Object lock=new Object(); - - boolean x11_forwarding=false; - boolean agent_forwarding=false; - - InputStream in=null; - OutputStream out=null; - - static Random random; - - Buffer buf; - Packet packet; - - SocketFactory socket_factory=null; - - static final int buffer_margin = 32 + // maximum padding length - 64 + // maximum mac length - 32; // margin for deflater; deflater may inflate data - - private Hashtable config=null; - - private Proxy proxy=null; - private UserInfo userinfo; - - private String hostKeyAlias=null; - private int serverAliveInterval=0; - private int serverAliveCountMax=1; - - private IdentityRepository identityRepository = null; - private HostKeyRepository hostkeyRepository = null; - private volatile String[] serverSigAlgs = null; - private volatile boolean sshBugSigType74 = false; - - protected boolean daemon_thread=false; - - private long kex_start_time=0L; - - int max_auth_tries = 6; - int auth_failures = 0; - - String host="127.0.0.1"; - String org_host="127.0.0.1"; - int port=22; - - String username=null; - byte[] password=null; - - JSch jsch; - Logger logger; - - Session(JSch jsch, String username, String host, int port) throws JSchException{ - super(); - this.jsch=jsch; - buf=new Buffer(); - packet=new Packet(buf); - this.username = username; - this.org_host = this.host = host; - this.port = port; - - applyConfig(); - - if(this.username==null) { - this.username=Util.getSystemProperty("user.name"); - } - - if(this.username==null) { - throw new JSchException("username is not given."); - } - } - - public void connect() throws JSchException{ - connect(timeout); - } - - public void connect(int connectTimeout) throws JSchException{ - if(isConnected){ - throw new JSchException("session is already connected"); - } - - io=new IO(); - if(random==null){ - try{ - Class c=Class.forName(getConfig("random")).asSubclass(Random.class); - random=c.getDeclaredConstructor().newInstance(); - } - catch(Exception e){ - throw new JSchException(e.toString(), e); - } - } - Packet.setRandom(random); - - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, - "Connecting to "+host+" port "+port); - } - - try { - int i, j; - - if(proxy==null){ - InputStream in; - OutputStream out; - if(socket_factory==null){ - socket=Util.createSocket(host, port, connectTimeout); - in=socket.getInputStream(); - out=socket.getOutputStream(); - } - else{ - socket=socket_factory.createSocket(host, port); - in=socket_factory.getInputStream(socket); - out=socket_factory.getOutputStream(socket); - } - //if(timeout>0){ socket.setSoTimeout(timeout); } - socket.setTcpNoDelay(true); - io.setInputStream(in); - io.setOutputStream(out); - } - else{ - synchronized(proxy){ - proxy.connect(socket_factory, host, port, connectTimeout); - io.setInputStream(proxy.getInputStream()); - io.setOutputStream(proxy.getOutputStream()); - socket=proxy.getSocket(); - } - } - - if(connectTimeout>0 && socket!=null){ - socket.setSoTimeout(connectTimeout); - } - - isConnected=true; - - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, - "Connection established"); - } - - jsch.addSession(this); - - { - // Some Cisco devices will miss to read '\n' if it is sent separately. - byte[] foo=new byte[V_C.length+2]; - System.arraycopy(V_C, 0, foo, 0, V_C.length); - foo[foo.length-2]=(byte)'\r'; - foo[foo.length-1]=(byte)'\n'; - io.put(foo, 0, foo.length); - } - - while(true){ - i=0; - j=0; - while(i0 && buf.buffer[i-1]==13){ // 0x0d - i--; - } - } - - if(i<=3 || - ((i!=buf.buffer.length) && - (buf.buffer[0]!='S'||buf.buffer[1]!='S'|| - buf.buffer[2]!='H'||buf.buffer[3]!='-'))){ - // It must not start with 'SSH-' - //System.err.println(new String(buf.buffer, 0, i); - continue; - } - - if(i==buf.buffer.length || - i<7 || // SSH-1.99 or SSH-2.0 - (buf.buffer[4]=='1' && buf.buffer[6]!='9') // SSH-1.5 - ){ - throw new JSchException("invalid server's version string"); - } - break; - } - - V_S=new byte[i]; System.arraycopy(buf.buffer, 0, V_S, 0, i); - //System.err.println("V_S: ("+i+") ["+new String(V_S)+"]"); - String _v_s=Util.byte2str(V_S); - sshBugSigType74=_v_s.startsWith("SSH-2.0-OpenSSH_7.4"); - - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, - "Remote version string: "+_v_s); - getLogger().log(Logger.INFO, - "Local version string: "+Util.byte2str(V_C)); - } - - send_kexinit(); - - buf=read(buf); - if(buf.getCommand()!=SSH_MSG_KEXINIT){ - in_kex=false; - throw new JSchException("invalid protocol: "+buf.getCommand()); - } - - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, - "SSH_MSG_KEXINIT received"); - } - - KeyExchange kex=receive_kexinit(buf); - - while(true){ - buf=read(buf); - if(kex.getState()==buf.getCommand()){ - kex_start_time=System.currentTimeMillis(); - boolean result=kex.next(buf); - if(!result){ - //System.err.println("verify: "+result); - in_kex=false; - throw new JSchException("verify: "+result); - } - } - else{ - in_kex=false; - throw new JSchException("invalid protocol(kex): "+buf.getCommand()); - } - if(kex.getState()==KeyExchange.STATE_END){ - break; - } - } - - try{ - long tmp=System.currentTimeMillis(); - in_prompt = true; - checkHost(host, port, kex); - in_prompt = false; - kex_start_time+=(System.currentTimeMillis()-tmp); - } - catch(JSchException ee){ - in_kex=false; - in_prompt = false; - throw ee; - } - - send_newkeys(); - - // receive SSH_MSG_NEWKEYS(21) - buf=read(buf); - //System.err.println("read: 21 ? "+buf.getCommand()); - if(buf.getCommand()==SSH_MSG_NEWKEYS){ - - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, - "SSH_MSG_NEWKEYS received"); - } - - receive_newkeys(buf, kex); - } - else{ - in_kex=false; - throw new JSchException("invalid protocol(newkyes): "+buf.getCommand()); - } - - try{ - String s = getConfig("MaxAuthTries"); - if(s!=null){ - max_auth_tries = Integer.parseInt(s); - } - } - catch(NumberFormatException e){ - throw new JSchException("MaxAuthTries: "+getConfig("MaxAuthTries"), e); - } - - boolean auth=false; - boolean auth_cancel=false; - - UserAuth ua=null; - try{ - Class c=Class.forName(getConfig("userauth.none")).asSubclass(UserAuth.class); - ua=c.getDeclaredConstructor().newInstance(); - } - catch(Exception e){ - throw new JSchException(e.toString(), e); - } - - auth=ua.start(this); - - String cmethods=getConfig("PreferredAuthentications"); - - String[] cmethoda=Util.split(cmethods, ","); - - String smethods=null; - if(!auth){ - smethods=((UserAuthNone)ua).getMethods(); - if(smethods!=null){ - smethods=smethods.toLowerCase(); - } - else{ - // methods: publickey,password,keyboard-interactive - //smethods="publickey,password,keyboard-interactive"; - smethods=cmethods; - } - } - - String[] smethoda=Util.split(smethods, ","); - - int methodi=0; - - loop: - while(true){ - - while(!auth && - cmethoda!=null && methodi c=null; - if(getConfig("userauth."+method)!=null){ - c=Class.forName(getConfig("userauth."+method)).asSubclass(UserAuth.class); - ua=c.getDeclaredConstructor().newInstance(); - } - } - catch(Exception e){ - if(getLogger().isEnabled(Logger.WARN)){ - getLogger().log(Logger.WARN, - "failed to load "+method+" method"); - } - } - - if(ua!=null){ - auth_cancel=false; - try{ - auth=ua.start(this); - if(auth && - getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, - "Authentication succeeded ("+method+")."); - } - } - catch(JSchAuthCancelException ee){ - auth_cancel=true; - } - catch(JSchPartialAuthException ee){ - String tmp = smethods; - smethods=ee.getMethods(); - smethoda=Util.split(smethods, ","); - if(!tmp.equals(smethods)){ - methodi=0; - } - //System.err.println("PartialAuth: "+methods); - auth_cancel=false; - continue loop; - } - catch(RuntimeException ee){ - throw ee; - } - catch(JSchException ee){ - throw ee; - } - catch(Exception ee){ - //System.err.println("ee: "+ee); // SSH_MSG_DISCONNECT: 2 Too many authentication failures - if(getLogger().isEnabled(Logger.WARN)){ - getLogger().log(Logger.WARN, - "an exception during authentication\n"+ee.toString()); - } - break loop; - } - } - } - break; - } - - if(!auth){ - if(auth_failures >= max_auth_tries){ - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, - "Login trials exceeds "+max_auth_tries); - } - } - throw new JSchException((auth_cancel ? "Auth cancel" - : "Auth fail") - + " for methods '" + smethods + "'"); - } - - if(socket!=null && (connectTimeout>0 || timeout>0)){ - socket.setSoTimeout(timeout); - } - - isAuthed=true; - - synchronized(lock){ - if(isConnected){ - connectThread=new Thread(this::run); - connectThread.setName("Connect thread "+host+" session"); - if(daemon_thread){ - connectThread.setDaemon(daemon_thread); - } - connectThread.start(); - - requestPortForwarding(); - } - else{ - // The session has been already down and - // we don't have to start new thread. - } - } - } - catch(Exception e) { - in_kex=false; - try{ - if(isConnected){ - String message = e.toString(); - packet.reset(); - buf.checkFreeSize(1+4*3+message.length()+2+buffer_margin); - buf.putByte((byte)SSH_MSG_DISCONNECT); - buf.putInt(3); - buf.putString(Util.str2byte(message)); - buf.putString(Util.str2byte("en")); - write(packet); - } - } - catch(Exception ee){} - try{ disconnect(); } catch(Exception ee){ } - isConnected=false; - //e.printStackTrace(); - if(e instanceof RuntimeException) throw (RuntimeException)e; - if(e instanceof JSchException) throw (JSchException)e; - throw new JSchException("Session.connect: "+e, e); - } - finally{ - Util.bzero(this.password); - this.password=null; - } - } - - private KeyExchange receive_kexinit(Buffer buf) throws Exception { - int j=buf.getInt(); - if(j!=buf.getLength()){ // packet was compressed and - buf.getByte(); // j is the size of deflated packet. - I_S=new byte[buf.index-5]; - } - else{ - I_S=new byte[j-1-buf.getByte()]; - } - System.arraycopy(buf.buffer, buf.s, I_S, 0, I_S.length); - - if(!in_kex){ // We are in rekeying activated by the remote! - send_kexinit(); - } - - guess=KeyExchange.guess(this, I_S, I_C); - - if(guess[KeyExchange.PROPOSAL_KEX_ALGS].equals("ext-info-c") || - guess[KeyExchange.PROPOSAL_KEX_ALGS].equals("ext-info-s")){ - throw new JSchException("Invalid Kex negotiated: " + guess[KeyExchange.PROPOSAL_KEX_ALGS]); - } - - if(!isAuthed && - (guess[KeyExchange.PROPOSAL_ENC_ALGS_CTOS].equals("none") || - (guess[KeyExchange.PROPOSAL_ENC_ALGS_STOC].equals("none")))){ - throw new JSchException("NONE Cipher should not be chosen before authentification is successed."); - } - - KeyExchange kex=null; - try{ - Class c=Class.forName(getConfig(guess[KeyExchange.PROPOSAL_KEX_ALGS])).asSubclass(KeyExchange.class); - kex=c.getDeclaredConstructor().newInstance(); - } - catch(Exception | NoClassDefFoundError e){ - throw new JSchException(e.toString(), e); - } - - kex.doInit(this, V_S, V_C, I_S, I_C); - return kex; - } - - private volatile boolean in_kex=false; - private volatile boolean in_prompt=false; - private volatile String[] not_available_shks=null; - public String[] getUnavailableSignatures() { - return not_available_shks; - } - public void rekey() throws Exception { - send_kexinit(); - } - private void send_kexinit() throws Exception { - if(in_kex) - return; - - String cipherc2s=getConfig("cipher.c2s"); - String ciphers2c=getConfig("cipher.s2c"); - String[] not_available_ciphers=checkCiphers(getConfig("CheckCiphers")); - if(not_available_ciphers!=null && not_available_ciphers.length>0){ - if(getLogger().isEnabled(Logger.DEBUG)){ - getLogger().log(Logger.DEBUG, - "cipher.c2s proposal before removing unavailable algos is: " + cipherc2s); - getLogger().log(Logger.DEBUG, - "cipher.s2c proposal before removing unavailable algos is: " + ciphers2c); - } - - cipherc2s=Util.diffString(cipherc2s, not_available_ciphers); - ciphers2c=Util.diffString(ciphers2c, not_available_ciphers); - if(cipherc2s==null || ciphers2c==null){ - throw new JSchException("There are not any available ciphers."); - } - - if(getLogger().isEnabled(Logger.DEBUG)){ - getLogger().log(Logger.DEBUG, - "cipher.c2s proposal after removing unavailable algos is: " + cipherc2s); - getLogger().log(Logger.DEBUG, - "cipher.s2c proposal after removing unavailable algos is: " + ciphers2c); - } - } - - String macc2s=getConfig("mac.c2s"); - String macs2c=getConfig("mac.s2c"); - String[] not_available_macs=checkMacs(getConfig("CheckMacs")); - if(not_available_macs!=null && not_available_macs.length>0){ - if(getLogger().isEnabled(Logger.DEBUG)){ - getLogger().log(Logger.DEBUG, - "mac.c2s proposal before removing unavailable algos is: " + macc2s); - getLogger().log(Logger.DEBUG, - "mac.s2c proposal before removing unavailable algos is: " + macs2c); - } - - macc2s=Util.diffString(macc2s, not_available_macs); - macs2c=Util.diffString(macs2c, not_available_macs); - if(macc2s==null || macs2c==null){ - throw new JSchException("There are not any available macs."); - } - - if(getLogger().isEnabled(Logger.DEBUG)){ - getLogger().log(Logger.DEBUG, - "mac.c2s proposal after removing unavailable algos is: " + macc2s); - getLogger().log(Logger.DEBUG, - "mac.s2c proposal after removing unavailable algos is: " + macs2c); - } - } - - String kex=getConfig("kex"); - String[] not_available_kexes=checkKexes(getConfig("CheckKexes")); - if(not_available_kexes!=null && not_available_kexes.length>0){ - if(getLogger().isEnabled(Logger.DEBUG)){ - getLogger().log(Logger.DEBUG, - "kex proposal before removing unavailable algos is: " + kex); - } - - kex=Util.diffString(kex, not_available_kexes); - if(kex==null){ - throw new JSchException("There are not any available kexes."); - } - - if(getLogger().isEnabled(Logger.DEBUG)){ - getLogger().log(Logger.DEBUG, - "kex proposal after removing unavailable algos is: " + kex); - } - } - - String enable_server_sig_algs=getConfig("enable_server_sig_algs"); - if(enable_server_sig_algs.equals("yes") && !isAuthed){ - kex+=",ext-info-c"; - } - - String server_host_key = getConfig("server_host_key"); - String[] not_available_shks = - checkSignatures(getConfig("CheckSignatures")); - // Cache for UserAuthPublicKey - this.not_available_shks = not_available_shks; - if(not_available_shks!=null && not_available_shks.length>0){ - if(getLogger().isEnabled(Logger.DEBUG)){ - getLogger().log(Logger.DEBUG, - "server_host_key proposal before removing unavailable algos is: " + server_host_key); - } - - server_host_key=Util.diffString(server_host_key, not_available_shks); - if(server_host_key==null){ - throw new JSchException("There are not any available sig algorithm."); - } - - if(getLogger().isEnabled(Logger.DEBUG)){ - getLogger().log(Logger.DEBUG, - "server_host_key proposal after removing unavailable algos is: " + server_host_key); - } - } - - String prefer_hkr=getConfig("prefer_known_host_key_types"); - if(prefer_hkr.equals("yes")){ - if(getLogger().isEnabled(Logger.DEBUG)){ - getLogger().log(Logger.DEBUG, - "server_host_key proposal before known_host reordering is: " + server_host_key); - } - - HostKeyRepository hkr=getHostKeyRepository(); - String chost=host; - if(hostKeyAlias!=null){ - chost=hostKeyAlias; - } - if(hostKeyAlias==null && port!=22){ - chost=("["+chost+"]:"+port); - } - HostKey[] hks=hkr.getHostKey(chost, null); - if(hks!=null && hks.length>0){ - List pref_shks=new ArrayList<>(); - List shks=new ArrayList<>(Arrays.asList(Util.split(server_host_key, ","))); - Iterator it=shks.iterator(); - while(it.hasNext()){ - String algo=it.next(); - String type=algo; - if(type.equals("rsa-sha2-256") || type.equals("rsa-sha2-512") || - type.equals("ssh-rsa-sha224@ssh.com") || type.equals("ssh-rsa-sha256@ssh.com") || - type.equals("ssh-rsa-sha384@ssh.com") || type.equals("ssh-rsa-sha512@ssh.com")){ - type="ssh-rsa"; - } - for(HostKey hk : hks){ - if(hk.getType().equals(type)){ - pref_shks.add(algo); - it.remove(); - break; - } - } - } - if(pref_shks.size()>0){ - pref_shks.addAll(shks); - server_host_key=String.join(",", pref_shks); - } - } - - if(getLogger().isEnabled(Logger.DEBUG)){ - getLogger().log(Logger.DEBUG, - "server_host_key proposal after known_host reordering is: " + server_host_key); - } - } - - in_kex=true; - kex_start_time=System.currentTimeMillis(); - - // byte SSH_MSG_KEXINIT(20) - // byte[16] cookie (random bytes) - // string kex_algorithms - // string server_host_key_algorithms - // string encryption_algorithms_client_to_server - // string encryption_algorithms_server_to_client - // string mac_algorithms_client_to_server - // string mac_algorithms_server_to_client - // string compression_algorithms_client_to_server - // string compression_algorithms_server_to_client - // string languages_client_to_server - // string languages_server_to_client - Buffer buf = new Buffer(); // send_kexinit may be invoked - Packet packet = new Packet(buf); // by user thread. - packet.reset(); - buf.putByte((byte) SSH_MSG_KEXINIT); - synchronized(random){ - random.fill(buf.buffer, buf.index, 16); buf.skip(16); - } - buf.putString(Util.str2byte(kex)); - buf.putString(Util.str2byte(server_host_key)); - buf.putString(Util.str2byte(cipherc2s)); - buf.putString(Util.str2byte(ciphers2c)); - buf.putString(Util.str2byte(getConfig("mac.c2s"))); - buf.putString(Util.str2byte(getConfig("mac.s2c"))); - buf.putString(Util.str2byte(getConfig("compression.c2s"))); - buf.putString(Util.str2byte(getConfig("compression.s2c"))); - buf.putString(Util.str2byte(getConfig("lang.c2s"))); - buf.putString(Util.str2byte(getConfig("lang.s2c"))); - buf.putByte((byte)0); - buf.putInt(0); - - buf.setOffSet(5); - I_C=new byte[buf.getLength()]; - buf.getByte(I_C); - - write(packet); - - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, - "SSH_MSG_KEXINIT sent"); - } - } - - private void send_newkeys() throws Exception { - // send SSH_MSG_NEWKEYS(21) - packet.reset(); - buf.putByte((byte)SSH_MSG_NEWKEYS); - write(packet); - - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, - "SSH_MSG_NEWKEYS sent"); - } - } - - private void checkHost(String chost, int port, KeyExchange kex) throws JSchException { - String shkc=getConfig("StrictHostKeyChecking"); - - if(hostKeyAlias!=null){ - chost=hostKeyAlias; - } - - //System.err.println("shkc: "+shkc); - - byte[] K_S=kex.getHostKey(); - String key_type=kex.getKeyType(); - String key_fprint=kex.getFingerPrint(); - - if(hostKeyAlias==null && port!=22){ - chost=("["+chost+"]:"+port); - } - - HostKeyRepository hkr=getHostKeyRepository(); - - String hkh=getConfig("HashKnownHosts"); - if(hkh.equals("yes") && (hkr instanceof KnownHosts)){ - hostkey=((KnownHosts)hkr).createHashedHostKey(chost, K_S); - } - else{ - hostkey=new HostKey(chost, K_S); - } - - int i=0; - synchronized(hkr){ - i=hkr.check(chost, K_S); - } - - boolean insert=false; - if((shkc.equals("ask") || shkc.equals("yes")) && - i==HostKeyRepository.CHANGED){ - String file=null; - synchronized(hkr){ - file=hkr.getKnownHostsRepositoryID(); - } - if(file==null){file="known_hosts";} - - boolean b=false; - - if(userinfo!=null){ - String message= -"WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!\n"+ -"IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n"+ -"Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n"+ -"It is also possible that the "+key_type+" host key has just been changed.\n"+ -"The fingerprint for the "+key_type+" key sent by the remote host "+chost+" is\n"+ -key_fprint+".\n"+ -"Please contact your system administrator.\n"+ -"Add correct host key in "+file+" to get rid of this message."; - - if(shkc.equals("ask")){ - b=userinfo.promptYesNo(message+ - "\nDo you want to delete the old key and insert the new key?"); - } - else{ // shkc.equals("yes") - userinfo.showMessage(message); - } - } - - if(!b){ - throw new JSchException("HostKey has been changed: "+chost); - } - - synchronized(hkr){ - hkr.remove(chost, - kex.getKeyAlgorithName(), - null); - insert=true; - } - } - - if((shkc.equals("ask") || shkc.equals("yes")) && - (i!=HostKeyRepository.OK) && !insert){ - if(shkc.equals("yes")){ - throw new JSchException("reject HostKey: "+host); - } - //System.err.println("finger-print: "+key_fprint); - if(userinfo!=null){ - boolean foo=userinfo.promptYesNo( -"The authenticity of host '"+host+"' can't be established.\n"+ -key_type+" key fingerprint is "+key_fprint+".\n"+ -"Are you sure you want to continue connecting?" - ); - if(!foo){ - throw new JSchException("reject HostKey: "+host); - } - insert=true; - } - else{ - if(i==HostKeyRepository.NOT_INCLUDED) - throw new JSchException("UnknownHostKey: "+host+". "+key_type+" key fingerprint is "+key_fprint); - else - throw new JSchException("HostKey has been changed: "+host); - } - } - - if(shkc.equals("no") && - HostKeyRepository.NOT_INCLUDED==i){ - insert=true; - } - - if(i==HostKeyRepository.OK){ - HostKey[] keys = - hkr.getHostKey(chost, kex.getKeyAlgorithName()); - String _key= Util.byte2str(Util.toBase64(K_S, 0, K_S.length, true)); - for(int j=0; j< keys.length; j++){ - if(keys[j].getKey().equals(_key) && - keys[j].getMarker().equals("@revoked")){ - if(userinfo!=null){ - userinfo.showMessage( -"The "+ key_type +" host key for "+ host +" is marked as revoked.\n"+ -"This could mean that a stolen key is being used to "+ -"impersonate this host."); - } - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, - "Host '"+host+"' has provided revoked key."); - } - throw new JSchException("revoked HostKey: "+host); - } - } - } - - if(i==HostKeyRepository.OK && - getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, - "Host '"+host+"' is known and matches the "+key_type+" host key"); - } - - if(insert && - getLogger().isEnabled(Logger.WARN)){ - getLogger().log(Logger.WARN, - "Permanently added '"+host+"' ("+key_type+") to the list of known hosts."); - } - - if(insert){ - synchronized(hkr){ - hkr.add(hostkey, userinfo); - } - } - } - -//public void start(){ (new Thread(this)).start(); } - - public Channel openChannel(String type) throws JSchException{ - if(!isConnected){ - throw new JSchException("session is down"); - } - try{ - Channel channel=Channel.getChannel(type, this); - addChannel(channel); - channel.init(); - if(channel instanceof ChannelSession){ - applyConfigChannel((ChannelSession)channel); - } - return channel; - } - catch(Exception e){ - //e.printStackTrace(); - } - return null; - } - - // encode will bin invoked in write with synchronization. - void encode(Packet packet) throws Exception{ -//System.err.println("encode: "+packet.buffer.getCommand()); -//System.err.println(" "+packet.buffer.index); -//if(packet.buffer.getCommand()==96){ -//Thread.dumpStack(); -//} - if(deflater!=null){ - compress_len[0]=packet.buffer.index; - packet.buffer.buffer=deflater.compress(packet.buffer.buffer, - 5, compress_len); - packet.buffer.index=compress_len[0]; - } - int bsize=8; - if(c2scipher!=null){ - //bsize=c2scipher.getIVSize(); - bsize=c2scipher_size; - } - boolean isChaCha20=(c2scipher!=null && c2scipher.isChaCha20()); - boolean isAEAD=(c2scipher!=null && c2scipher.isAEAD()); - boolean isEtM=(!isChaCha20 && !isAEAD && c2scipher!=null && c2smac!=null && c2smac.isEtM()); - packet.padding(bsize, !(isChaCha20 || isAEAD || isEtM)); - - byte[] buf=packet.buffer.buffer; - if(isChaCha20){ - // init cipher with seq number - c2scipher.update(seqo); - //encrypt packet length field - c2scipher.update(buf, 0, 4, buf, 0); - //encrypt rest of packet & add tag - c2scipher.doFinal(buf, 0, packet.buffer.index, buf, 0); - packet.buffer.skip(c2scipher.getTagSize()); - } - else if(isAEAD){ - c2scipher.updateAAD(buf, 0, 4); - c2scipher.doFinal(buf, 4, packet.buffer.index-4, buf, 4); - packet.buffer.skip(c2scipher.getTagSize()); - } - else if(isEtM){ - c2scipher.update(buf, 4, packet.buffer.index-4, buf, 4); - c2smac.update(seqo); - c2smac.update(packet.buffer.buffer, 0, packet.buffer.index); - c2smac.doFinal(packet.buffer.buffer, packet.buffer.index); - packet.buffer.skip(c2smac.getBlockSize()); - } - else{ - if(c2smac!=null){ - c2smac.update(seqo); - c2smac.update(packet.buffer.buffer, 0, packet.buffer.index); - c2smac.doFinal(packet.buffer.buffer, packet.buffer.index); - } - if(c2scipher!=null){ - c2scipher.update(buf, 0, packet.buffer.index, buf, 0); - } - if(c2smac!=null){ - packet.buffer.skip(c2smac.getBlockSize()); - } - } - } - - int[] uncompress_len=new int[1]; - int[] compress_len=new int[1]; - - private int s2ccipher_size=8; - private int c2scipher_size=8; - Buffer read(Buffer buf) throws Exception{ - int j=0; - boolean isChaCha20=(s2ccipher!=null && s2ccipher.isChaCha20()); - boolean isAEAD=(s2ccipher!=null && s2ccipher.isAEAD()); - boolean isEtM=(!isChaCha20 && !isAEAD && s2ccipher!=null && s2cmac!=null && s2cmac.isEtM()); - while(true){ - buf.reset(); - if(isChaCha20){ - //read encrypted packet length field - io.getByte(buf.buffer, buf.index, 4); - buf.index+=4; - // init cipher with seq number - s2ccipher.update(seqi); - //decrypt packet length field - byte[] tmp=new byte[4]; - s2ccipher.update(buf.buffer, 0, 4, tmp, 0); - j=((tmp[0]<<24)&0xff000000)| - ((tmp[1]<<16)&0x00ff0000)| - ((tmp[2]<< 8)&0x0000ff00)| - ((tmp[3] )&0x000000ff); - // RFC 4253 6.1. Maximum Packet Length - if(j<5 || j>PACKET_MAX_SIZE){ - start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE); - } - j+=s2ccipher.getTagSize(); - if((buf.index+j)>buf.buffer.length){ - byte[] foo=new byte[buf.index+j]; - System.arraycopy(buf.buffer, 0, foo, 0, buf.index); - buf.buffer=foo; - } - - if((j%s2ccipher_size)!=0){ - String message="Bad packet length "+j; - if(getLogger().isEnabled(Logger.FATAL)){ - getLogger().log(Logger.FATAL, message); - } - start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE-s2ccipher_size); - } - - io.getByte(buf.buffer, buf.index, j); - // subtract tag size now that whole packet has been fetched - j -= s2ccipher.getTagSize(); buf.index+=(j); - try { - s2ccipher.doFinal(buf.buffer, 0, j+4, buf.buffer, 0); - } - catch(AEADBadTagException e){ - throw new JSchException("Packet corrupt", e); - } - // overwrite encrypted packet length field with decrypted version - System.arraycopy(tmp, 0, buf.buffer, 0, 4); - } - else if(isAEAD || isEtM){ - io.getByte(buf.buffer, buf.index, 4); - buf.index+=4; - j=((buf.buffer[0]<<24)&0xff000000)| - ((buf.buffer[1]<<16)&0x00ff0000)| - ((buf.buffer[2]<< 8)&0x0000ff00)| - ((buf.buffer[3] )&0x000000ff); - // RFC 4253 6.1. Maximum Packet Length - if(j<5 || j>PACKET_MAX_SIZE){ - start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE); - } - if(isAEAD){ - j+=s2ccipher.getTagSize(); - } - if((buf.index+j)>buf.buffer.length){ - byte[] foo=new byte[buf.index+j]; - System.arraycopy(buf.buffer, 0, foo, 0, buf.index); - buf.buffer=foo; - } - - if((j%s2ccipher_size)!=0){ - String message="Bad packet length "+j; - if(getLogger().isEnabled(Logger.FATAL)){ - getLogger().log(Logger.FATAL, message); - } - start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE-s2ccipher_size); - } - - io.getByte(buf.buffer, buf.index, j); buf.index+=(j); - - if(isAEAD){ - try { - s2ccipher.updateAAD(buf.buffer, 0, 4); - s2ccipher.doFinal(buf.buffer, 4, j, buf.buffer, 4); - } - catch(AEADBadTagException e){ - throw new JSchException("Packet corrupt", e); - } - // don't include AEAD tag size in buf so that decompression works below - buf.index -= s2ccipher.getTagSize(); - } - else{ - s2cmac.update(seqi); - s2cmac.update(buf.buffer, 0, buf.index); - s2cmac.doFinal(s2cmac_result1, 0); - - io.getByte(s2cmac_result2, 0, s2cmac_result2.length); - if(!Util.arraysequals(s2cmac_result1, s2cmac_result2)){ - throw new JSchException("Packet corrupt"); - } - s2ccipher.update(buf.buffer, 4, j, buf.buffer, 4); - } - } - else{ - io.getByte(buf.buffer, buf.index, s2ccipher_size); - buf.index+=s2ccipher_size; - if(s2ccipher!=null){ - s2ccipher.update(buf.buffer, 0, s2ccipher_size, buf.buffer, 0); - } - j=((buf.buffer[0]<<24)&0xff000000)| - ((buf.buffer[1]<<16)&0x00ff0000)| - ((buf.buffer[2]<< 8)&0x0000ff00)| - ((buf.buffer[3] )&0x000000ff); - // RFC 4253 6.1. Maximum Packet Length - if(j<5 || j>PACKET_MAX_SIZE){ - start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE); - } - int need = j+4-s2ccipher_size; - //if(need<0){ - // throw new IOException("invalid data"); - //} - if((buf.index+need)>buf.buffer.length){ - byte[] foo=new byte[buf.index+need]; - System.arraycopy(buf.buffer, 0, foo, 0, buf.index); - buf.buffer=foo; - } - - if((need%s2ccipher_size)!=0){ - String message="Bad packet length "+need; - if(getLogger().isEnabled(Logger.FATAL)){ - getLogger().log(Logger.FATAL, message); - } - start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE-s2ccipher_size); - } - - if(need>0){ - io.getByte(buf.buffer, buf.index, need); buf.index+=(need); - if(s2ccipher!=null){ - s2ccipher.update(buf.buffer, s2ccipher_size, need, buf.buffer, s2ccipher_size); - } - } - - if(s2cmac!=null){ - s2cmac.update(seqi); - s2cmac.update(buf.buffer, 0, buf.index); - s2cmac.doFinal(s2cmac_result1, 0); - - io.getByte(s2cmac_result2, 0, s2cmac_result2.length); - if(!Util.arraysequals(s2cmac_result1, s2cmac_result2)){ - if(need+s2ccipher_size > PACKET_MAX_SIZE){ - throw new IOException("MAC Error"); - } - start_discard(buf, s2ccipher, s2cmac, buf.index, PACKET_MAX_SIZE-need-s2ccipher_size); - continue; - } - } - } - - seqi++; - - if(inflater!=null){ - //inflater.uncompress(buf); - int pad=buf.buffer[4]; - uncompress_len[0]=buf.index-5-pad; - byte[] foo=inflater.uncompress(buf.buffer, 5, uncompress_len); - if(foo!=null){ - buf.buffer=foo; - buf.index=5+uncompress_len[0]; - } - else{ - System.err.println("fail in inflater"); - break; - } - } - - int type=buf.getCommand()&0xff; - //System.err.println("read: "+type); - if(type==SSH_MSG_DISCONNECT){ - buf.rewind(); - buf.getInt();buf.getShort(); - int reason_code=buf.getInt(); - byte[] description=buf.getString(); - byte[] language_tag=buf.getString(); - throw new JSchException("SSH_MSG_DISCONNECT: "+ - reason_code+ - " "+Util.byte2str(description)+ - " "+Util.byte2str(language_tag)); - //break; - } - else if(type==SSH_MSG_IGNORE){ - } - else if(type==SSH_MSG_UNIMPLEMENTED){ - buf.rewind(); - buf.getInt();buf.getShort(); - int reason_id=buf.getInt(); - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, - "Received SSH_MSG_UNIMPLEMENTED for "+reason_id); - } - } - else if(type==SSH_MSG_DEBUG){ - buf.rewind(); - buf.getInt();buf.getShort(); -/* - byte always_display=(byte)buf.getByte(); - byte[] message=buf.getString(); - byte[] language_tag=buf.getString(); - System.err.println("SSH_MSG_DEBUG:"+ - " "+Util.byte2str(message)+ - " "+Util.byte2str(language_tag)); -*/ - } - else if(type==SSH_MSG_CHANNEL_WINDOW_ADJUST){ - buf.rewind(); - buf.getInt();buf.getShort(); - Channel c=Channel.getChannel(buf.getInt(), this); - if(c==null){ - } - else{ - c.addRemoteWindowSize(buf.getUInt()); - } - } - else if(type==SSH_MSG_EXT_INFO){ - buf.rewind(); - buf.getInt();buf.getShort(); - boolean ignore=false; - String enable_server_sig_algs=getConfig("enable_server_sig_algs"); - if(!enable_server_sig_algs.equals("yes")){ - ignore=true; - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, "Ignoring SSH_MSG_EXT_INFO while enable_server_sig_algs != yes"); - } - } - else if(isAuthed){ - ignore=true; - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, "Ignoring SSH_MSG_EXT_INFO received after SSH_MSG_USERAUTH_SUCCESS"); - } - } - else if(in_kex){ - ignore=true; - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, "Ignoring SSH_MSG_EXT_INFO received before SSH_MSG_NEWKEYS"); - } - } - else{ - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, "SSH_MSG_EXT_INFO received"); - } - } - long num_extensions=buf.getUInt(); - for(long i=0; i"); - } - if(sshBugSigType74){ - if(!foo.isEmpty()){ - foo+=",rsa-sha2-256,rsa-sha2-512"; - } - else{ - foo="rsa-sha2-256,rsa-sha2-512"; - } - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, "OpenSSH 7.4 detected: adding rsa-sha2-256 & rsa-sha2-512 to server-sig-algs"); - } - } - serverSigAlgs=Util.split(foo, ","); - } - } - } - else if(type==UserAuth.SSH_MSG_USERAUTH_SUCCESS){ - isAuthed=true; - if(inflater==null && deflater==null){ - String method; - method=guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS]; - initDeflater(method); - method=guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC]; - initInflater(method); - } - break; - } - else{ - break; - } - } - buf.rewind(); - return buf; - } - - private void start_discard(Buffer buf, Cipher cipher, MAC mac, - int mac_already, int discard) throws JSchException{ - if(!cipher.isCBC() || (mac != null && mac.isEtM())){ - throw new JSchException("Packet corrupt"); - } - - if(mac != null){ - mac.update(seqi); - mac.update(buf.buffer, 0, mac_already); - } - - IOException ioe=null; - try{ - while(discard>0){ - buf.reset(); - int len = discard>buf.buffer.length ? buf.buffer.length : discard; - io.getByte(buf.buffer, 0, len); - if(mac!=null){ - mac.update(buf.buffer, 0, len); - } - discard -= len; - } - } - catch(IOException e){ - ioe = e; - if(getLogger().isEnabled(Logger.ERROR)){ - getLogger().log(Logger.ERROR, - "start_discard finished early due to " + e.getMessage()); - } - } - - if(mac!=null){ - mac.doFinal(buf.buffer, 0); - } - - JSchException e = new JSchException("Packet corrupt"); - if(ioe!=null){ - e.addSuppressed(ioe); - } - throw e; - } - - byte[] getSessionId(){ - return session_id; - } - - private void receive_newkeys(Buffer buf, KeyExchange kex) throws Exception { - updateKeys(kex); - in_kex=false; - } - private void updateKeys(KeyExchange kex) throws Exception{ - byte[] K=kex.getK(); - byte[] H=kex.getH(); - HASH hash=kex.getHash(); - - if(session_id==null){ - session_id=new byte[H.length]; - System.arraycopy(H, 0, session_id, 0, H.length); - } - - /* - Initial IV client to server: HASH (K || H || "A" || session_id) - Initial IV server to client: HASH (K || H || "B" || session_id) - Encryption key client to server: HASH (K || H || "C" || session_id) - Encryption key server to client: HASH (K || H || "D" || session_id) - Integrity key client to server: HASH (K || H || "E" || session_id) - Integrity key server to client: HASH (K || H || "F" || session_id) - */ - - buf.reset(); - buf.putMPInt(K); - buf.putByte(H); - buf.putByte((byte)0x41); - buf.putByte(session_id); - hash.update(buf.buffer, 0, buf.index); - IVc2s=hash.digest(); - - int j=buf.index-session_id.length-1; - - buf.buffer[j]++; - hash.update(buf.buffer, 0, buf.index); - IVs2c=hash.digest(); - - buf.buffer[j]++; - hash.update(buf.buffer, 0, buf.index); - Ec2s=hash.digest(); - - buf.buffer[j]++; - hash.update(buf.buffer, 0, buf.index); - Es2c=hash.digest(); - - buf.buffer[j]++; - hash.update(buf.buffer, 0, buf.index); - MACc2s=hash.digest(); - - buf.buffer[j]++; - hash.update(buf.buffer, 0, buf.index); - MACs2c=hash.digest(); - - try{ - Class cc; - Class cm; - String method; - - method=guess[KeyExchange.PROPOSAL_ENC_ALGS_STOC]; - cc=Class.forName(getConfig(method)).asSubclass(Cipher.class); - s2ccipher=cc.getDeclaredConstructor().newInstance(); - while(s2ccipher.getBlockSize()>Es2c.length){ - buf.reset(); - buf.putMPInt(K); - buf.putByte(H); - buf.putByte(Es2c); - hash.update(buf.buffer, 0, buf.index); - byte[] foo=hash.digest(); - byte[] bar=new byte[Es2c.length+foo.length]; - System.arraycopy(Es2c, 0, bar, 0, Es2c.length); - System.arraycopy(foo, 0, bar, Es2c.length, foo.length); - Es2c=bar; - } - s2ccipher.init(Cipher.DECRYPT_MODE, Es2c, IVs2c); - s2ccipher_size=s2ccipher.getIVSize(); - - if(!s2ccipher.isAEAD()){ - method=guess[KeyExchange.PROPOSAL_MAC_ALGS_STOC]; - cm=Class.forName(getConfig(method)).asSubclass(MAC.class); - s2cmac=cm.getDeclaredConstructor().newInstance(); - MACs2c = expandKey(buf, K, H, MACs2c, hash, s2cmac.getBlockSize()); - s2cmac.init(MACs2c); - //mac_buf=new byte[s2cmac.getBlockSize()]; - s2cmac_result1=new byte[s2cmac.getBlockSize()]; - s2cmac_result2=new byte[s2cmac.getBlockSize()]; - } - - method=guess[KeyExchange.PROPOSAL_ENC_ALGS_CTOS]; - cc=Class.forName(getConfig(method)).asSubclass(Cipher.class); - c2scipher=cc.getDeclaredConstructor().newInstance(); - while(c2scipher.getBlockSize()>Ec2s.length){ - buf.reset(); - buf.putMPInt(K); - buf.putByte(H); - buf.putByte(Ec2s); - hash.update(buf.buffer, 0, buf.index); - byte[] foo=hash.digest(); - byte[] bar=new byte[Ec2s.length+foo.length]; - System.arraycopy(Ec2s, 0, bar, 0, Ec2s.length); - System.arraycopy(foo, 0, bar, Ec2s.length, foo.length); - Ec2s=bar; - } - c2scipher.init(Cipher.ENCRYPT_MODE, Ec2s, IVc2s); - c2scipher_size=c2scipher.getIVSize(); - - if(!c2scipher.isAEAD()){ - method=guess[KeyExchange.PROPOSAL_MAC_ALGS_CTOS]; - cm=Class.forName(getConfig(method)).asSubclass(MAC.class); - c2smac=cm.getDeclaredConstructor().newInstance(); - MACc2s = expandKey(buf, K, H, MACc2s, hash, c2smac.getBlockSize()); - c2smac.init(MACc2s); - } - - method=guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS]; - initDeflater(method); - - method=guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC]; - initInflater(method); - } - catch(Exception | NoClassDefFoundError e){ - if(e instanceof JSchException) - throw e; - throw new JSchException(e.toString(), e); - //System.err.println("updatekeys: "+e); - } - } - - - /* - * RFC 4253 7.2. Output from Key Exchange - * If the key length needed is longer than the output of the HASH, the - * key is extended by computing HASH of the concatenation of K and H and - * the entire key so far, and appending the resulting bytes (as many as - * HASH generates) to the key. This process is repeated until enough - * key material is available; the key is taken from the beginning of - * this value. In other words: - * K1 = HASH(K || H || X || session_id) (X is e.g., "A") - * K2 = HASH(K || H || K1) - * K3 = HASH(K || H || K1 || K2) - * ... - * key = K1 || K2 || K3 || ... - */ - private byte[] expandKey(Buffer buf, byte[] K, byte[] H, byte[] key, - HASH hash, int required_length) throws Exception { - byte[] result = key; - int size = hash.getBlockSize(); - while(result.length < required_length){ - buf.reset(); - buf.putMPInt(K); - buf.putByte(H); - buf.putByte(result); - hash.update(buf.buffer, 0, buf.index); - byte[] tmp = new byte[result.length+size]; - System.arraycopy(result, 0, tmp, 0, result.length); - System.arraycopy(hash.digest(), 0, tmp, result.length, size); - Util.bzero(result); - result = tmp; - } - return result; - } - - /*synchronized*/ void write(Packet packet, Channel c, int length) throws Exception{ - long t = getTimeout(); - while(true){ - if(in_kex){ - if(t>0L && (System.currentTimeMillis()-kex_start_time)>t){ - throw new JSchException("timeout in waiting for rekeying process."); - } - try{Thread.sleep(10);} - catch(InterruptedException e){}; - continue; - } - synchronized(c){ - - if(c.rwsize=length){ - c.rwsize-=length; - break; - } - - } - if(c.close || !c.isConnected()){ - throw new IOException("channel is broken"); - } - - boolean sendit=false; - int s=0; - byte command=0; - int recipient=-1; - synchronized(c){ - if(c.rwsize>0){ - long len=c.rwsize; - if(len>length){ - len=length; - } - if(len!=length){ - s=packet.shift((int)len, - (c2scipher!=null ? c2scipher_size : 8), - (c2smac!=null ? c2smac.getBlockSize() : 0)); - } - command=packet.buffer.getCommand(); - recipient=c.getRecipient(); - length-=len; - c.rwsize-=len; - sendit=true; - } - } - if(sendit){ - _write(packet); - if(length==0){ - return; - } - packet.unshift(command, recipient, s, length); - } - - synchronized(c){ - if(in_kex){ - continue; - } - if(c.rwsize>=length){ - c.rwsize-=length; - break; - } - - //try{ - //System.out.println("1wait: "+c.rwsize); - // c.notifyme++; - // c.wait(100); - //} - //catch(InterruptedException e){ - //} - //finally{ - // c.notifyme--; - //} - } - } - _write(packet); - } - - void write(Packet packet) throws Exception{ - // System.err.println("in_kex="+in_kex+" "+(packet.buffer.getCommand())); - long t = getTimeout(); - while(in_kex){ - if(t>0L && - (System.currentTimeMillis()-kex_start_time)>t && - !in_prompt - ){ - throw new JSchException("timeout in waiting for rekeying process."); - } - byte command=packet.buffer.getCommand(); - //System.err.println("command: "+command); - if(command==SSH_MSG_KEXINIT || - command==SSH_MSG_NEWKEYS || - command==SSH_MSG_KEXDH_INIT || - command==SSH_MSG_KEXDH_REPLY || - command==SSH_MSG_KEX_DH_GEX_GROUP || - command==SSH_MSG_KEX_DH_GEX_INIT || - command==SSH_MSG_KEX_DH_GEX_REPLY || - command==SSH_MSG_KEX_DH_GEX_REQUEST || - command==SSH_MSG_DISCONNECT){ - break; - } - try{Thread.sleep(10);} - catch(InterruptedException e){}; - } - _write(packet); - } - - private void _write(Packet packet) throws Exception{ - synchronized(lock){ - encode(packet); - if(io!=null){ - io.put(packet); - seqo++; - } - } - } - - Runnable thread; - void run(){ - thread=this::run; - - byte[] foo; - Buffer buf=new Buffer(); - Packet packet=new Packet(buf); - int i=0; - Channel channel; - int[] start=new int[1]; - int[] length=new int[1]; - KeyExchange kex=null; - - int stimeout=0; - try{ - while(isConnected && - thread!=null){ - try{ - buf=read(buf); - stimeout=0; - } - catch(InterruptedIOException/*SocketTimeoutException*/ ee){ - if(!in_kex && stimeoutlport is 0, the tcp port will be allocated. - * @param lport local port for local port forwarding - * @param host host address for local port forwarding - * @param rport remote port number for local port forwarding - * @return an allocated local TCP port number - * @see #setPortForwardingL(String bind_address, int lport, String host, int rport, ServerSocketFactory ssf, int connectTimeout) - */ - public int setPortForwardingL(int lport, String host, int rport) throws JSchException{ - return setPortForwardingL("127.0.0.1", lport, host, rport); - } - - /** - * Registers the local port forwarding. If bind_address is an empty string - * or '*', the port should be available from all interfaces. - * If bind_address is "localhost" or - * null, the listening port will be bound for local use only. - * If lport is 0, the tcp port will be allocated. - * @param bind_address bind address for local port forwarding - * @param lport local port for local port forwarding - * @param host host address for local port forwarding - * @param rport remote port number for local port forwarding - * @return an allocated local TCP port number - * @see #setPortForwardingL(String bind_address, int lport, String host, int rport, ServerSocketFactory ssf, int connectTimeout) - */ - public int setPortForwardingL(String bind_address, int lport, String host, int rport) throws JSchException{ - return setPortForwardingL(bind_address, lport, host, rport, null); - } - - /** - * Registers the local port forwarding. - * If bind_address is an empty string or "*", - * the port should be available from all interfaces. - * If bind_address is "localhost" or - * null, the listening port will be bound for local use only. - * If lport is 0, the tcp port will be allocated. - * @param bind_address bind address for local port forwarding - * @param lport local port for local port forwarding - * @param host host address for local port forwarding - * @param rport remote port number for local port forwarding - * @param ssf socket factory - * @return an allocated local TCP port number - * @see #setPortForwardingL(String bind_address, int lport, String host, int rport, ServerSocketFactory ssf, int connectTimeout) - */ - public int setPortForwardingL(String bind_address, int lport, String host, int rport, ServerSocketFactory ssf) throws JSchException{ - return setPortForwardingL(bind_address, lport, host, rport, ssf, 0); - } - - /** - * Registers the local port forwarding. - * If bind_address is an empty string - * or "*", the port should be available from all interfaces. - * If bind_address is "localhost" or - * null, the listening port will be bound for local use only. - * If lport is 0, the tcp port will be allocated. - * @param bind_address bind address for local port forwarding - * @param lport local port for local port forwarding - * @param host host address for local port forwarding - * @param rport remote port number for local port forwarding - * @param ssf socket factory - * @param connectTimeout timeout for establishing port connection - * @return an allocated local TCP port number - */ - public int setPortForwardingL(String bind_address, int lport, String host, int rport, ServerSocketFactory ssf, int connectTimeout) throws JSchException{ - PortWatcher pw=PortWatcher.addPort(this, bind_address, lport, host, rport, ssf); - pw.setConnectTimeout(connectTimeout); - Thread tmp=new Thread(pw::run); - tmp.setName("PortWatcher Thread for "+host); - if(daemon_thread){ - tmp.setDaemon(daemon_thread); - } - tmp.start(); - return pw.lport; - } - - public int setSocketForwardingL(String bindAddress, int lport, String socketPath, ServerSocketFactory ssf, int connectTimeout) throws JSchException { - PortWatcher pw=PortWatcher.addSocket(this, bindAddress, lport, socketPath, ssf); - pw.setConnectTimeout(connectTimeout); - Thread tmp=new Thread(pw::run); - tmp.setName("PortWatcher Thread for "+host); - if(daemon_thread){ - tmp.setDaemon(daemon_thread); - } - tmp.start(); - return pw.lport; - } - - /** - * Cancels the local port forwarding assigned - * at local TCP port lport on loopback interface. - * - * @param lport local TCP port - */ - public void delPortForwardingL(int lport) throws JSchException{ - delPortForwardingL("127.0.0.1", lport); - } - - /** - * Cancels the local port forwarding assigned - * at local TCP port lport on bind_address interface. - * - * @param bind_address bind_address of network interfaces - * @param lport local TCP port - */ - public void delPortForwardingL(String bind_address, int lport) throws JSchException{ - PortWatcher.delPort(this, bind_address, lport); - } - - /** - * Lists the registered local port forwarding. - * - * @return a list of "lport:host:hostport" - */ - public String[] getPortForwardingL() throws JSchException{ - return PortWatcher.getPortForwarding(this); - } - - /** - * Registers the remote port forwarding for the loopback interface - * of the remote. - * - * @param rport remote port - * @param host host address - * @param lport local port - * @see #setPortForwardingR(String bind_address, int rport, String host, int lport, SocketFactory sf) - */ - public void setPortForwardingR(int rport, String host, int lport) throws JSchException{ - setPortForwardingR(null, rport, host, lport, (SocketFactory)null); - } - - /** - * Registers the remote port forwarding. - * If bind_address is an empty string or "*", - * the port should be available from all interfaces. - * If bind_address is "localhost" or is not given, - * the listening port will be bound for local use only. - * Note that if GatewayPorts is "no" on the - * remote, "localhost" is always used as a bind_address. - * - * @param bind_address bind address - * @param rport remote port - * @param host host address - * @param lport local port - * @see #setPortForwardingR(String bind_address, int rport, String host, int lport, SocketFactory sf) - */ - public void setPortForwardingR(String bind_address, int rport, String host, int lport) throws JSchException{ - setPortForwardingR(bind_address, rport, host, lport, (SocketFactory)null); - } - - /** - * Registers the remote port forwarding for the loopback interface - * of the remote. - * - * @param rport remote port - * @param host host address - * @param lport local port - * @param sf socket factory - * @see #setPortForwardingR(String bind_address, int rport, String host, int lport, SocketFactory sf) - */ - public void setPortForwardingR(int rport, String host, int lport, SocketFactory sf) throws JSchException{ - setPortForwardingR(null, rport, host, lport, sf); - } - - // TODO: This method should return the integer value as the assigned port. - /** - * Registers the remote port forwarding. - * If bind_address is an empty string or "*", - * the port should be available from all interfaces. - * If bind_address is "localhost" or is not given, - * the listening port will be bound for local use only. - * Note that if GatewayPorts is "no" on the - * remote, "localhost" is always used as a bind_address. - * If rport is 0, the TCP port will be allocated on the remote. - * - * @param bind_address bind address - * @param rport remote port - * @param host host address - * @param lport local port - * @param sf socket factory - */ - public void setPortForwardingR(String bind_address, int rport, String host, int lport, SocketFactory sf) throws JSchException{ - int allocated=_setPortForwardingR(bind_address, rport); - ChannelForwardedTCPIP.addPort(this, bind_address, - rport, allocated, host, lport, sf); - } - - /** - * Registers the remote port forwarding for the loopback interface - * of the remote. - * The TCP connection to rport on the remote will be - * forwarded to an instance of the class daemon. - * The class specified by daemon must implement - * ForwardedTCPIPDaemon. - * - * @param rport remote port - * @param daemon class name, which implements "ForwardedTCPIPDaemon" - * @see #setPortForwardingR(String bind_address, int rport, String daemon, Object[] arg) - */ - public void setPortForwardingR(int rport, String daemon) throws JSchException{ - setPortForwardingR(null, rport, daemon, null); - } - - /** - * Registers the remote port forwarding for the loopback interface - * of the remote. - * The TCP connection to rport on the remote will be - * forwarded to an instance of the class daemon with - * the argument arg. - * The class specified by daemon must implement ForwardedTCPIPDaemon. - * - * @param rport remote port - * @param daemon class name, which implements "ForwardedTCPIPDaemon" - * @param arg arguments for "daemon" - * @see #setPortForwardingR(String bind_address, int rport, String daemon, Object[] arg) - */ - public void setPortForwardingR(int rport, String daemon, Object[] arg) throws JSchException{ - setPortForwardingR(null, rport, daemon, arg); - } - - /** - * Registers the remote port forwarding. - * If bind_address is an empty string - * or "*", the port should be available from all interfaces. - * If bind_address is "localhost" or is not given, - * the listening port will be bound for local use only. - * Note that if GatewayPorts is "no" on the - * remote, "localhost" is always used as a bind_address. - * The TCP connection to rport on the remote will be - * forwarded to an instance of the class daemon with the - * argument arg. - * The class specified by daemon must implement ForwardedTCPIPDaemon. - * - * @param bind_address bind address - * @param rport remote port - * @param daemon class name, which implements "ForwardedTCPIPDaemon" - * @param arg arguments for "daemon" - * @see #setPortForwardingR(String bind_address, int rport, String daemon, Object[] arg) - */ - public void setPortForwardingR(String bind_address, int rport, String daemon, Object[] arg) throws JSchException{ - int allocated = _setPortForwardingR(bind_address, rport); - ChannelForwardedTCPIP.addPort(this, bind_address, - rport, allocated, daemon, arg); - } - - /** - * Lists the registered remote port forwarding. - * - * @return a list of "rport:host:hostport" - */ - public String[] getPortForwardingR() throws JSchException{ - return ChannelForwardedTCPIP.getPortForwarding(this); - } - - static class Forwarding { - String bind_address = null; - int port = -1; - String host = null; - int hostport = -1; - String socketPath = null; - } - - /** - * The given argument may be "[bind_address:]port:host:hostport" or - * "[bind_address:]port host:hostport", which is from LocalForward command of - * ~/.ssh/config . Also allows "[bind_address:]port:socketPath" or "[bind_address:]port socketPath" for socket forwarding. - */ - Forwarding parseForwarding(String conf) throws JSchException { - String[] tmp = conf.split(" "); - if(tmp.length>1){ // "[bind_address:]port host:hostport" - Vector foo = new Vector<>(); - for(int i=0; ibind_address is an empty string or "*", - * the port should be available from all interfaces. - * If bind_address is "localhost" or is not given, - * the listening port will be bound for local use only. - * - * @param conf configuration of local port forwarding - * @return an assigned port number - * @see #setPortForwardingL(String bind_address, int lport, String host, int rport) - */ - public int setPortForwardingL(String conf) throws JSchException { - Forwarding f = parseForwarding(conf); - return setPortForwardingL(f.bind_address, f.port, f.host, f.hostport); - } - - /** - * Registers the remote port forwarding. The argument should be - * in the format like "[bind_address:]port:host:hostport". If the - * bind_address is not given, the default is to only bind to loopback - * addresses. If the bind_address is "*" or an empty string, - * then the forwarding is requested to listen on all interfaces. - * Note that if GatewayPorts is "no" on the remote, - * "localhost" is always used for bind_address. - * If the specified remote is "0", - * the TCP port will be allocated on the remote. - * - * @param conf configuration of remote port forwarding - * @return an allocated TCP port on the remote. - * @see #setPortForwardingR(String bind_address, int rport, String host, int rport) - */ - public int setPortForwardingR(String conf) throws JSchException { - Forwarding f = parseForwarding(conf); - int allocated = _setPortForwardingR(f.bind_address, f.port); - ChannelForwardedTCPIP.addPort(this, f.bind_address, - f.port, allocated, f.host, f.hostport, null); - return allocated; - } - - /** - * Instantiates an instance of stream-forwarder to host:port. - * Set I/O stream to the given channel, and then invoke Channel#connect() method. - * - * @param host remote host, which the given stream will be plugged to. - * @param port remote port, which the given stream will be plugged to. - */ - public Channel getStreamForwarder(String host, int port) throws JSchException { - ChannelDirectTCPIP channel = new ChannelDirectTCPIP(); - channel.init(); - this.addChannel(channel); - channel.setHost(host); - channel.setPort(port); - return channel; - } - - private static class GlobalRequestReply{ - private Thread thread=null; - private int reply=-1; - private int port=0; - void setThread(Thread thread){ - this.thread=thread; - this.reply=-1; - } - Thread getThread(){ return thread; } - void setReply(int reply){ this.reply=reply; } - int getReply(){ return this.reply; } - int getPort(){ return this.port; } - void setPort(int port){ this.port=port; } - } - private GlobalRequestReply grr=new GlobalRequestReply(); - private int _setPortForwardingR(String bind_address, int rport) throws JSchException{ - synchronized(grr){ - Buffer buf=new Buffer(200); // ?? - Packet packet=new Packet(buf); - - String address_to_bind=ChannelForwardedTCPIP.normalize(bind_address); - - grr.setThread(Thread.currentThread()); - grr.setPort(rport); - - try{ - // byte SSH_MSG_GLOBAL_REQUEST 80 - // string "tcpip-forward" - // boolean want_reply - // string address_to_bind - // uint32 port number to bind - packet.reset(); - buf.putByte((byte) SSH_MSG_GLOBAL_REQUEST); - buf.putString(Util.str2byte("tcpip-forward")); - buf.putByte((byte)1); - buf.putString(Util.str2byte(address_to_bind)); - buf.putInt(rport); - write(packet); - } - catch(Exception e){ - grr.setThread(null); - throw new JSchException(e.toString(), e); - } - - int count = 0; - int reply = grr.getReply(); - while(count < 10 && reply == -1){ - try{ Thread.sleep(1000); } - catch(Exception e){ - } - count++; - reply = grr.getReply(); - } - grr.setThread(null); - if(reply != 1){ - throw new JSchException("remote port forwarding failed for listen port "+rport); - } - rport=grr.getPort(); - } - return rport; - } - - /** - * Cancels the remote port forwarding assigned at remote TCP port rport. - * - * @param rport remote TCP port - */ - public void delPortForwardingR(int rport) throws JSchException{ - this.delPortForwardingR(null, rport); - } - - /** - * Cancels the remote port forwarding assigned at - * remote TCP port rport bound on the interface at - * bind_address. - * - * @param bind_address bind address of the interface on the remote - * @param rport remote TCP port - */ - public void delPortForwardingR(String bind_address, int rport) throws JSchException{ - ChannelForwardedTCPIP.delPort(this, bind_address, rport); - } - - private void initDeflater(String method) throws JSchException{ - Compression odeflater=deflater; - if(method.equals("none")){ - deflater=null; - if(odeflater!=null){ - odeflater.end(); - } - return; - } - String foo=getConfig(method); - if(foo!=null){ - if(method.equals("zlib") || - (isAuthed && method.equals("zlib@openssh.com"))){ - try{ - Class c=Class.forName(foo).asSubclass(Compression.class); - deflater=c.getDeclaredConstructor().newInstance(); - int level=6; - try{ level=Integer.parseInt(getConfig("compression_level"));} - catch(Exception ee){ } - deflater.init(Compression.DEFLATER, level, this); - } - catch(Exception ee){ - throw new JSchException(ee.toString(), ee); - //System.err.println(foo+" isn't accessible."); - } - finally{ - if(odeflater!=null){ - odeflater.end(); - } - } - } - } - } - private void initInflater(String method) throws JSchException{ - Compression oinflater=inflater; - if(method.equals("none")){ - inflater=null; - if(oinflater!=null){ - oinflater.end(); - } - return; - } - String foo=getConfig(method); - if(foo!=null){ - if(method.equals("zlib") || - (isAuthed && method.equals("zlib@openssh.com"))){ - try{ - Class c=Class.forName(foo).asSubclass(Compression.class); - inflater=c.getDeclaredConstructor().newInstance(); - inflater.init(Compression.INFLATER, 0, this); - } - catch(Exception ee){ - throw new JSchException(ee.toString(), ee); - //System.err.println(foo+" isn't accessible."); - } - finally{ - if(oinflater!=null){ - oinflater.end(); - } - } - } - } - } - - void addChannel(Channel channel){ - channel.setSession(this); - } - - String[] getServerSigAlgs(){ return serverSigAlgs; } - public void setProxy(Proxy proxy){ this.proxy=proxy; } - public void setHost(String host){ this.host=host; } - public void setPort(int port){ this.port=port; } - void setUserName(String username){ this.username=username; } - public void setUserInfo(UserInfo userinfo){ this.userinfo=userinfo; } - public UserInfo getUserInfo(){ return userinfo; } - public void setInputStream(InputStream in){ this.in=in; } - public void setOutputStream(OutputStream out){ this.out=out; } - public void setX11Host(String host){ ChannelX11.setHost(host); } - public void setX11Port(int port){ ChannelX11.setPort(port); } - public void setX11Cookie(String cookie){ ChannelX11.setCookie(cookie); } - public void setPassword(String password){ - if(password!=null) - this.password=Util.str2byte(password); - } - public void setPassword(byte[] password){ - if(password!=null){ - this.password=new byte[password.length]; - System.arraycopy(password, 0, this.password, 0, password.length); - } - } - - public void setConfig(Properties newconf){ - Hashtable foo=new Hashtable<>(); - for(String key : newconf.stringPropertyNames()){ - foo.put(key, newconf.getProperty(key)); - } - setConfig(foo); - } - - public void setConfig(Hashtable newconf){ - synchronized(lock){ - if(config==null) - config=new Hashtable<>(); - for(Enumeration e=newconf.keys() ; e.hasMoreElements() ;) { - String newkey=e.nextElement(); - String key=(newkey.equals("PubkeyAcceptedKeyTypes") ? "PubkeyAcceptedAlgorithms" : newkey); - String value=newconf.get(newkey); - if(key.equals("enable_server_sig_algs") && !value.equals("yes")){ - serverSigAlgs=null; - } - config.put(key, value); - } - } - } - - public void setConfig(String key, String value){ - synchronized(lock){ - if(config==null){ - config=new Hashtable<>(); - } - if(key.equals("PubkeyAcceptedKeyTypes")){ - config.put("PubkeyAcceptedAlgorithms", value); - } - else{ - if(key.equals("enable_server_sig_algs") && !value.equals("yes")){ - serverSigAlgs=null; - } - config.put(key, value); - } - } - } - - public String getConfig(String key){ - if(key.equals("PubkeyAcceptedKeyTypes")){ - key="PubkeyAcceptedAlgorithms"; - } - Object foo=null; - if(config!=null){ - foo=config.get(key); - if(foo instanceof String) return (String)foo; - } - foo=JSch.getConfig(key); - if(foo instanceof String) return (String)foo; - return null; - } - - public void setSocketFactory(SocketFactory sfactory){ - socket_factory=sfactory; - } - public boolean isConnected(){ return isConnected; } - public int getTimeout(){ return timeout; } - public void setTimeout(int timeout) throws JSchException { - if(socket==null){ - if(timeout<0){ - throw new JSchException("invalid timeout value"); - } - this.timeout=timeout; - return; - } - try{ - socket.setSoTimeout(timeout); - this.timeout=timeout; - } - catch(Exception e){ - throw new JSchException(e.toString(), e); - } - } - public String getServerVersion(){ - return Util.byte2str(V_S); - } - public String getClientVersion(){ - return Util.byte2str(V_C); - } - public void setClientVersion(String cv){ - V_C=Util.str2byte(cv); - } - - public void sendIgnore() throws Exception{ - Buffer buf=new Buffer(); - Packet packet=new Packet(buf); - packet.reset(); - buf.putByte((byte)SSH_MSG_IGNORE); - write(packet); - } - - private static final byte[] keepalivemsg=Util.str2byte("keepalive@jcraft.com"); - public void sendKeepAliveMsg() throws Exception{ - Buffer buf=new Buffer(); - Packet packet=new Packet(buf); - packet.reset(); - buf.putByte((byte)SSH_MSG_GLOBAL_REQUEST); - buf.putString(keepalivemsg); - buf.putByte((byte)1); - write(packet); - } - - private static final byte[] nomoresessions=Util.str2byte("no-more-sessions@openssh.com"); - public void noMoreSessionChannels() throws Exception{ - Buffer buf=new Buffer(); - Packet packet=new Packet(buf); - packet.reset(); - buf.putByte((byte)SSH_MSG_GLOBAL_REQUEST); - buf.putString(nomoresessions); - buf.putByte((byte)0); - write(packet); - } - - private HostKey hostkey=null; - public HostKey getHostKey(){ return hostkey; } - public String getHost(){return host;} - public String getUserName(){return username;} - public int getPort(){return port;} - public void setHostKeyAlias(String hostKeyAlias){ - this.hostKeyAlias=hostKeyAlias; - } - public String getHostKeyAlias(){ - return hostKeyAlias; - } - - /** - * Sets the interval to send a keep-alive message. If zero is - * specified, any keep-alive message must not be sent. The default interval - * is zero. - * - * @param interval the specified interval, in milliseconds. - * @see #getServerAliveInterval() - */ - public void setServerAliveInterval(int interval) throws JSchException { - setTimeout(interval); - this.serverAliveInterval=interval; - } - - /** - * Returns setting for the interval to send a keep-alive message. - * - * @see #setServerAliveInterval(int) - */ - public int getServerAliveInterval(){ - return this.serverAliveInterval; - } - - /** - * Sets the number of keep-alive messages which may be sent without - * receiving any messages back from the server. If this threshold is - * reached while keep-alive messages are being sent, the connection will - * be disconnected. The default value is one. - * - * @param count the specified count - * @see #getServerAliveCountMax() - */ - public void setServerAliveCountMax(int count){ - this.serverAliveCountMax=count; - } - - /** - * Returns setting for the threshold to send keep-alive messages. - * - * @see #setServerAliveCountMax(int) - */ - public int getServerAliveCountMax(){ - return this.serverAliveCountMax; - } - - public void setDaemonThread(boolean enable){ - this.daemon_thread=enable; - } - - private String[] checkCiphers(String ciphers){ - if(ciphers==null || ciphers.length()==0) - return null; - - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, - "CheckCiphers: "+ciphers); - } - - String cipherc2s=getConfig("cipher.c2s"); - String ciphers2c=getConfig("cipher.s2c"); - - Vector result=new Vector<>(); - String[] _ciphers=Util.split(ciphers, ","); - for(int i=0; i<_ciphers.length; i++){ - String cipher=_ciphers[i]; - if(ciphers2c.indexOf(cipher) == -1 && cipherc2s.indexOf(cipher) == -1) - continue; - if(!checkCipher(getConfig(cipher))){ - result.addElement(cipher); - } - } - if(result.size()==0) - return null; - String[] foo=new String[result.size()]; - System.arraycopy(result.toArray(), 0, foo, 0, result.size()); - - if(getLogger().isEnabled(Logger.INFO)){ - for(int i=0; i c=Class.forName(cipher).asSubclass(Cipher.class); - Cipher _c=c.getDeclaredConstructor().newInstance(); - _c.init(Cipher.ENCRYPT_MODE, - new byte[_c.getBlockSize()], - new byte[_c.getIVSize()]); - return true; - } - catch(Exception | NoClassDefFoundError e){ - return false; - } - } - - private String[] checkMacs(String macs){ - if(macs==null || macs.length()==0) - return null; - - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, - "CheckMacs: "+macs); - } - - String macc2s=getConfig("mac.c2s"); - String macs2c=getConfig("mac.s2c"); - - Vector result=new Vector<>(); - String[] _macs=Util.split(macs, ","); - for(int i=0; i<_macs.length; i++){ - String mac=_macs[i]; - if(macs2c.indexOf(mac) == -1 && macc2s.indexOf(mac) == -1) - continue; - if(!checkMac(getConfig(mac))){ - result.addElement(mac); - } - } - if(result.size()==0) - return null; - String[] foo=new String[result.size()]; - System.arraycopy(result.toArray(), 0, foo, 0, result.size()); - - if(getLogger().isEnabled(Logger.INFO)){ - for(int i=0; i c=Class.forName(mac).asSubclass(MAC.class); - MAC _c=c.getDeclaredConstructor().newInstance(); - _c.init(new byte[_c.getBlockSize()]); - return true; - } - catch(Exception | NoClassDefFoundError e){ - return false; - } - } - - private String[] checkKexes(String kexes){ - if(kexes==null || kexes.length()==0) - return null; - - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, - "CheckKexes: "+kexes); - } - - Vector result=new Vector<>(); - String[] _kexes=Util.split(kexes, ","); - for(int i=0; i<_kexes.length; i++){ - if(!checkKex(this, getConfig(_kexes[i]))){ - result.addElement(_kexes[i]); - } - } - if(result.size()==0) - return null; - String[] foo=new String[result.size()]; - System.arraycopy(result.toArray(), 0, foo, 0, result.size()); - - if(getLogger().isEnabled(Logger.INFO)){ - for(int i=0; i c=Class.forName(kex).asSubclass(KeyExchange.class); - KeyExchange _c=c.getDeclaredConstructor().newInstance(); - _c.doInit(s ,null, null, null, null); - return true; - } - catch(Exception | NoClassDefFoundError e){ return false; } - } - - private String[] checkSignatures(String sigs){ - if(sigs==null || sigs.length()==0) - return null; - - if(getLogger().isEnabled(Logger.INFO)){ - getLogger().log(Logger.INFO, - "CheckSignatures: "+sigs); - } - - Vector result=new Vector<>(); - String[] _sigs=Util.split(sigs, ","); - for(int i=0; i<_sigs.length; i++){ - try{ - Class c=Class.forName(JSch.getConfig(_sigs[i])).asSubclass(Signature.class); - final Signature sig=c.getDeclaredConstructor().newInstance(); - sig.init(); - } - catch(Exception | NoClassDefFoundError e){ - result.addElement(_sigs[i]); - } - } - if(result.size()==0) - return null; - String[] foo=new String[result.size()]; - System.arraycopy(result.toArray(), 0, foo, 0, result.size()); - if(getLogger().isEnabled(Logger.INFO)){ - for(int i=0; inull. - * - * @param identityRepository - * @see #getIdentityRepository() - */ - public void setIdentityRepository(IdentityRepository identityRepository){ - this.identityRepository = identityRepository; - } - - /** - * Gets the identityRepository. - * If this.identityRepository is null, - * JSch#getIdentityRepository() will be invoked. - * - * @see JSch#getIdentityRepository() - */ - IdentityRepository getIdentityRepository(){ - if(identityRepository == null) - return jsch.getIdentityRepository(); - return identityRepository; - } - - /** - * Sets the hostkeyRepository, which will be referred in checking host keys. - * - * @param hostkeyRepository - * @see #getHostKeyRepository() - */ - public void setHostKeyRepository(HostKeyRepository hostkeyRepository){ - this.hostkeyRepository = hostkeyRepository; - } - - /** - * Gets the hostkeyRepository. - * If this.hostkeyRepository is null, - * JSch#getHostKeyRepository() will be invoked. - * - * @see JSch#getHostKeyRepository() - */ - public HostKeyRepository getHostKeyRepository(){ - if(hostkeyRepository == null) - return jsch.getHostKeyRepository(); - return hostkeyRepository; - } - - /* - // setProxyCommand("ssh -l user2 host2 -o 'ProxyCommand ssh user1@host1 nc host2 22' nc %h %p") - public void setProxyCommand(String command){ - setProxy(new ProxyCommand(command)); - } - - class ProxyCommand implements Proxy { - String command; - Process p = null; - InputStream in = null; - OutputStream out = null; - ProxyCommand(String command){ - this.command = command; - } - public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws Exception { - String _command = command.replace("%h", host); - _command = _command.replace("%p", new Integer(port).toString()); - p = Runtime.getRuntime().exec(_command); - in = p.getInputStream(); - out = p.getOutputStream(); - } - public Socket getSocket() { return null; } - public InputStream getInputStream() { return in; } - public OutputStream getOutputStream() { return out; } - public void close() { - try{ - if(p!=null){ - p.getErrorStream().close(); - p.getOutputStream().close(); - p.getInputStream().close(); - p.destroy(); - p=null; - } - } - catch(IOException e){ - } - } - } - */ - - private void applyConfig() throws JSchException { - ConfigRepository configRepository = jsch.getConfigRepository(); - if(configRepository == null){ - return; - } - - ConfigRepository.Config config = - configRepository.getConfig(org_host); - - String value = null; - - if(username==null){ - value = config.getUser(); - if(value != null) - username = value; - } - - value = config.getHostname(); - if(value != null) - host = value; - - int port = config.getPort(); - if(port != -1) - this.port = port; - - checkConfig(config, "kex"); - checkConfig(config, "server_host_key"); - checkConfig(config, "prefer_known_host_key_types"); - - checkConfig(config, "cipher.c2s"); - checkConfig(config, "cipher.s2c"); - checkConfig(config, "mac.c2s"); - checkConfig(config, "mac.s2c"); - checkConfig(config, "compression.c2s"); - checkConfig(config, "compression.s2c"); - checkConfig(config, "compression_level"); - - checkConfig(config, "StrictHostKeyChecking"); - checkConfig(config, "HashKnownHosts"); - checkConfig(config, "PreferredAuthentications"); - checkConfig(config, "PubkeyAcceptedAlgorithms"); - checkConfig(config, "FingerprintHash"); - checkConfig(config, "MaxAuthTries"); - checkConfig(config, "ClearAllForwardings"); - - value = config.getValue("HostKeyAlias"); - if(value != null) - this.setHostKeyAlias(value); - - value = config.getValue("UserKnownHostsFile"); - if(value != null) { - KnownHosts kh = new KnownHosts(jsch); - kh.setKnownHosts(value); - this.setHostKeyRepository(kh); - } - - String[] values = config.getValues("IdentityFile"); - if(values != null) { - String[] global = - configRepository.getConfig("").getValues("IdentityFile"); - if(global != null){ - for(int i = 0; i < global.length; i++){ - jsch.addIdentity(global[i]); - } - } - else { - global = new String[0]; - } - if(values.length - global.length > 0){ - IdentityRepositoryWrapper ir = - new IdentityRepositoryWrapper(jsch.getIdentityRepository(), true); - for(int i = 0; i < values.length; i++){ - String ifile = values[i]; - for(int j = 0; j < global.length; j++){ - if(!ifile.equals(global[j])) - continue; - ifile = null; - break; - } - if(ifile == null) - continue; - Identity identity = - IdentityFile.newInstance(ifile, null, jsch); - ir.add(identity); - } - this.setIdentityRepository(ir); - } - } - - value = config.getValue("ServerAliveInterval"); - if(value != null) { - try { - this.setServerAliveInterval(Integer.parseInt(value)); - } - catch(NumberFormatException e){ - } - } - - value = config.getValue("ConnectTimeout"); - if(value != null) { - try { - setTimeout(Integer.parseInt(value)); - } - catch(NumberFormatException e){ - } - } - - value = config.getValue("MaxAuthTries"); - if(value != null) { - setConfig("MaxAuthTries", value); - } - - value = config.getValue("ClearAllForwardings"); - if(value != null) { - setConfig("ClearAllForwardings", value); - } - - } - - private void applyConfigChannel(ChannelSession channel) throws JSchException { - ConfigRepository configRepository = jsch.getConfigRepository(); - if(configRepository == null){ - return; - } - - ConfigRepository.Config config = - configRepository.getConfig(org_host); - - String value = null; - - value = config.getValue("ForwardAgent"); - if(value != null){ - channel.setAgentForwarding(value.equals("yes")); - } - - value = config.getValue("RequestTTY"); - if(value != null){ - channel.setPty(value.equals("yes")); - } - } - - private void requestPortForwarding() throws JSchException { - - if(getConfig("ClearAllForwardings").equals("yes")) - return; - - ConfigRepository configRepository = jsch.getConfigRepository(); - if(configRepository == null){ - return; - } - - ConfigRepository.Config config = - configRepository.getConfig(org_host); - - String[] values = config.getValues("LocalForward"); - if(values != null){ - for(int i = 0; i < values.length; i++) { - setPortForwardingL(values[i]); - } - } - - values = config.getValues("RemoteForward"); - if(values != null){ - for(int i = 0; i < values.length; i++) { - setPortForwardingR(values[i]); - } - } - } - - private void checkConfig(ConfigRepository.Config config, String key){ - String value = config.getValue(key); - if(value == null && key.equals("PubkeyAcceptedAlgorithms")) - value = config.getValue("PubkeyAcceptedKeyTypes"); - if(value != null) - this.setConfig(key, value); - } - - /** - * Returns the logger being used by this instance of Session. If no - * particular logger has been set, the instance logger of the - * jsch instance is returned this session belongs to. - * @return The logger - */ - public Logger getLogger() { - if (logger != null) { - return logger; - } - return jsch.getInstanceLogger(); - } - - /** - * Sets the logger being used by this instance of Session - * @param logger The logger or null if the instance logger - * of this instance's jsch instance should be used - */ - public void setLogger(Logger logger) { - this.logger = logger; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpATTRS.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpATTRS.java deleted file mode 100644 index c98877b2..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpATTRS.java +++ /dev/null @@ -1,295 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.text.SimpleDateFormat; -import java.util.Date; - -/* - uint32 flags - uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE - uint32 uid present only if flag SSH_FILEXFER_ATTR_UIDGID - uint32 gid present only if flag SSH_FILEXFER_ATTR_UIDGID - uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS - uint32 atime present only if flag SSH_FILEXFER_ACMODTIME - uint32 mtime present only if flag SSH_FILEXFER_ACMODTIME - uint32 extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED - string extended_type - string extended_data - ... more extended data (extended_type - extended_data pairs), - so that number of pairs equals extended_count -*/ -public class SftpATTRS { - - static final int S_ISUID = 04000; // set user ID on execution - static final int S_ISGID = 02000; // set group ID on execution - static final int S_ISVTX = 01000; // sticky bit ****** NOT DOCUMENTED ***** - - static final int S_IRUSR = 00400; // read by owner - static final int S_IWUSR = 00200; // write by owner - static final int S_IXUSR = 00100; // execute/search by owner - static final int S_IREAD = 00400; // read by owner - static final int S_IWRITE= 00200; // write by owner - static final int S_IEXEC = 00100; // execute/search by owner - - static final int S_IRGRP = 00040; // read by group - static final int S_IWGRP = 00020; // write by group - static final int S_IXGRP = 00010; // execute/search by group - - static final int S_IROTH = 00004; // read by others - static final int S_IWOTH = 00002; // write by others - static final int S_IXOTH = 00001; // execute/search by others - - private static final int pmask = 0xFFF; - - public String getPermissionsString() { - StringBuilder buf = new StringBuilder(10); - - if(isDir()) buf.append('d'); - else if(isLink()) buf.append('l'); - else buf.append('-'); - - if((permissions & S_IRUSR)!=0) buf.append('r'); - else buf.append('-'); - - if((permissions & S_IWUSR)!=0) buf.append('w'); - else buf.append('-'); - - if((permissions & S_ISUID)!=0) buf.append('s'); - else if ((permissions & S_IXUSR)!=0) buf.append('x'); - else buf.append('-'); - - if((permissions & S_IRGRP)!=0) buf.append('r'); - else buf.append('-'); - - if((permissions & S_IWGRP)!=0) buf.append('w'); - else buf.append('-'); - - if((permissions & S_ISGID)!=0) buf.append('s'); - else if((permissions & S_IXGRP)!=0) buf.append('x'); - else buf.append('-'); - - if((permissions & S_IROTH) != 0) buf.append('r'); - else buf.append('-'); - - if((permissions & S_IWOTH) != 0) buf.append('w'); - else buf.append('-'); - - if((permissions & S_IXOTH) != 0) buf.append('x'); - else buf.append('-'); - return (buf.toString()); - } - - public String getAtimeString(){ - Date date= new Date(((long)atime)*1000L); - return (date.toString()); - } - - public String getMtimeString(){ - Date date= new Date(((long)mtime)*1000L); - return (date.toString()); - } - - public static final int SSH_FILEXFER_ATTR_SIZE= 0x00000001; - public static final int SSH_FILEXFER_ATTR_UIDGID= 0x00000002; - public static final int SSH_FILEXFER_ATTR_PERMISSIONS= 0x00000004; - public static final int SSH_FILEXFER_ATTR_ACMODTIME= 0x00000008; - public static final int SSH_FILEXFER_ATTR_EXTENDED= 0x80000000; - - static final int S_IFMT=0xf000; - static final int S_IFIFO=0x1000; - static final int S_IFCHR=0x2000; - static final int S_IFDIR=0x4000; - static final int S_IFBLK=0x6000; - static final int S_IFREG=0x8000; - static final int S_IFLNK=0xa000; - static final int S_IFSOCK=0xc000; - - int flags=0; - long size; - int uid; - int gid; - int permissions; - int atime; - int mtime; - String[] extended=null; - - private SftpATTRS(){ - } - - static SftpATTRS getATTR(Buffer buf){ - SftpATTRS attr=new SftpATTRS(); - attr.flags=buf.getInt(); - if((attr.flags&SSH_FILEXFER_ATTR_SIZE)!=0){ attr.size=buf.getLong(); } - if((attr.flags&SSH_FILEXFER_ATTR_UIDGID)!=0){ - attr.uid=buf.getInt(); attr.gid=buf.getInt(); - } - if((attr.flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0){ - attr.permissions=buf.getInt(); - } - if((attr.flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){ - attr.atime=buf.getInt(); - } - if((attr.flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){ - attr.mtime=buf.getInt(); - } - if((attr.flags&SSH_FILEXFER_ATTR_EXTENDED)!=0){ - int count=buf.getInt(); - if(count>0){ - attr.extended=new String[count*2]; - for(int i=0; i0){ - for(int i=0; i0){ - for(int i=0; i c=Class.forName(session.getConfig(method)).asSubclass(GSSContext.class); - context=c.getDeclaredConstructor().newInstance(); - } - catch(Exception e){ - return false; - } - - try{ - context.create(username, session.host); - } - catch(JSchException e){ - return false; - } - - byte[] token=new byte[0]; - - while(!context.isEstablished()){ - try{ - token=context.init(token, 0, token.length); - } - catch(JSchException e){ - // TODO - // ERRTOK should be sent? - // byte SSH_MSG_USERAUTH_GSSAPI_ERRTOK - // string error token - return false; - } - - if(token!=null){ - packet.reset(); - buf.putByte((byte)SSH_MSG_USERAUTH_GSSAPI_TOKEN); - buf.putString(token); - session.write(packet); - } - - if(!context.isEstablished()){ - buf=session.read(buf); - command=buf.getCommand()&0xff; - if(command==SSH_MSG_USERAUTH_GSSAPI_ERROR){ - // uint32 major_status - // uint32 minor_status - // string message - // string language tag - - buf=session.read(buf); - command=buf.getCommand()&0xff; - //return false; - } - else if(command==SSH_MSG_USERAUTH_GSSAPI_ERRTOK){ - // string error token - - buf=session.read(buf); - command=buf.getCommand()&0xff; - //return false; - } - - if(command==SSH_MSG_USERAUTH_FAILURE){ - return false; - } - - buf.getInt(); buf.getByte(); buf.getByte(); - token=buf.getString(); - } - } - - Buffer mbuf=new Buffer(); - // string session identifier - // byte SSH_MSG_USERAUTH_REQUEST - // string user name - // string service - // string "gssapi-with-mic" - mbuf.putString(session.getSessionId()); - mbuf.putByte((byte)SSH_MSG_USERAUTH_REQUEST); - mbuf.putString(_username); - mbuf.putString(Util.str2byte("ssh-connection")); - mbuf.putString(Util.str2byte("gssapi-with-mic")); - - byte[] mic=context.getMIC(mbuf.buffer, 0, mbuf.getLength()); - - if(mic==null){ - return false; - } - - packet.reset(); - buf.putByte((byte)SSH_MSG_USERAUTH_GSSAPI_MIC); - buf.putString(mic); - session.write(packet); - - context.dispose(); - - buf=session.read(buf); - command=buf.getCommand()&0xff; - - if(command==SSH_MSG_USERAUTH_SUCCESS){ - return true; - } - else if(command==SSH_MSG_USERAUTH_FAILURE){ - buf.getInt(); buf.getByte(); buf.getByte(); - byte[] foo=buf.getString(); - int partial_success=buf.getByte(); - //System.err.println(new String(foo)+ - // " partial_success:"+(partial_success!=0)); - if(partial_success!=0){ - throw new JSchPartialAuthException(Util.byte2str(foo)); - } - } - return false; - } -} - - diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthKeyboardInteractive.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthKeyboardInteractive.java deleted file mode 100644 index 1efe03a9..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthKeyboardInteractive.java +++ /dev/null @@ -1,204 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -class UserAuthKeyboardInteractive extends UserAuth{ - @Override - public boolean start(Session session) throws Exception{ - super.start(session); - - if(userinfo!=null && !(userinfo instanceof UIKeyboardInteractive)){ - return false; - } - - String dest=username+"@"+session.host; - if(session.port!=22){ - dest+=(":"+session.port); - } - byte[] password=session.password; - - boolean cancel=false; - - byte[] _username=null; - _username=Util.str2byte(username); - - while(true){ - - if(session.auth_failures >= session.max_auth_tries){ - return false; - } - - // send - // byte SSH_MSG_USERAUTH_REQUEST(50) - // string user name (ISO-10646 UTF-8, as defined in [RFC-2279]) - // string service name (US-ASCII) "ssh-userauth" ? "ssh-connection" - // string "keyboard-interactive" (US-ASCII) - // string language tag (as defined in [RFC-3066]) - // string submethods (ISO-10646 UTF-8) - packet.reset(); - buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST); - buf.putString(_username); - buf.putString(Util.str2byte("ssh-connection")); - //buf.putString("ssh-userauth".getBytes()); - buf.putString(Util.str2byte("keyboard-interactive")); - buf.putString(Util.empty); - buf.putString(Util.empty); - session.write(packet); - - boolean firsttime=true; - loop: - while(true){ - buf=session.read(buf); - int command=buf.getCommand()&0xff; - - if(command==SSH_MSG_USERAUTH_SUCCESS){ - return true; - } - if(command==SSH_MSG_USERAUTH_BANNER){ - buf.getInt(); buf.getByte(); buf.getByte(); - byte[] _message=buf.getString(); - byte[] lang=buf.getString(); - String message=Util.byte2str(_message); - if(userinfo!=null){ - userinfo.showMessage(message); - } - continue loop; - } - if(command==SSH_MSG_USERAUTH_FAILURE){ - buf.getInt(); buf.getByte(); buf.getByte(); - byte[] foo=buf.getString(); - int partial_success=buf.getByte(); -// System.err.println(new String(foo)+ -// " partial_success:"+(partial_success!=0)); - - if(partial_success!=0){ - throw new JSchPartialAuthException(Util.byte2str(foo)); - } - - if(firsttime){ - return false; - //throw new JSchException("USERAUTH KI is not supported"); - //cancel=true; // ?? - } - session.auth_failures++; - break; - } - if(command==SSH_MSG_USERAUTH_INFO_REQUEST){ - firsttime=false; - buf.getInt(); buf.getByte(); buf.getByte(); - String name=Util.byte2str(buf.getString()); - String instruction=Util.byte2str(buf.getString()); - String languate_tag=Util.byte2str(buf.getString()); - int num=buf.getInt(); - String[] prompt=new String[num]; - boolean[] echo=new boolean[num]; - for(int i=0; i= 0){ - response=new byte[1][]; - response[0]=password; - password=null; - } - else if(num>0 - ||(name.length()>0 || instruction.length()>0) - ){ - if(userinfo!=null){ - UIKeyboardInteractive kbi=(UIKeyboardInteractive)userinfo; - String[] _response=kbi.promptKeyboardInteractive(dest, - name, - instruction, - prompt, - echo); - if(_response!=null){ - response=new byte[_response.length][]; - for(int i=0; i<_response.length; i++){ - response[i]=Util.str2byte(_response[i]); - } - } - } - } - - // byte SSH_MSG_USERAUTH_INFO_RESPONSE(61) - // int num-responses - // string response[1] (ISO-10646 UTF-8) - // ... - // string response[num-responses] (ISO-10646 UTF-8) - packet.reset(); - buf.putByte((byte)SSH_MSG_USERAUTH_INFO_RESPONSE); - if(num>0 && - (response==null || // cancel - num!=response.length)){ - - if(response==null){ - // working around the bug in OpenSSH ;-< - buf.putInt(num); - for(int i=0; i= session.max_auth_tries){ - return false; - } - - if(password==null){ - if(userinfo==null){ - //throw new JSchException("USERAUTH fail"); - return false; - } - if(!userinfo.promptPassword("Password for "+dest)){ - throw new JSchAuthCancelException("password"); - //break; - } - - String _password=userinfo.getPassword(); - if(_password==null){ - throw new JSchAuthCancelException("password"); - //break; - } - password=Util.str2byte(_password); - } - - byte[] _username=null; - _username=Util.str2byte(username); - - // send - // byte SSH_MSG_USERAUTH_REQUEST(50) - // string user name - // string service name ("ssh-connection") - // string "password" - // boolen FALSE - // string plaintext password (ISO-10646 UTF-8) - packet.reset(); - buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST); - buf.putString(_username); - buf.putString(Util.str2byte("ssh-connection")); - buf.putString(Util.str2byte("password")); - buf.putByte((byte)0); - buf.putString(password); - session.write(packet); - - loop: - while(true){ - buf=session.read(buf); - int command=buf.getCommand()&0xff; - - if(command==SSH_MSG_USERAUTH_SUCCESS){ - return true; - } - if(command==SSH_MSG_USERAUTH_BANNER){ - buf.getInt(); buf.getByte(); buf.getByte(); - byte[] _message=buf.getString(); - byte[] lang=buf.getString(); - String message=Util.byte2str(_message); - if(userinfo!=null){ - userinfo.showMessage(message); - } - continue loop; - } - if(command==SSH_MSG_USERAUTH_PASSWD_CHANGEREQ){ - buf.getInt(); buf.getByte(); buf.getByte(); - byte[] instruction=buf.getString(); - byte[] tag=buf.getString(); - if(userinfo==null || - !(userinfo instanceof UIKeyboardInteractive)){ - if(userinfo!=null){ - userinfo.showMessage("Password must be changed."); - } - return false; - } - - UIKeyboardInteractive kbi=(UIKeyboardInteractive)userinfo; - String[] response; - String name="Password Change Required"; - String[] prompt={"New Password: "}; - boolean[] echo={false}; - response=kbi.promptKeyboardInteractive(dest, - name, - Util.byte2str(instruction), - prompt, - echo); - if(response==null){ - throw new JSchAuthCancelException("password"); - } - - byte[] newpassword=Util.str2byte(response[0]); - - // send - // byte SSH_MSG_USERAUTH_REQUEST(50) - // string user name - // string service name ("ssh-connection") - // string "password" - // boolen TRUE - // string plaintext old password (ISO-10646 UTF-8) - // string plaintext new password (ISO-10646 UTF-8) - packet.reset(); - buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST); - buf.putString(_username); - buf.putString(Util.str2byte("ssh-connection")); - buf.putString(Util.str2byte("password")); - buf.putByte((byte)1); - buf.putString(password); - buf.putString(newpassword); - Util.bzero(newpassword); - response=null; - session.write(packet); - continue loop; - } - if(command==SSH_MSG_USERAUTH_FAILURE){ - buf.getInt(); buf.getByte(); buf.getByte(); - byte[] foo=buf.getString(); - int partial_success=buf.getByte(); - //System.err.println(new String(foo)+ - // " partial_success:"+(partial_success!=0)); - if(partial_success!=0){ - throw new JSchPartialAuthException(Util.byte2str(foo)); - } - session.auth_failures++; - break; - } - else{ - //System.err.println("USERAUTH fail ("+buf.getCommand()+")"); -// throw new JSchException("USERAUTH fail ("+buf.getCommand()+")"); - return false; - } - } - - if(password!=null){ - Util.bzero(password); - password=null; - } - - } - - } - finally{ - if(password!=null){ - Util.bzero(password); - password=null; - } - } - - //throw new JSchException("USERAUTH fail"); - //return false; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthPublicKey.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthPublicKey.java deleted file mode 100644 index d18cf731..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthPublicKey.java +++ /dev/null @@ -1,401 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -import java.util.*; - -class UserAuthPublicKey extends UserAuth{ - - @Override - public boolean start(Session session) throws Exception{ - super.start(session); - - Vector identities=session.getIdentityRepository().getIdentities(); - - synchronized(identities){ - if(identities.size()<=0){ - return false; - } - - String pkmethodstr=session.getConfig("PubkeyAcceptedAlgorithms"); - if(session.getLogger().isEnabled(Logger.DEBUG)){ - session.getLogger().log(Logger.DEBUG, - "PubkeyAcceptedAlgorithms = " + pkmethodstr); - } - - String[] not_available_pka = session.getUnavailableSignatures(); - List not_available_pks=(not_available_pka!=null && not_available_pka.length>0 ? - Arrays.asList(not_available_pka) : - Collections.emptyList()); - if(!not_available_pks.isEmpty()){ - if(session.getLogger().isEnabled(Logger.DEBUG)){ - session.getLogger().log(Logger.DEBUG, - "Signature algorithms unavailable for non-agent identities = " + not_available_pks); - } - } - - List pkmethods=Arrays.asList(Util.split(pkmethodstr, ",")); - if(pkmethods.isEmpty()){ - return false; - } - - String[] server_sig_algs=session.getServerSigAlgs(); - if(server_sig_algs!=null && server_sig_algs.length>0){ - List _known=new ArrayList<>(); - List _unknown=new ArrayList<>(); - for(String pkmethod : pkmethods){ - boolean add=false; - for(String server_sig_alg : server_sig_algs){ - if(pkmethod.equals(server_sig_alg)){ - add=true; - break; - } - } - - if(add){ - _known.add(pkmethod); - } - else{ - _unknown.add(pkmethod); - } - } - - if(!_known.isEmpty()){ - if(session.getLogger().isEnabled(Logger.DEBUG)){ - session.getLogger().log(Logger.DEBUG, - "PubkeyAcceptedAlgorithms in server-sig-algs = " + _known); - } - } - - if(!_unknown.isEmpty()){ - if(session.getLogger().isEnabled(Logger.DEBUG)){ - session.getLogger().log(Logger.DEBUG, - "PubkeyAcceptedAlgorithms not in server-sig-algs = " + _unknown); - } - } - - if(!_known.isEmpty() && !_unknown.isEmpty()){ - boolean success=_start(session, identities, _known, not_available_pks); - if(success){ - return true; - } - - return _start(session, identities, _unknown, not_available_pks); - } - } - else{ - if(session.getLogger().isEnabled(Logger.DEBUG)){ - session.getLogger().log(Logger.DEBUG, "No server-sig-algs found, using PubkeyAcceptedAlgorithms = " + pkmethods); - } - } - - return _start(session, identities, pkmethods, not_available_pks); - } - } - - private boolean _start(Session session, List identities, List pkmethods, List not_available_pks) throws Exception{ - if(session.auth_failures >= session.max_auth_tries){ - return false; - } - - List rsamethods=new ArrayList<>(); - List nonrsamethods=new ArrayList<>(); - for(String pkmethod : pkmethods){ - if(pkmethod.equals("ssh-rsa") || pkmethod.equals("rsa-sha2-256") || pkmethod.equals("rsa-sha2-512") || - pkmethod.equals("ssh-rsa-sha224@ssh.com") || pkmethod.equals("ssh-rsa-sha256@ssh.com") || - pkmethod.equals("ssh-rsa-sha384@ssh.com") || pkmethod.equals("ssh-rsa-sha512@ssh.com")){ - rsamethods.add(pkmethod); - } - else{ - nonrsamethods.add(pkmethod); - } - } - - byte[] _username=Util.str2byte(username); - - int command; - - iloop: - for(Identity identity : identities){ - - if(session.auth_failures >= session.max_auth_tries){ - return false; - } - - //System.err.println("UserAuthPublicKey: identity.isEncrypted()="+identity.isEncrypted()); - decryptKey(session, identity); - //System.err.println("UserAuthPublicKey: identity.isEncrypted()="+identity.isEncrypted()); - - String _ipkmethod=identity.getAlgName(); - List ipkmethods=null; - if(_ipkmethod.equals("ssh-rsa")){ - ipkmethods=rsamethods; - } - else if(nonrsamethods.contains(_ipkmethod)){ - ipkmethods=Collections.singletonList(_ipkmethod); - } - if(ipkmethods==null) { - if(session.getLogger().isEnabled(Logger.DEBUG)){ - session.getLogger().log(Logger.DEBUG, - _ipkmethod+" cannot be used as public key type for identity "+identity.getName()); - } - continue; - } - - byte[] pubkeyblob=identity.getPublicKeyBlob(); - List pkmethodsuccesses=null; - - if(pubkeyblob!=null){ - command=SSH_MSG_USERAUTH_FAILURE; - loop3: - for(String ipkmethod : ipkmethods){ - if(not_available_pks.contains(ipkmethod) && !(identity instanceof AgentIdentity)){ - if(session.getLogger().isEnabled(Logger.DEBUG)){ - session.getLogger().log(Logger.DEBUG, - ipkmethod+" not available for identity "+identity.getName()); - } - continue loop3; - } - - // send - // byte SSH_MSG_USERAUTH_REQUEST(50) - // string user name - // string service name ("ssh-connection") - // string "publickey" - // boolen FALSE - // string public key algorithm name - // string public key blob - packet.reset(); - buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST); - buf.putString(_username); - buf.putString(Util.str2byte("ssh-connection")); - buf.putString(Util.str2byte("publickey")); - buf.putByte((byte)0); - buf.putString(Util.str2byte(ipkmethod)); - buf.putString(pubkeyblob); - session.write(packet); - - loop1: - while(true){ - buf=session.read(buf); - command=buf.getCommand()&0xff; - - if(command==SSH_MSG_USERAUTH_PK_OK){ - if(session.getLogger().isEnabled(Logger.DEBUG)){ - session.getLogger().log(Logger.DEBUG, - ipkmethod + " preauth success"); - } - pkmethodsuccesses=Collections.singletonList(ipkmethod); - break loop3; - } - else if(command==SSH_MSG_USERAUTH_FAILURE){ - if(session.getLogger().isEnabled(Logger.DEBUG)){ - session.getLogger().log(Logger.DEBUG, - ipkmethod + " preauth failure"); - } - continue loop3; - } - else if(command==SSH_MSG_USERAUTH_BANNER){ - buf.getInt(); buf.getByte(); buf.getByte(); - byte[] _message=buf.getString(); - byte[] lang=buf.getString(); - String message=Util.byte2str(_message); - if(userinfo!=null){ - userinfo.showMessage(message); - } - continue loop1; - } - else{ - //System.err.println("USERAUTH fail ("+command+")"); - //throw new JSchException("USERAUTH fail ("+command+")"); - if(session.getLogger().isEnabled(Logger.DEBUG)){ - session.getLogger().log(Logger.DEBUG, - ipkmethod + " preauth failure command (" + command + ")"); - } - continue loop3; - } - } - } - - if(command!=SSH_MSG_USERAUTH_PK_OK){ - continue iloop; - } - } - - - - if(identity.isEncrypted()) continue; - if(pubkeyblob==null) pubkeyblob=identity.getPublicKeyBlob(); - -//System.err.println("UserAuthPublicKey: pubkeyblob="+pubkeyblob); - - if(pubkeyblob==null) continue; - if(pkmethodsuccesses==null) pkmethodsuccesses=ipkmethods; - - loop4: - for(String pkmethodsuccess : pkmethodsuccesses){ - if(not_available_pks.contains(pkmethodsuccess) && !(identity instanceof AgentIdentity)){ - if(session.getLogger().isEnabled(Logger.DEBUG)){ - session.getLogger().log(Logger.DEBUG, - pkmethodsuccess+" not available for identity "+identity.getName()); - } - continue loop4; - } - - // send - // byte SSH_MSG_USERAUTH_REQUEST(50) - // string user name - // string service name ("ssh-connection") - // string "publickey" - // boolen TRUE - // string public key algorithm name - // string public key blob - // string signature - packet.reset(); - buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST); - buf.putString(_username); - buf.putString(Util.str2byte("ssh-connection")); - buf.putString(Util.str2byte("publickey")); - buf.putByte((byte)1); - buf.putString(Util.str2byte(pkmethodsuccess)); - buf.putString(pubkeyblob); - -// byte[] tmp=new byte[buf.index-5]; -// System.arraycopy(buf.buffer, 5, tmp, 0, tmp.length); -// buf.putString(signature); - - byte[] sid=session.getSessionId(); - int sidlen=sid.length; - byte[] tmp=new byte[4+sidlen+buf.index-5]; - tmp[0]=(byte)(sidlen>>>24); - tmp[1]=(byte)(sidlen>>>16); - tmp[2]=(byte)(sidlen>>>8); - tmp[3]=(byte)(sidlen); - System.arraycopy(sid, 0, tmp, 4, sidlen); - System.arraycopy(buf.buffer, 5, tmp, 4+sidlen, buf.index-5); - byte[] signature=identity.getSignature(tmp, pkmethodsuccess); - if(signature==null){ // for example, too long key length. - if(session.getLogger().isEnabled(Logger.DEBUG)){ - session.getLogger().log(Logger.DEBUG, - pkmethodsuccess + " signature failure"); - } - continue loop4; - } - buf.putString(signature); - session.write(packet); - - loop2: - while(true){ - buf=session.read(buf); - command=buf.getCommand()&0xff; - - if(command==SSH_MSG_USERAUTH_SUCCESS){ - if(session.getLogger().isEnabled(Logger.DEBUG)){ - session.getLogger().log(Logger.DEBUG, - pkmethodsuccess + " auth success"); - } - return true; - } - else if(command==SSH_MSG_USERAUTH_BANNER){ - buf.getInt(); buf.getByte(); buf.getByte(); - byte[] _message=buf.getString(); - byte[] lang=buf.getString(); - String message=Util.byte2str(_message); - if(userinfo!=null){ - userinfo.showMessage(message); - } - continue loop2; - } - else if(command==SSH_MSG_USERAUTH_FAILURE){ - buf.getInt(); buf.getByte(); buf.getByte(); - byte[] foo=buf.getString(); - int partial_success=buf.getByte(); - //System.err.println(new String(foo)+ - // " partial_success:"+(partial_success!=0)); - if(partial_success!=0){ - throw new JSchPartialAuthException(Util.byte2str(foo)); - } - session.auth_failures++; - if(session.getLogger().isEnabled(Logger.DEBUG)){ - session.getLogger().log(Logger.DEBUG, - pkmethodsuccess + " auth failure"); - } - break loop2; - } - //System.err.println("USERAUTH fail ("+command+")"); - //throw new JSchException("USERAUTH fail ("+command+")"); - if(session.getLogger().isEnabled(Logger.DEBUG)){ - session.getLogger().log(Logger.DEBUG, - pkmethodsuccess + " auth failure command (" + command +")"); - } - break loop2; - } - } - } - return false; - } - - private void decryptKey(Session session, Identity identity) throws JSchException { - byte[] passphrase=null; - int count=5; - while(true){ - if((identity.isEncrypted() && passphrase==null)){ - if(userinfo==null) throw new JSchException("USERAUTH fail"); - if(identity.isEncrypted() && - !userinfo.promptPassphrase("Passphrase for "+identity.getName())){ - throw new JSchAuthCancelException("publickey"); - //throw new JSchException("USERAUTH cancel"); - //break; - } - String _passphrase=userinfo.getPassphrase(); - if(_passphrase!=null){ - passphrase= Util.str2byte(_passphrase); - } - } - - if(!identity.isEncrypted() || passphrase!=null){ - if(identity.setPassphrase(passphrase)){ - if(passphrase!=null && - (session.getIdentityRepository() instanceof IdentityRepositoryWrapper)){ - ((IdentityRepositoryWrapper)session.getIdentityRepository()).check(); - } - break; - } - } - Util.bzero(passphrase); - passphrase=null; - count--; - if(count==0)break; - } - - Util.bzero(passphrase); - passphrase=null; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserInfo.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserInfo.java deleted file mode 100644 index 73fe5612..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserInfo.java +++ /dev/null @@ -1,39 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; - -public interface UserInfo{ - String getPassphrase(); - String getPassword(); - boolean promptPassword(String message); - boolean promptPassphrase(String message); - boolean promptYesNo(String message); - void showMessage(String message); -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Util.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Util.java deleted file mode 100644 index dcfd4b67..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Util.java +++ /dev/null @@ -1,569 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch; -import java.net.Socket; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.Vector; - -class Util{ - - private static final byte[] b64 =Util.str2byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="); - private static byte val(byte foo){ - if(foo == '=') return 0; - for(int j=0; j>>4)); - if(buf[i+2]==(byte)'='){ j++; break;} - foo[j+1]=(byte)(((val(buf[i+1])&0x0f)<<4)|((val(buf[i+2])&0x3c)>>>2)); - if(buf[i+3]==(byte)'='){ j+=2; break;} - foo[j+2]=(byte)(((val(buf[i+2])&0x03)<<6)|(val(buf[i+3])&0x3f)); - j+=3; - } - byte[] bar=new byte[j]; - System.arraycopy(foo, 0, bar, 0, j); - return bar; - } - catch(ArrayIndexOutOfBoundsException e) { - throw new JSchException("fromBase64: invalid base64 data", e); - } - } - static byte[] toBase64(byte[] buf, int start, int length, boolean include_pad){ - - byte[] tmp=new byte[length*2]; - int i,j,k; - - int foo=(length/3)*3+start; - i=0; - for(j=start; j>>2)&0x3f; - tmp[i++]=b64[k]; - k=(buf[j]&0x03)<<4|(buf[j+1]>>>4)&0x0f; - tmp[i++]=b64[k]; - k=(buf[j+1]&0x0f)<<2|(buf[j+2]>>>6)&0x03; - tmp[i++]=b64[k]; - k=buf[j+2]&0x3f; - tmp[i++]=b64[k]; - } - - foo=(start+length)-foo; - if(foo==1){ - k=(buf[j]>>>2)&0x3f; - tmp[i++]=b64[k]; - k=((buf[j]&0x03)<<4)&0x3f; - tmp[i++]=b64[k]; - if(include_pad){ - tmp[i++]=(byte)'='; - tmp[i++]=(byte)'='; - } - } - else if(foo==2){ - k=(buf[j]>>>2)&0x3f; - tmp[i++]=b64[k]; - k=(buf[j]&0x03)<<4|(buf[j+1]>>>4)&0x0f; - tmp[i++]=b64[k]; - k=((buf[j+1]&0x0f)<<2)&0x3f; - tmp[i++]=b64[k]; - if(include_pad){ - tmp[i++]=(byte)'='; - } - } - byte[] bar=new byte[i]; - System.arraycopy(tmp, 0, bar, 0, i); - return bar; - -// return sun.misc.BASE64Encoder().encode(buf); - } - - static String[] split(String foo, String split){ - if(foo==null) - return null; - byte[] buf=Util.str2byte(foo); - Vector bar=new Vector<>(); - int start=0; - int index; - while(true){ - index=foo.indexOf(split, start); - if(index>=0){ - bar.addElement(Util.byte2str(buf, start, index-start)); - start=index+1; - continue; - } - bar.addElement(Util.byte2str(buf, start, buf.length-start)); - break; - } - String[] result=new String[bar.size()]; - for(int i=0; i0 && name[0]=='.'){ - if(pattern.length>0 && pattern[0]=='.'){ - if(pattern.length==2 && pattern[1]=='*') return true; - return glob(pattern, pattern_index+1, name, name_index+1); - } - return false; - } - return glob(pattern, pattern_index, name, name_index); - } - static private boolean glob(byte[] pattern, int pattern_index, - byte[] name, int name_index){ - //System.err.println("glob: "+new String(pattern)+", "+pattern_index+" "+new String(name)+", "+name_index); - - int patternlen=pattern.length; - if(patternlen==0) - return false; - - int namelen=name.length; - int i=pattern_index; - int j=name_index; - - while(i>>4)&0xf]); - sb.append(chars[(bar)&0xf]); - if(i+1 { - sockp[0]=null; - try{ - sockp[0]=new Socket(_host, _port); - } - catch(Exception e){ - ee[0]=e; - if(sockp[0]!=null && sockp[0].isConnected()){ - try{ - sockp[0].close(); - } - catch(Exception eee){} - } - sockp[0]=null; - } - }); - tmp.setName("Opening Socket "+host); - tmp.start(); - try{ - tmp.join(timeout); - message="timeout: "; - } - catch(InterruptedException eee){ - } - if(sockp[0]!=null && sockp[0].isConnected()){ - socket=sockp[0]; - } - else{ - message+="socket is not established"; - if(ee[0]!=null){ - message=ee[0].toString(); - } - tmp.interrupt(); - tmp=null; - throw new JSchException(message, ee[0]); - } - return socket; - } - - static byte[] str2byte(String str, Charset encoding){ - if(str==null) - return null; - return str.getBytes(encoding); - } - - static byte[] str2byte(String str){ - return str2byte(str, StandardCharsets.UTF_8); - } - - static String byte2str(byte[] str, Charset encoding){ - return byte2str(str, 0, str.length, encoding); - } - - static String byte2str(byte[] str, int s, int l, Charset encoding){ - return new String(str, s, l, encoding); - } - - static String byte2str(byte[] str){ - return byte2str(str, 0, str.length, StandardCharsets.UTF_8); - } - - static String byte2str(byte[] str, int s, int l){ - return byte2str(str, s, l, StandardCharsets.UTF_8); - } - - static String toHex(byte[] str){ - StringBuilder sb = new StringBuilder(); - for(int i = 0; i>>8); - bar[j++]=(byte)foo[i]; - } - } - return bar; - } - */ - static void bzero(byte[] foo){ - if(foo==null) - return; - for(int i=0; i -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, 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.jcraft.jsch.jbcrypt; - -import java.nio.charset.StandardCharsets; -import java.security.DigestException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; - -/** - * BCrypt implements OpenBSD-style Blowfish password hashing using - * the scheme described in "A Future-Adaptable Password Scheme" by - * Niels Provos and David Mazieres. - *

    - * This password hashing system tries to thwart off-line password - * cracking using a computationally-intensive hashing algorithm, - * based on Bruce Schneier's Blowfish cipher. The work factor of - * the algorithm is parameterised, so it can be increased as - * computers get faster. - *

    - * Usage is really simple. To hash a password for the first time, - * call the hashpw method with a random salt, like this: - *

    - * - * String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt());
    - *
    - *

    - * To check whether a plaintext password matches one that has been - * hashed previously, use the checkpw method: - *

    - * - * if (BCrypt.checkpw(candidate_password, stored_hash))
    - *     System.out.println("It matches");
    - * else
    - *     System.out.println("It does not match");
    - *
    - *

    - * The gensalt() method takes an optional parameter (log_rounds) - * that determines the computational complexity of the hashing: - *

    - * - * String strong_salt = BCrypt.gensalt(10)
    - * String stronger_salt = BCrypt.gensalt(12)
    - *
    - *

    - * The amount of work increases exponentially (2**log_rounds), so - * each increment is twice as much work. The default log_rounds is - * 10, and the valid range is 4 to 30. - * - * @author Damien Miller - * @version 0.2 - */ -public class BCrypt { - // BCrypt parameters - private static final int GENSALT_DEFAULT_LOG2_ROUNDS = 10; - private static final int BCRYPT_SALT_LEN = 16; - - // Blowfish parameters - private static final int BLOWFISH_NUM_ROUNDS = 16; - - // Initial contents of key schedule - private static final int P_orig[] = { - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, - 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, - 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, - 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, - 0x9216d5d9, 0x8979fb1b - }; - private static final int S_orig[] = { - 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, - 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, - 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, - 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, - 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, - 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, - 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, - 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, - 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, - 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, - 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, - 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, - 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, - 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, - 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, - 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, - 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, - 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, - 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, - 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, - 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, - 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, - 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, - 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, - 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, - 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, - 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, - 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, - 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, - 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, - 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, - 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, - 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, - 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, - 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, - 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, - 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, - 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, - 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, - 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, - 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, - 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, - 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, - 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, - 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, - 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, - 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, - 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, - 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, - 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, - 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, - 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, - 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, - 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, - 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, - 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, - 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, - 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, - 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, - 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, - 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, - 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, - 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, - 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, - 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, - 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, - 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, - 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, - 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, - 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, - 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, - 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, - 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, - 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, - 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, - 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, - 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, - 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, - 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, - 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, - 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, - 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, - 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, - 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, - 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, - 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, - 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, - 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, - 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, - 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, - 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, - 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, - 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, - 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, - 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, - 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, - 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, - 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, - 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, - 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, - 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, - 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, - 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, - 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, - 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, - 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, - 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, - 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, - 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, - 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, - 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, - 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, - 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, - 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, - 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, - 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, - 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, - 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, - 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, - 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, - 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, - 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, - 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, - 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, - 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, - 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, - 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, - 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, - 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, - 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, - 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, - 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, - 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, - 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, - 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, - 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, - 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, - 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, - 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, - 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, - 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, - 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, - 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, - 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, - 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, - 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, - 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, - 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, - 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, - 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, - 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, - 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, - 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, - 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, - 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, - 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, - 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, - 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, - 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, - 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, - 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, - 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, - 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, - 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, - 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, - 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, - 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, - 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, - 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, - 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, - 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, - 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, - 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, - 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, - 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, - 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, - 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, - 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, - 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, - 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, - 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, - 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, - 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, - 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, - 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, - 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0, - 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, - 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, - 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, - 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, - 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, - 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, - 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, - 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, - 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, - 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, - 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, - 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, - 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, - 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, - 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, - 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, - 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, - 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, - 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, - 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, - 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, - 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, - 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, - 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, - 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, - 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, - 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, - 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, - 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, - 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, - 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, - 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, - 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, - 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, - 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, - 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, - 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, - 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, - 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, - 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, - 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, - 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, - 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, - 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, - 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, - 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, - 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, - 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, - 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, - 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, - 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, - 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, - 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, - 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, - 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, - 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, - 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, - 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, - 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, - 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, - 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, - 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 - }; - - // OpenBSD IV: "OxychromaticBlowfishSwatDynamite" in big endian - private static final int[] openbsd_iv = new int[] { - 0x4f787963, 0x68726f6d, 0x61746963, 0x426c6f77, - 0x66697368, 0x53776174, 0x44796e61, 0x6d697465, - }; - - // bcrypt IV: "OrpheanBeholderScryDoubt". The C implementation calls - // this "ciphertext", but it is really plaintext or an IV. We keep - // the name to make code comparison easier. - static private final int bf_crypt_ciphertext[] = { - 0x4f727068, 0x65616e42, 0x65686f6c, - 0x64657253, 0x63727944, 0x6f756274 - }; - - // Table for Base64 encoding - static private final char base64_code[] = { - '.', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', - 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', - 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', - '6', '7', '8', '9' - }; - - // Table for Base64 decoding - static private final byte index_64[] = { - -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, -1, -1, -1, 0, 1, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, - -1, -1, -1, -1, -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, 26, 27, - -1, -1, -1, -1, -1, -1, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, -1, -1, -1, -1, -1 - }; - - // Expanded Blowfish key - private int P[]; - private int S[]; - - /** - * Encode a byte array using bcrypt's slightly-modified base64 - * encoding scheme. Note that this is *not* compatible with - * the standard MIME-base64 encoding. - * - * @param d the byte array to encode - * @param len the number of bytes to encode - * @return base64-encoded string - * @exception IllegalArgumentException if the length is invalid - */ - private static String encode_base64(byte d[], int len) - throws IllegalArgumentException { - int off = 0; - StringBuilder rs = new StringBuilder(); - int c1, c2; - - if (len <= 0 || len > d.length) - throw new IllegalArgumentException ("Invalid len"); - - while (off < len) { - c1 = d[off++] & 0xff; - rs.append(base64_code[(c1 >> 2) & 0x3f]); - c1 = (c1 & 0x03) << 4; - if (off >= len) { - rs.append(base64_code[c1 & 0x3f]); - break; - } - c2 = d[off++] & 0xff; - c1 |= (c2 >> 4) & 0x0f; - rs.append(base64_code[c1 & 0x3f]); - c1 = (c2 & 0x0f) << 2; - if (off >= len) { - rs.append(base64_code[c1 & 0x3f]); - break; - } - c2 = d[off++] & 0xff; - c1 |= (c2 >> 6) & 0x03; - rs.append(base64_code[c1 & 0x3f]); - rs.append(base64_code[c2 & 0x3f]); - } - return rs.toString(); - } - - /** - * Look up the 3 bits base64-encoded by the specified character, - * range-checking againt conversion table - * @param x the base64-encoded value - * @return the decoded value of x - */ - private static byte char64(char x) { - if ((int)x < 0 || (int)x > index_64.length) - return -1; - return index_64[(int)x]; - } - - /** - * Decode a string encoded using bcrypt's base64 scheme to a - * byte array. Note that this is *not* compatible with - * the standard MIME-base64 encoding. - * @param s the string to decode - * @param maxolen the maximum number of bytes to decode - * @return an array containing the decoded bytes - * @throws IllegalArgumentException if maxolen is invalid - */ - private static byte[] decode_base64(String s, int maxolen) - throws IllegalArgumentException { - StringBuilder rs = new StringBuilder(); - int off = 0, slen = s.length(), olen = 0; - byte ret[]; - byte c1, c2, c3, c4, o; - - if (maxolen <= 0) - throw new IllegalArgumentException ("Invalid maxolen"); - - while (off < slen - 1 && olen < maxolen) { - c1 = char64(s.charAt(off++)); - c2 = char64(s.charAt(off++)); - if (c1 == -1 || c2 == -1) - break; - o = (byte)(c1 << 2); - o |= (c2 & 0x30) >> 4; - rs.append((char)o); - if (++olen >= maxolen || off >= slen) - break; - c3 = char64(s.charAt(off++)); - if (c3 == -1) - break; - o = (byte)((c2 & 0x0f) << 4); - o |= (c3 & 0x3c) >> 2; - rs.append((char)o); - if (++olen >= maxolen || off >= slen) - break; - c4 = char64(s.charAt(off++)); - o = (byte)((c3 & 0x03) << 6); - o |= c4; - rs.append((char)o); - ++olen; - } - - ret = new byte[olen]; - for (off = 0; off < olen; off++) - ret[off] = (byte)rs.charAt(off); - return ret; - } - - /** - * Blowfish encipher a single 64-bit block encoded as - * two 32-bit halves - * @param lr an array containing the two 32-bit half blocks - * @param off the position in the array of the blocks - */ - private final void encipher(int lr[], int off) { - int i, n, l = lr[off], r = lr[off + 1]; - - l ^= P[0]; - for (i = 0; i <= BLOWFISH_NUM_ROUNDS - 2;) { - // Feistel substitution on left word - n = S[(l >> 24) & 0xff]; - n += S[0x100 | ((l >> 16) & 0xff)]; - n ^= S[0x200 | ((l >> 8) & 0xff)]; - n += S[0x300 | (l & 0xff)]; - r ^= n ^ P[++i]; - - // Feistel substitution on right word - n = S[(r >> 24) & 0xff]; - n += S[0x100 | ((r >> 16) & 0xff)]; - n ^= S[0x200 | ((r >> 8) & 0xff)]; - n += S[0x300 | (r & 0xff)]; - l ^= n ^ P[++i]; - } - lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1]; - lr[off + 1] = l; - } - - /** - * Cycically extract a word of key material - * @param data the string to extract the data from - * @param offp a "pointer" (as a one-entry array) to the - * current offset into data - * @return the next word of material from data - */ - private static int streamtoword(byte data[], int offp[]) { - int i; - int word = 0; - int off = offp[0]; - - for (i = 0; i < 4; i++) { - word = (word << 8) | (data[off] & 0xff); - off = (off + 1) % data.length; - } - - offp[0] = off; - return word; - } - - /** - * Initialise the Blowfish key schedule - */ - private void init_key() { - P = P_orig.clone(); - S = S_orig.clone(); - } - - /** - * Key the Blowfish cipher - * @param key an array containing the key - */ - private void key(byte key[]) { - int i; - int koffp[] = { 0 }; - int lr[] = { 0, 0 }; - int plen = P.length, slen = S.length; - - for (i = 0; i < plen; i++) - P[i] = P[i] ^ streamtoword(key, koffp); - - for (i = 0; i < plen; i += 2) { - encipher(lr, 0); - P[i] = lr[0]; - P[i + 1] = lr[1]; - } - - for (i = 0; i < slen; i += 2) { - encipher(lr, 0); - S[i] = lr[0]; - S[i + 1] = lr[1]; - } - } - - /** - * Perform the "enhanced key schedule" step described by - * Provos and Mazieres in "A Future-Adaptable Password Scheme" - * http://www.openbsd.org/papers/bcrypt-paper.ps - * @param data salt information - * @param key password information - */ - private void ekskey(byte data[], byte key[]) { - int i; - int koffp[] = { 0 }, doffp[] = { 0 }; - int lr[] = { 0, 0 }; - int plen = P.length, slen = S.length; - - for (i = 0; i < plen; i++) - P[i] = P[i] ^ streamtoword(key, koffp); - - for (i = 0; i < plen; i += 2) { - lr[0] ^= streamtoword(data, doffp); - lr[1] ^= streamtoword(data, doffp); - encipher(lr, 0); - P[i] = lr[0]; - P[i + 1] = lr[1]; - } - - for (i = 0; i < slen; i += 2) { - lr[0] ^= streamtoword(data, doffp); - lr[1] ^= streamtoword(data, doffp); - encipher(lr, 0); - S[i] = lr[0]; - S[i + 1] = lr[1]; - } - } - - /** - * Compatibility with new OpenBSD function. - */ - public void hash(byte[] hpass, byte[] hsalt, byte[] output) { - init_key(); - ekskey(hsalt, hpass); - for (int i = 0; i < 64; i++) { - key(hsalt); - key(hpass); - } - - int[] buf = new int[openbsd_iv.length]; - System.arraycopy(openbsd_iv, 0, buf, 0, openbsd_iv.length); - for (int i = 0; i < 8; i += 2) { - for (int j = 0; j < 64; j++) { - encipher(buf, i); - } - } - - for (int i = 0, j = 0; i < buf.length; i++) { - // Output of this is little endian - output[j++] = (byte)(buf[i] & 0xff); - output[j++] = (byte)((buf[i] >> 8) & 0xff); - output[j++] = (byte)((buf[i] >> 16) & 0xff); - output[j++] = (byte)((buf[i] >> 24) & 0xff); - } - } - - /** - * Compatibility with new OpenBSD function. - */ - public void pbkdf(byte[] password, byte[] salt, int rounds, byte[] output) { - try { - MessageDigest sha512 = MessageDigest.getInstance("SHA-512"); - - int nblocks = (output.length + 31) / 32; - byte[] hpass = sha512.digest(password); - - byte[] hsalt = new byte[64]; - byte[] block_b = new byte[4]; - byte[] out = new byte[32]; - byte[] tmp = new byte[32]; - for (int block = 1; block <= nblocks; block++) { - // Block count is in big endian - block_b[0] = (byte) ((block >> 24) & 0xFF); - block_b[1] = (byte) ((block >> 16) & 0xFF); - block_b[2] = (byte) ((block >> 8) & 0xFF); - block_b[3] = (byte) (block & 0xFF); - - sha512.reset(); - sha512.update(salt); - sha512.update(block_b); - sha512.digest(hsalt, 0, hsalt.length); - - hash(hpass, hsalt, out); - System.arraycopy(out, 0, tmp, 0, out.length); - - for (int round = 1; round < rounds; round++) { - sha512.reset(); - sha512.update(tmp); - sha512.digest(hsalt, 0, hsalt.length); - - hash(hpass, hsalt, tmp); - - for (int i = 0; i < tmp.length; i++) { - out[i] ^= tmp[i]; - } - } - - for (int i = 0; i < out.length; i++) { - int idx = i * nblocks + (block - 1); - if (idx < output.length) { - output[idx] = out[i]; - } - } - } - } catch (DigestException e) { - throw new RuntimeException(e); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } - } - - /** - * Perform the central password hashing step in the - * bcrypt scheme - * @param password the password to hash - * @param salt the binary salt to hash with the password - * @param log_rounds the binary logarithm of the number - * of rounds of hashing to apply - * @param cdata the plaintext to encrypt - * @return an array containing the binary hashed password - */ - public byte[] crypt_raw(byte password[], byte salt[], int log_rounds, - int cdata[]) { - int rounds, i, j; - int clen = cdata.length; - byte ret[]; - - if (log_rounds < 4 || log_rounds > 30) - throw new IllegalArgumentException ("Bad number of rounds"); - rounds = 1 << log_rounds; - if (salt.length != BCRYPT_SALT_LEN) - throw new IllegalArgumentException ("Bad salt length"); - - init_key(); - ekskey(salt, password); - for (i = 0; i != rounds; i++) { - key(password); - key(salt); - } - - for (i = 0; i < 64; i++) { - for (j = 0; j < (clen >> 1); j++) - encipher(cdata, j << 1); - } - - ret = new byte[clen * 4]; - for (i = 0, j = 0; i < clen; i++) { - ret[j++] = (byte)((cdata[i] >> 24) & 0xff); - ret[j++] = (byte)((cdata[i] >> 16) & 0xff); - ret[j++] = (byte)((cdata[i] >> 8) & 0xff); - ret[j++] = (byte)(cdata[i] & 0xff); - } - return ret; - } - - /** - * Hash a password using the OpenBSD bcrypt scheme - * @param password the password to hash - * @param salt the salt to hash with (perhaps generated - * using BCrypt.gensalt) - * @return the hashed password - */ - public static String hashpw(String password, String salt) { - BCrypt B; - String real_salt; - byte passwordb[], saltb[], hashed[]; - char minor = (char)0; - int rounds, off = 0; - StringBuilder rs = new StringBuilder(); - - if (salt.charAt(0) != '$' || salt.charAt(1) != '2') - throw new IllegalArgumentException ("Invalid salt version"); - if (salt.charAt(2) == '$') - off = 3; - else { - minor = salt.charAt(2); - if (minor != 'a' || salt.charAt(3) != '$') - throw new IllegalArgumentException ("Invalid salt revision"); - off = 4; - } - - // Extract number of rounds - if (salt.charAt(off + 2) > '$') - throw new IllegalArgumentException ("Missing salt rounds"); - rounds = Integer.parseInt(salt.substring(off, off + 2)); - - real_salt = salt.substring(off + 3, off + 25); - passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes(StandardCharsets.UTF_8); - - saltb = decode_base64(real_salt, BCRYPT_SALT_LEN); - - B = new BCrypt(); - hashed = B.crypt_raw(passwordb, saltb, rounds, - bf_crypt_ciphertext.clone()); - - rs.append("$2"); - if (minor >= 'a') - rs.append(minor); - rs.append("$"); - if (rounds < 10) - rs.append("0"); - if (rounds > 30) { - throw new IllegalArgumentException( - "rounds exceeds maximum (30)"); - } - rs.append(Integer.toString(rounds)); - rs.append("$"); - rs.append(encode_base64(saltb, saltb.length)); - rs.append(encode_base64(hashed, - bf_crypt_ciphertext.length * 4 - 1)); - return rs.toString(); - } - - /** - * Generate a salt for use with the BCrypt.hashpw() method - * @param log_rounds the log2 of the number of rounds of - * hashing to apply - the work factor therefore increases as - * 2**log_rounds. - * @param random an instance of SecureRandom to use - * @return an encoded salt value - */ - public static String gensalt(int log_rounds, SecureRandom random) { - StringBuilder rs = new StringBuilder(); - byte rnd[] = new byte[BCRYPT_SALT_LEN]; - - random.nextBytes(rnd); - - rs.append("$2a$"); - if (log_rounds < 10) - rs.append("0"); - if (log_rounds > 30) { - throw new IllegalArgumentException( - "log_rounds exceeds maximum (30)"); - } - rs.append(Integer.toString(log_rounds)); - rs.append("$"); - rs.append(encode_base64(rnd, rnd.length)); - return rs.toString(); - } - - /** - * Generate a salt for use with the BCrypt.hashpw() method - * @param log_rounds the log2 of the number of rounds of - * hashing to apply - the work factor therefore increases as - * 2**log_rounds. - * @return an encoded salt value - */ - public static String gensalt(int log_rounds) { - return gensalt(log_rounds, new SecureRandom()); - } - - /** - * Generate a salt for use with the BCrypt.hashpw() method, - * selecting a reasonable default for the number of hashing - * rounds to apply - * @return an encoded salt value - */ - public static String gensalt() { - return gensalt(GENSALT_DEFAULT_LOG2_ROUNDS); - } - - /** - * Check that a plaintext password matches a previously hashed - * one - * @param plaintext the plaintext password to verify - * @param hashed the previously-hashed password - * @return true if the passwords match, false otherwise - */ - public static boolean checkpw(String plaintext, String hashed) { - String try_pw = hashpw(plaintext, hashed); - byte hashed_bytes[] = hashed.getBytes(StandardCharsets.UTF_8); - byte try_bytes[] = try_pw.getBytes(StandardCharsets.UTF_8); - if (hashed_bytes.length != try_bytes.length) - return false; - byte ret = 0; - for (int i = 0; i < try_bytes.length; i++) - ret |= hashed_bytes[i] ^ try_bytes[i]; - return ret == 0; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128CBC.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128CBC.java deleted file mode 100644 index b8ea67bc..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128CBC.java +++ /dev/null @@ -1,77 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import com.jcraft.jsch.Cipher; -import javax.crypto.spec.*; - -public class AES128CBC implements Cipher{ - private static final int ivsize=16; - private static final int bsize=16; - private javax.crypto.Cipher cipher; - @Override - public int getIVSize(){return ivsize;} - @Override - public int getBlockSize(){return bsize;} - @Override - public void init(int mode, byte[] key, byte[] iv) throws Exception{ - String pad="NoPadding"; - byte[] tmp; - if(iv.length>ivsize){ - tmp=new byte[ivsize]; - System.arraycopy(iv, 0, tmp, 0, tmp.length); - iv=tmp; - } - if(key.length>bsize){ - tmp=new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, tmp.length); - key=tmp; - } - - try{ - SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); - cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad); - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - keyspec, new IvParameterSpec(iv)); - } - catch(Exception e){ - cipher=null; - throw e; - } - } - @Override - public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ - cipher.update(foo, s1, len, bar, s2); - } - @Override - public boolean isCBC(){return true; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128CTR.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128CTR.java deleted file mode 100644 index 950b08d9..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128CTR.java +++ /dev/null @@ -1,77 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import com.jcraft.jsch.Cipher; -import javax.crypto.spec.*; - -public class AES128CTR implements Cipher{ - private static final int ivsize=16; - private static final int bsize=16; - private javax.crypto.Cipher cipher; - @Override - public int getIVSize(){return ivsize;} - @Override - public int getBlockSize(){return bsize;} - @Override - public void init(int mode, byte[] key, byte[] iv) throws Exception{ - String pad="NoPadding"; - byte[] tmp; - if(iv.length>ivsize){ - tmp=new byte[ivsize]; - System.arraycopy(iv, 0, tmp, 0, tmp.length); - iv=tmp; - } - if(key.length>bsize){ - tmp=new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, tmp.length); - key=tmp; - } - - try{ - SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); - cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad); - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - keyspec, new IvParameterSpec(iv)); - } - catch(Exception e){ - cipher=null; - throw e; - } - } - @Override - public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ - cipher.update(foo, s1, len, bar, s2); - } - @Override - public boolean isCBC(){return false; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128GCM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128GCM.java deleted file mode 100644 index d10df726..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128GCM.java +++ /dev/null @@ -1,37 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class AES128GCM extends AESGCM{ - //Actually the key size, not block size - private static final int bsize=16; - @Override - public int getBlockSize(){return bsize;} -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES192CBC.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES192CBC.java deleted file mode 100644 index 24d2abd5..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES192CBC.java +++ /dev/null @@ -1,76 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import com.jcraft.jsch.Cipher; -import javax.crypto.spec.*; - -public class AES192CBC implements Cipher{ - private static final int ivsize=16; - private static final int bsize=24; - private javax.crypto.Cipher cipher; - @Override - public int getIVSize(){return ivsize;} - @Override - public int getBlockSize(){return bsize;} - @Override - public void init(int mode, byte[] key, byte[] iv) throws Exception{ - String pad="NoPadding"; - byte[] tmp; - if(iv.length>ivsize){ - tmp=new byte[ivsize]; - System.arraycopy(iv, 0, tmp, 0, tmp.length); - iv=tmp; - } - if(key.length>bsize){ - tmp=new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, tmp.length); - key=tmp; - } - try{ - SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); - cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad); - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - keyspec, new IvParameterSpec(iv)); - } - catch(Exception e){ - cipher=null; - throw e; - } - } - @Override - public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ - cipher.update(foo, s1, len, bar, s2); - } - @Override - public boolean isCBC(){return true; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES192CTR.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES192CTR.java deleted file mode 100644 index 339f5832..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES192CTR.java +++ /dev/null @@ -1,76 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import com.jcraft.jsch.Cipher; -import javax.crypto.spec.*; - -public class AES192CTR implements Cipher{ - private static final int ivsize=16; - private static final int bsize=24; - private javax.crypto.Cipher cipher; - @Override - public int getIVSize(){return ivsize;} - @Override - public int getBlockSize(){return bsize;} - @Override - public void init(int mode, byte[] key, byte[] iv) throws Exception{ - String pad="NoPadding"; - byte[] tmp; - if(iv.length>ivsize){ - tmp=new byte[ivsize]; - System.arraycopy(iv, 0, tmp, 0, tmp.length); - iv=tmp; - } - if(key.length>bsize){ - tmp=new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, tmp.length); - key=tmp; - } - try{ - SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); - cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad); - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - keyspec, new IvParameterSpec(iv)); - } - catch(Exception e){ - cipher=null; - throw e; - } - } - @Override - public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ - cipher.update(foo, s1, len, bar, s2); - } - @Override - public boolean isCBC(){return false; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256CBC.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256CBC.java deleted file mode 100644 index dd706046..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256CBC.java +++ /dev/null @@ -1,76 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import com.jcraft.jsch.Cipher; -import javax.crypto.spec.*; - -public class AES256CBC implements Cipher{ - private static final int ivsize=16; - private static final int bsize=32; - private javax.crypto.Cipher cipher; - @Override - public int getIVSize(){return ivsize;} - @Override - public int getBlockSize(){return bsize;} - @Override - public void init(int mode, byte[] key, byte[] iv) throws Exception{ - String pad="NoPadding"; - byte[] tmp; - if(iv.length>ivsize){ - tmp=new byte[ivsize]; - System.arraycopy(iv, 0, tmp, 0, tmp.length); - iv=tmp; - } - if(key.length>bsize){ - tmp=new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, tmp.length); - key=tmp; - } - try{ - SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); - cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad); - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - keyspec, new IvParameterSpec(iv)); - } - catch(Exception e){ - cipher=null; - throw e; - } - } - @Override - public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ - cipher.update(foo, s1, len, bar, s2); - } - @Override - public boolean isCBC(){return true; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256CTR.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256CTR.java deleted file mode 100644 index cff20fcf..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256CTR.java +++ /dev/null @@ -1,76 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import com.jcraft.jsch.Cipher; -import javax.crypto.spec.*; - -public class AES256CTR implements Cipher{ - private static final int ivsize=16; - private static final int bsize=32; - private javax.crypto.Cipher cipher; - @Override - public int getIVSize(){return ivsize;} - @Override - public int getBlockSize(){return bsize;} - @Override - public void init(int mode, byte[] key, byte[] iv) throws Exception{ - String pad="NoPadding"; - byte[] tmp; - if(iv.length>ivsize){ - tmp=new byte[ivsize]; - System.arraycopy(iv, 0, tmp, 0, tmp.length); - iv=tmp; - } - if(key.length>bsize){ - tmp=new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, tmp.length); - key=tmp; - } - try{ - SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); - cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad); - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - keyspec, new IvParameterSpec(iv)); - } - catch(Exception e){ - cipher=null; - throw e; - } - } - @Override - public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ - cipher.update(foo, s1, len, bar, s2); - } - @Override - public boolean isCBC(){return false; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256GCM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256GCM.java deleted file mode 100644 index d61a6142..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256GCM.java +++ /dev/null @@ -1,37 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class AES256GCM extends AESGCM{ - //Actually the key size, not block size - private static final int bsize=32; - @Override - public int getBlockSize(){return bsize;} -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AESGCM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AESGCM.java deleted file mode 100644 index de33b7c4..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AESGCM.java +++ /dev/null @@ -1,103 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import com.jcraft.jsch.Cipher; -import java.nio.ByteBuffer; -import javax.crypto.spec.*; - -abstract class AESGCM implements Cipher{ - //Actually the block size, not IV size - private static final int ivsize=16; - private static final int tagsize=16; - private javax.crypto.Cipher cipher; - private SecretKeySpec keyspec; - private int mode; - private ByteBuffer iv; - private long initcounter; - @Override - public int getIVSize(){return ivsize;} - @Override - public int getTagSize(){return tagsize;} - @Override - public void init(int mode, byte[] key, byte[] iv) throws Exception{ - String pad="NoPadding"; - byte[] tmp; - if(iv.length>12){ - tmp=new byte[12]; - System.arraycopy(iv, 0, tmp, 0, tmp.length); - iv=tmp; - } - int bsize=getBlockSize(); - if(key.length>bsize){ - tmp=new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, tmp.length); - key=tmp; - } - this.mode=((mode==ENCRYPT_MODE)? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE); - this.iv=ByteBuffer.wrap(iv); - this.initcounter=this.iv.getLong(4); - try{ - keyspec=new SecretKeySpec(key, "AES"); - cipher=javax.crypto.Cipher.getInstance("AES/GCM/"+pad); - cipher.init(this.mode, keyspec, new GCMParameterSpec(tagsize*8,iv)); - } - catch(Exception e){ - cipher=null; - keyspec=null; - this.iv=null; - throw e; - } - } - @Override - public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ - cipher.update(foo, s1, len, bar, s2); - } - @Override - public void updateAAD(byte[] foo, int s1, int len) throws Exception{ - cipher.updateAAD(foo, s1, len); - } - @Override - public void doFinal(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ - cipher.doFinal(foo, s1, len, bar, s2); - long newcounter=iv.getLong(4)+1; - if (newcounter == initcounter) { - throw new IllegalStateException("GCM IV would be reused"); - } - iv.putLong(4, newcounter); - cipher.init(mode, keyspec, new GCMParameterSpec(tagsize*8,iv.array())); - } - @Override - public boolean isCBC(){return false; } - @Override - public boolean isAEAD(){return true; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR.java deleted file mode 100644 index 1ca00556..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR.java +++ /dev/null @@ -1,73 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import com.jcraft.jsch.Cipher; -import javax.crypto.*; -import javax.crypto.spec.*; - -public class ARCFOUR implements Cipher{ - private static final int ivsize=8; - private static final int bsize=16; - private javax.crypto.Cipher cipher; - @Override - public int getIVSize(){return ivsize;} - @Override - public int getBlockSize(){return bsize;} - @Override - public void init(int mode, byte[] key, byte[] iv) throws Exception{ - String pad="NoPadding"; - byte[] tmp; - if(key.length>bsize){ - tmp=new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, tmp.length); - key=tmp; - } - - try{ - cipher=javax.crypto.Cipher.getInstance("RC4"); - SecretKeySpec _key = new SecretKeySpec(key, "RC4"); - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - _key); - } - catch(Exception e){ - cipher=null; - throw e; - } - } - @Override - public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ - cipher.update(foo, s1, len, bar, s2); - } - @Override - public boolean isCBC(){return false; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR128.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR128.java deleted file mode 100644 index ebb8d017..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR128.java +++ /dev/null @@ -1,76 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import com.jcraft.jsch.Cipher; -import javax.crypto.*; -import javax.crypto.spec.*; - -public class ARCFOUR128 implements Cipher{ - private static final int ivsize=8; - private static final int bsize=16; - private static final int skip=1536; - private javax.crypto.Cipher cipher; - @Override - public int getIVSize(){return ivsize;} - @Override - public int getBlockSize(){return bsize;} - @Override - public void init(int mode, byte[] key, byte[] iv) throws Exception{ - byte[] tmp; - if(key.length>bsize){ - tmp=new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, tmp.length); - key=tmp; - } - try{ - cipher=javax.crypto.Cipher.getInstance("RC4"); - SecretKeySpec _key = new SecretKeySpec(key, "RC4"); - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - _key); - byte[] foo=new byte[1]; - for(int i=0; ibsize){ - tmp=new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, tmp.length); - key=tmp; - } - try{ - cipher=javax.crypto.Cipher.getInstance("RC4"); - SecretKeySpec _key = new SecretKeySpec(key, "RC4"); - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - _key); - byte[] foo=new byte[1]; - for(int i=0; iivsize){ - tmp=new byte[ivsize]; - System.arraycopy(iv, 0, tmp, 0, tmp.length); - iv=tmp; - } - if(key.length>bsize){ - tmp=new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, tmp.length); - key=tmp; - } - try{ - SecretKeySpec skeySpec = new SecretKeySpec(key, "Blowfish"); - cipher=javax.crypto.Cipher.getInstance("Blowfish/CBC/"+pad); - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - skeySpec, new IvParameterSpec(iv)); - } - catch(Exception e){ - throw e; - } - } - @Override - public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ - cipher.update(foo, s1, len, bar, s2); - } - @Override - public boolean isCBC(){return true; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/BlowfishCTR.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/BlowfishCTR.java deleted file mode 100644 index a0d2051b..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/BlowfishCTR.java +++ /dev/null @@ -1,76 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import com.jcraft.jsch.Cipher; -import javax.crypto.spec.*; - -public class BlowfishCTR implements Cipher{ - private static final int ivsize=8; - private static final int bsize=32; - private javax.crypto.Cipher cipher; - @Override - public int getIVSize(){return ivsize;} - @Override - public int getBlockSize(){return bsize;} - @Override - public void init(int mode, byte[] key, byte[] iv) throws Exception{ - String pad="NoPadding"; -// if(padding) pad="PKCS5Padding"; - byte[] tmp; - if(iv.length>ivsize){ - tmp=new byte[ivsize]; - System.arraycopy(iv, 0, tmp, 0, tmp.length); - iv=tmp; - } - if(key.length>bsize){ - tmp=new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, tmp.length); - key=tmp; - } - try{ - SecretKeySpec skeySpec = new SecretKeySpec(key, "Blowfish"); - cipher=javax.crypto.Cipher.getInstance("Blowfish/CTR/"+pad); - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - skeySpec, new IvParameterSpec(iv)); - } - catch(Exception e){ - throw e; - } - } - @Override - public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ - cipher.update(foo, s1, len, bar, s2); - } - @Override - public boolean isCBC(){return false; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/DH.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/DH.java deleted file mode 100644 index b4690b1f..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/DH.java +++ /dev/null @@ -1,108 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import java.math.BigInteger; -import java.security.*; -import javax.crypto.*; -import javax.crypto.interfaces.*; -import javax.crypto.spec.*; -import com.jcraft.jsch.JSchException; - -public class DH implements com.jcraft.jsch.DH{ - BigInteger p; - BigInteger g; - BigInteger e; // my public key - byte[] e_array; - BigInteger f; // your public key - BigInteger K; // shared secret key - byte[] K_array; - - private KeyPairGenerator myKpairGen; - private KeyAgreement myKeyAgree; - @Override - public void init() throws Exception{ - myKpairGen=KeyPairGenerator.getInstance("DH"); - myKeyAgree=KeyAgreement.getInstance("DH"); - } - @Override - public byte[] getE() throws Exception{ - if(e==null){ - DHParameterSpec dhSkipParamSpec=new DHParameterSpec(p, g); - myKpairGen.initialize(dhSkipParamSpec); - KeyPair myKpair=myKpairGen.generateKeyPair(); - myKeyAgree.init(myKpair.getPrivate()); - e=((DHPublicKey)(myKpair.getPublic())).getY(); - e_array=e.toByteArray(); - } - return e_array; - } - @Override - public byte[] getK() throws Exception{ - if(K==null){ - KeyFactory myKeyFac=KeyFactory.getInstance("DH"); - DHPublicKeySpec keySpec=new DHPublicKeySpec(f, p, g); - PublicKey yourPubKey=myKeyFac.generatePublic(keySpec); - myKeyAgree.doPhase(yourPubKey, true); - byte[] mySharedSecret=myKeyAgree.generateSecret(); - K=new BigInteger(1, mySharedSecret); - K_array=K.toByteArray(); - K_array=mySharedSecret; - } - return K_array; - } - @Override - public void setP(byte[] p){ setP(new BigInteger(1, p)); } - @Override - public void setG(byte[] g){ setG(new BigInteger(1, g)); } - @Override - public void setF(byte[] f){ setF(new BigInteger(1, f)); } - void setP(BigInteger p){this.p=p;} - void setG(BigInteger g){this.g=g;} - void setF(BigInteger f){this.f=f;} - - // e, f must be in [1, p-1]. - @Override - public void checkRange() throws Exception { - /* - checkRange(e); - checkRange(f); - */ - } - - private void checkRange(BigInteger tmp) throws Exception { - BigInteger one = BigInteger.ONE; - BigInteger p_1 = p.subtract(one); - // !(1bsize){ - byte[] tmp = new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, bsize); - key = tmp; - } - SecretKeySpec skey = new SecretKeySpec(key, algorithm); - mac = Mac.getInstance(algorithm); - mac.init(skey); - } - - private final byte[] tmp = new byte[4]; - @Override - public void update(int i){ - tmp[0] = (byte)(i>>>24); - tmp[1] = (byte)(i>>>16); - tmp[2] = (byte)(i>>>8); - tmp[3] = (byte)i; - update(tmp, 0, 4); - } - - @Override - public void update(byte foo[], int s, int l){ - mac.update(foo, s, l); - } - - @Override - public void doFinal(byte[] buf, int offset){ - try{ - mac.doFinal(buf, offset); - } - catch(ShortBufferException e){ - System.err.println(e); - } - } - - @Override - public String getName(){ - return name; - } - - @Override - public boolean isEtM(){ - return etm; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD5.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD5.java deleted file mode 100644 index ca02c1cb..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD5.java +++ /dev/null @@ -1,42 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import com.jcraft.jsch.MAC; -import javax.crypto.*; -import javax.crypto.spec.*; - -public class HMACMD5 extends HMAC { - public HMACMD5(){ - name = "hmac-md5"; - bsize = 16; - algorithm = "HmacMD5"; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD596.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD596.java deleted file mode 100644 index 3c1bb7bc..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD596.java +++ /dev/null @@ -1,48 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class HMACMD596 extends HMACMD5 { - public HMACMD596(){ - name="hmac-md5-96"; - } - - @Override - public int getBlockSize(){ - return 12; - }; - - private final byte[] _buf16 = new byte[16]; - @Override - public void doFinal(byte[] buf, int offset){ - super.doFinal(_buf16, 0); - System.arraycopy(_buf16, 0, buf, offset, 12); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD596ETM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD596ETM.java deleted file mode 100644 index d6310644..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD596ETM.java +++ /dev/null @@ -1,37 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class HMACMD596ETM extends HMACMD596 { - public HMACMD596ETM(){ - name="hmac-md5-96-etm@openssh.com"; - etm=true; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD5ETM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD5ETM.java deleted file mode 100644 index ea21e74b..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD5ETM.java +++ /dev/null @@ -1,41 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import com.jcraft.jsch.MAC; -import javax.crypto.*; -import javax.crypto.spec.*; - -public class HMACMD5ETM extends HMACMD5 { - public HMACMD5ETM(){ - name = "hmac-md5-etm@openssh.com"; - etm = true; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA1.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA1.java deleted file mode 100644 index eda37275..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA1.java +++ /dev/null @@ -1,38 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class HMACSHA1 extends HMAC { - public HMACSHA1(){ - name = "hmac-sha1"; - bsize = 20; - algorithm = "HmacSHA1"; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA196.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA196.java deleted file mode 100644 index a2348331..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA196.java +++ /dev/null @@ -1,49 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class HMACSHA196 extends HMACSHA1 { - - public HMACSHA196(){ - name = "hmac-sha1-96"; - } - - @Override - public int getBlockSize(){ - return 12; - }; - - private final byte[] _buf20 = new byte[20]; - @Override - public void doFinal(byte[] buf, int offset){ - super.doFinal(_buf20, 0); - System.arraycopy(_buf20, 0, buf, offset, 12); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA196ETM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA196ETM.java deleted file mode 100644 index c1a0e23f..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA196ETM.java +++ /dev/null @@ -1,38 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class HMACSHA196ETM extends HMACSHA196 { - - public HMACSHA196ETM(){ - name = "hmac-sha1-96-etm@openssh.com"; - etm = true; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA1ETM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA1ETM.java deleted file mode 100644 index 05db55c1..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA1ETM.java +++ /dev/null @@ -1,37 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class HMACSHA1ETM extends HMACSHA1 { - public HMACSHA1ETM(){ - name = "hmac-sha1-etm@openssh.com"; - etm = true; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA224SSHCOM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA224SSHCOM.java deleted file mode 100644 index dae8689a..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA224SSHCOM.java +++ /dev/null @@ -1,38 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class HMACSHA224SSHCOM extends HMAC { - public HMACSHA224SSHCOM(){ - name = "hmac-sha224@ssh.com"; - bsize = 28; - algorithm = "HmacSHA224"; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256.java deleted file mode 100644 index 0517438f..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256.java +++ /dev/null @@ -1,38 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class HMACSHA256 extends HMAC { - public HMACSHA256(){ - name = "hmac-sha2-256"; - bsize = 32; - algorithm = "HmacSHA256"; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA2562SSHCOM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA2562SSHCOM.java deleted file mode 100644 index 51668f21..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA2562SSHCOM.java +++ /dev/null @@ -1,38 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class HMACSHA2562SSHCOM extends HMAC { - public HMACSHA2562SSHCOM(){ - name = "hmac-sha256-2@ssh.com"; - bsize = 32; - algorithm = "HmacSHA256"; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256ETM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256ETM.java deleted file mode 100644 index 8f852d06..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256ETM.java +++ /dev/null @@ -1,37 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class HMACSHA256ETM extends HMACSHA256 { - public HMACSHA256ETM(){ - name = "hmac-sha2-256-etm@openssh.com"; - etm = true; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256SSHCOM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256SSHCOM.java deleted file mode 100644 index 8d6571f2..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256SSHCOM.java +++ /dev/null @@ -1,45 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -//This MAC appears to use a shortened keysize of 16 bytes instead of 32 bytes. -//See discussion at https://github.com/ronf/asyncssh/issues/399. -public class HMACSHA256SSHCOM extends HMAC { - public HMACSHA256SSHCOM(){ - name = "hmac-sha256@ssh.com"; - bsize = 16; - algorithm = "HmacSHA256"; - } - - @Override - public int getBlockSize(){ - return 32; - }; -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA384SSHCOM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA384SSHCOM.java deleted file mode 100644 index 64fe7608..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA384SSHCOM.java +++ /dev/null @@ -1,38 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class HMACSHA384SSHCOM extends HMAC { - public HMACSHA384SSHCOM(){ - name = "hmac-sha384@ssh.com"; - bsize = 48; - algorithm = "HmacSHA384"; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512.java deleted file mode 100644 index be0bc90e..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512.java +++ /dev/null @@ -1,38 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class HMACSHA512 extends HMAC { - public HMACSHA512(){ - name = "hmac-sha2-512"; - bsize = 64; - algorithm = "HmacSHA512"; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512ETM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512ETM.java deleted file mode 100644 index d4656e02..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512ETM.java +++ /dev/null @@ -1,37 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class HMACSHA512ETM extends HMACSHA512 { - public HMACSHA512ETM(){ - name = "hmac-sha2-512-etm@openssh.com"; - etm = true; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512SSHCOM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512SSHCOM.java deleted file mode 100644 index 722fe92c..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512SSHCOM.java +++ /dev/null @@ -1,38 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class HMACSHA512SSHCOM extends HMAC { - public HMACSHA512SSHCOM(){ - name = "hmac-sha512@ssh.com"; - bsize = 64; - algorithm = "HmacSHA512"; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenDSA.java deleted file mode 100644 index 9f30710b..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenDSA.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import java.security.*; -import java.security.interfaces.*; - -public class KeyPairGenDSA implements com.jcraft.jsch.KeyPairGenDSA{ - byte[] x; // private - byte[] y; // public - byte[] p; - byte[] q; - byte[] g; - - @Override - public void init(int key_size) throws Exception{ - KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA"); - keyGen.initialize(key_size, new SecureRandom()); - KeyPair pair = keyGen.generateKeyPair(); - PublicKey pubKey=pair.getPublic(); - PrivateKey prvKey=pair.getPrivate(); - - x=((DSAPrivateKey)prvKey).getX().toByteArray(); - y=((DSAPublicKey)pubKey).getY().toByteArray(); - - DSAParams params=((DSAKey)prvKey).getParams(); - p=params.getP().toByteArray(); - q=params.getQ().toByteArray(); - g=params.getG().toByteArray(); - } - @Override - public byte[] getX(){return x;} - @Override - public byte[] getY(){return y;} - @Override - public byte[] getP(){return p;} - @Override - public byte[] getQ(){return q;} - @Override - public byte[] getG(){return g;} -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenECDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenECDSA.java deleted file mode 100644 index dc55ad44..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenECDSA.java +++ /dev/null @@ -1,100 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import java.security.*; -import java.security.interfaces.*; -import java.security.spec.*; -import com.jcraft.jsch.JSchException; - -public class KeyPairGenECDSA implements com.jcraft.jsch.KeyPairGenECDSA { - byte[] d; - byte[] r; - byte[] s; - ECPublicKey pubKey; - ECPrivateKey prvKey; - ECParameterSpec params; - @Override - public void init(int key_size) throws Exception { - String name=null; - if(key_size==256) name="secp256r1"; - else if(key_size==384) name="secp384r1"; - else if(key_size==521) name="secp521r1"; - else throw new JSchException("unsupported key size: "+key_size); - - for(int i = 0; i<1000; i++) { - KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC"); - ECGenParameterSpec ecsp = new ECGenParameterSpec(name); - kpg.initialize(ecsp); - KeyPair kp = kpg.genKeyPair(); - prvKey = (ECPrivateKey)kp.getPrivate(); - pubKey = (ECPublicKey)kp.getPublic(); - params=pubKey.getParams(); - d=prvKey.getS().toByteArray(); - ECPoint w = pubKey.getW(); - r = w.getAffineX().toByteArray(); - s = w.getAffineY().toByteArray(); - - if(r.length!=s.length) continue; - if(key_size==256 && r.length==32) break; - if(key_size==384 && r.length==48) break; - if(key_size==521 && r.length==66) break; - } - if(d.lengthtmp.length){ tmp=new byte[len]; } - random.nextBytes(tmp); - System.arraycopy(tmp, 0, foo, start, len); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA1.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA1.java deleted file mode 100644 index 00bbb845..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA1.java +++ /dev/null @@ -1,57 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import com.jcraft.jsch.HASH; - -import java.security.*; - -public class SHA1 implements HASH{ - MessageDigest md; - @Override - public int getBlockSize(){return 20;} - @Override - public void init() throws Exception{ - try{ md=MessageDigest.getInstance("SHA-1"); } - catch(Exception e){ - System.err.println(e); - } - } - @Override - public void update(byte[] foo, int start, int len) throws Exception{ - md.update(foo, start, len); - } - @Override - public byte[] digest() throws Exception{ - return md.digest(); - } - @Override - public String name(){return "SHA1";} -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA224.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA224.java deleted file mode 100644 index e7fcf883..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA224.java +++ /dev/null @@ -1,57 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import com.jcraft.jsch.HASH; - -import java.security.*; - -public class SHA224 implements HASH { - MessageDigest md; - @Override - public int getBlockSize(){return 28;} - @Override - public void init() throws Exception { - try{ md=MessageDigest.getInstance("SHA-224"); } - catch(Exception e){ - System.err.println(e); - } - } - @Override - public void update(byte[] foo, int start, int len) throws Exception { - md.update(foo, start, len); - } - @Override - public byte[] digest() throws Exception { - return md.digest(); - } - @Override - public String name(){return "SHA224";} -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA256.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA256.java deleted file mode 100644 index bd5da24f..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA256.java +++ /dev/null @@ -1,57 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import com.jcraft.jsch.HASH; - -import java.security.*; - -public class SHA256 implements HASH { - MessageDigest md; - @Override - public int getBlockSize(){return 32;} - @Override - public void init() throws Exception { - try{ md=MessageDigest.getInstance("SHA-256"); } - catch(Exception e){ - System.err.println(e); - } - } - @Override - public void update(byte[] foo, int start, int len) throws Exception { - md.update(foo, start, len); - } - @Override - public byte[] digest() throws Exception { - return md.digest(); - } - @Override - public String name(){return "SHA256";} -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA384.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA384.java deleted file mode 100644 index 6221a7d2..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA384.java +++ /dev/null @@ -1,55 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import java.security.*; - -public class SHA384 implements com.jcraft.jsch.HASH { - MessageDigest md; - @Override - public int getBlockSize(){return 48;} - @Override - public void init() throws Exception { - try{ md=MessageDigest.getInstance("SHA-384"); } - catch(Exception e){ - System.err.println(e); - } - } - @Override - public void update(byte[] foo, int start, int len) throws Exception { - md.update(foo, start, len); - } - @Override - public byte[] digest() throws Exception { - return md.digest(); - } - @Override - public String name(){return "SHA384";} -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA512.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA512.java deleted file mode 100644 index a201f536..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA512.java +++ /dev/null @@ -1,55 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import java.security.*; - -public class SHA512 implements com.jcraft.jsch.HASH { - MessageDigest md; - @Override - public int getBlockSize(){return 64;} - @Override - public void init() throws Exception { - try{ md=MessageDigest.getInstance("SHA-512"); } - catch(Exception e){ - System.err.println(e); - } - } - @Override - public void update(byte[] foo, int start, int len) throws Exception { - md.update(foo, start, len); - } - @Override - public byte[] digest() throws Exception { - return md.digest(); - } - @Override - public String name(){return "SHA512";} -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureDSA.java deleted file mode 100644 index 26df5621..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureDSA.java +++ /dev/null @@ -1,164 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import java.math.BigInteger; -import java.nio.charset.StandardCharsets; -import java.security.*; -import java.security.spec.*; -import com.jcraft.jsch.Buffer; - -public class SignatureDSA implements com.jcraft.jsch.SignatureDSA{ - - java.security.Signature signature; - KeyFactory keyFactory; - - @Override - public void init() throws Exception{ - signature=java.security.Signature.getInstance("SHA1withDSA"); - keyFactory=KeyFactory.getInstance("DSA"); - } - @Override - public void setPubKey(byte[] y, byte[] p, byte[] q, byte[] g) throws Exception{ - DSAPublicKeySpec dsaPubKeySpec = - new DSAPublicKeySpec(new BigInteger(y), - new BigInteger(p), - new BigInteger(q), - new BigInteger(g)); - PublicKey pubKey=keyFactory.generatePublic(dsaPubKeySpec); - signature.initVerify(pubKey); - } - @Override - public void setPrvKey(byte[] x, byte[] p, byte[] q, byte[] g) throws Exception{ - DSAPrivateKeySpec dsaPrivKeySpec = - new DSAPrivateKeySpec(new BigInteger(x), - new BigInteger(p), - new BigInteger(q), - new BigInteger(g)); - PrivateKey prvKey = keyFactory.generatePrivate(dsaPrivKeySpec); - signature.initSign(prvKey); - } - @Override - public byte[] sign() throws Exception{ - byte[] sig=signature.sign(); -/* -System.err.print("sign["+sig.length+"] "); -for(int i=0; i 1 && - secret[0] == 0 && (secret[1]&0x80) == 0) { - byte[] tmp=new byte[secret.length-1]; - System.arraycopy(secret, 1, tmp, 0, tmp.length); - return normalize(tmp); - } - else { - return secret; - } - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA256.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA256.java deleted file mode 100644 index 6989de24..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA256.java +++ /dev/null @@ -1,37 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class SignatureECDSA256 extends SignatureECDSAN { - @Override - String getName() { - return "ecdsa-sha2-nistp256"; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA384.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA384.java deleted file mode 100644 index 3ff01166..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA384.java +++ /dev/null @@ -1,37 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class SignatureECDSA384 extends SignatureECDSAN { - @Override - String getName() { - return "ecdsa-sha2-nistp384"; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA521.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA521.java deleted file mode 100644 index f6527ff4..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA521.java +++ /dev/null @@ -1,37 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -public class SignatureECDSA521 extends SignatureECDSAN { - @Override - String getName() { - return "ecdsa-sha2-nistp521"; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSAN.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSAN.java deleted file mode 100644 index 0a5dca9a..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSAN.java +++ /dev/null @@ -1,214 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import java.math.BigInteger; -import java.security.*; -import java.security.spec.*; -import com.jcraft.jsch.Buffer; - -abstract class SignatureECDSAN implements com.jcraft.jsch.SignatureECDSA { - - Signature signature; - KeyFactory keyFactory; - - abstract String getName(); - - @Override - public void init() throws Exception{ - String name = getName(); - String foo="SHA256withECDSA"; - if(name.equals("ecdsa-sha2-nistp384")) foo="SHA384withECDSA"; - else if(name.equals("ecdsa-sha2-nistp521")) foo="SHA512withECDSA"; - signature=java.security.Signature.getInstance(foo); - keyFactory=KeyFactory.getInstance("EC"); - } - - @Override - public void setPubKey(byte[] r, byte[] s) throws Exception{ - - // r and s must be unsigned values. - r=insert0(r); - s=insert0(s); - - String name="secp256r1"; - if(r.length>=64) name="secp521r1"; - else if(r.length>=48) name="secp384r1"; - - AlgorithmParameters param = AlgorithmParameters.getInstance("EC"); - param.init(new ECGenParameterSpec(name)); - ECParameterSpec ecparam = param.getParameterSpec(ECParameterSpec.class); - ECPoint w = new ECPoint(new BigInteger(1, r), new BigInteger(1, s)); - PublicKey pubKey = - keyFactory.generatePublic(new ECPublicKeySpec(w, ecparam)); - signature.initVerify(pubKey); - } - - @Override - public void setPrvKey(byte[] d) throws Exception{ - - // d must be unsigned value. - d=insert0(d); - - String name="secp256r1"; - if(d.length>=64) name="secp521r1"; - else if(d.length>=48) name="secp384r1"; - - AlgorithmParameters param = AlgorithmParameters.getInstance("EC"); - param.init(new ECGenParameterSpec(name)); - ECParameterSpec ecparam = param.getParameterSpec(ECParameterSpec.class); - BigInteger _d = new BigInteger(1, d); - PrivateKey prvKey = - keyFactory.generatePrivate(new ECPrivateKeySpec(_d, ecparam)); - signature.initSign(prvKey); - } - @Override - public byte[] sign() throws Exception{ - byte[] sig=signature.sign(); - - // It seems that the output from SunEC is in ASN.1, - // so we have to convert it. - if(sig[0]==0x30 && // in ASN.1 - ((sig[1]+2 == sig.length) || - ((sig[1]&0x80)!=0 && (sig[2]&0xff)+3==sig.length))){// 2bytes for len - - int index=3; - if((sig[1]&0x80)!=0 && (sig[2]&0xff)+3==sig.length) - index=4; - - byte[] r = new byte[sig[index]]; - byte[] s = new byte[sig[index+2+sig[index]]]; - System.arraycopy(sig, index+1, r, 0, r.length); - System.arraycopy(sig, index+3+sig[index], s, 0, s.length); - - r = chop0(r); - s = chop0(s); - - Buffer buf = new Buffer(); - buf.putMPInt(r); - buf.putMPInt(s); - - sig=new byte[buf.getLength()]; - buf.setOffSet(0); - buf.getByte(sig); - } - - return sig; - } - @Override - public void update(byte[] foo) throws Exception{ - signature.update(foo); - } - @Override - public boolean verify(byte[] sig) throws Exception{ - - // It seems that SunEC expects ASN.1 data, - // so we have to convert it. - if(!(sig[0]==0x30 && // not in ASN.1 - ((sig[1]+2 == sig.length) || - ((sig[1]&0x80)!=0 && (sig[2]&0xff)+3==sig.length)))) { - Buffer b = new Buffer(sig); - - b.getString(); // ecdsa-sha2-nistp256 - b.getInt(); - - byte[] r = b.getMPInt(); - byte[] s = b.getMPInt(); - - r=trimLeadingZeros(insert0(r)); - s=trimLeadingZeros(insert0(s)); - - byte[] asn1 = null; - if(r.length<64){ - asn1 = new byte[6+r.length+s.length]; - asn1[0] = (byte)0x30; - asn1[1] = (byte)(4+r.length+s.length); - asn1[2] = (byte)0x02; - asn1[3] = (byte)r.length; - System.arraycopy(r, 0, asn1, 4, r.length); - asn1[r.length+4] = (byte)0x02; - asn1[r.length+5] = (byte)s.length; - System.arraycopy(s, 0, asn1, (6+r.length), s.length); - } - else { - asn1 = new byte[6+r.length+s.length+1]; - asn1[0] = (byte)0x30; - asn1[1] = (byte)0x81; - asn1[2] = (byte)(4+r.length+s.length); - asn1[3] = (byte)0x02; - asn1[4] = (byte)r.length; - System.arraycopy(r, 0, asn1, 5, r.length); - asn1[r.length+5] = (byte)0x02; - asn1[r.length+6] = (byte)s.length; - System.arraycopy(s, 0, asn1, (7+r.length), s.length); - } - sig=asn1; - } - - return signature.verify(sig); - } - - private static byte[] insert0(byte[] buf){ - if ((buf[0] & 0x80) == 0) return buf; - byte[] tmp = new byte[buf.length+1]; - System.arraycopy(buf, 0, tmp, 1, buf.length); - bzero(buf); - return tmp; - } - - private static byte[] chop0(byte[] buf){ - if(buf[0]!=0) return buf; - byte[] tmp = new byte[buf.length-1]; - System.arraycopy(buf, 1, tmp, 0, tmp.length); - bzero(buf); - return tmp; - } - - private static void bzero(byte[] buf){ - for(int i = 0; iivsize){ - tmp=new byte[ivsize]; - System.arraycopy(iv, 0, tmp, 0, tmp.length); - iv=tmp; - } - if(key.length>bsize){ - tmp=new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, tmp.length); - key=tmp; - } - - try{ - cipher=javax.crypto.Cipher.getInstance("DESede/CBC/"+pad); -/* - // The following code does not work on IBM's JDK 1.4.1 - SecretKeySpec skeySpec = new SecretKeySpec(key, "DESede"); - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - skeySpec, new IvParameterSpec(iv)); -*/ - DESedeKeySpec keyspec=new DESedeKeySpec(key); - SecretKeyFactory keyfactory=SecretKeyFactory.getInstance("DESede"); - SecretKey _key=keyfactory.generateSecret(keyspec); - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - _key, new IvParameterSpec(iv)); - } - catch(Exception e){ - cipher=null; - throw e; - } - } - @Override - public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ - cipher.update(foo, s1, len, bar, s2); - } - @Override - public boolean isCBC(){return true; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/TripleDESCTR.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/TripleDESCTR.java deleted file mode 100644 index 12de00c0..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/TripleDESCTR.java +++ /dev/null @@ -1,89 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jce; - -import com.jcraft.jsch.Cipher; -import javax.crypto.*; -import javax.crypto.spec.*; - -public class TripleDESCTR implements Cipher{ - private static final int ivsize=8; - private static final int bsize=24; - private javax.crypto.Cipher cipher; - @Override - public int getIVSize(){return ivsize;} - @Override - public int getBlockSize(){return bsize;} - @Override - public void init(int mode, byte[] key, byte[] iv) throws Exception{ - String pad="NoPadding"; - //if(padding) pad="PKCS5Padding"; - byte[] tmp; - if(iv.length>ivsize){ - tmp=new byte[ivsize]; - System.arraycopy(iv, 0, tmp, 0, tmp.length); - iv=tmp; - } - if(key.length>bsize){ - tmp=new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, tmp.length); - key=tmp; - } - - try{ - cipher=javax.crypto.Cipher.getInstance("DESede/CTR/"+pad); -/* - // The following code does not work on IBM's JDK 1.4.1 - SecretKeySpec skeySpec = new SecretKeySpec(key, "DESede"); - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - skeySpec, new IvParameterSpec(iv)); -*/ - DESedeKeySpec keyspec=new DESedeKeySpec(key); - SecretKeyFactory keyfactory=SecretKeyFactory.getInstance("DESede"); - SecretKey _key=keyfactory.generateSecret(keyspec); - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - _key, new IvParameterSpec(iv)); - } - catch(Exception e){ - cipher=null; - throw e; - } - } - @Override - public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ - cipher.update(foo, s1, len, bar, s2); - } - @Override - public boolean isCBC(){return false; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/juz/Compression.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/juz/Compression.java deleted file mode 100644 index 9bfe26e4..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/juz/Compression.java +++ /dev/null @@ -1,141 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -package com.jcraft.jsch.juz; - -import com.jcraft.jsch.*; -import java.util.function.Supplier; -import java.util.zip.Deflater; -import java.util.zip.Inflater; - -/** - * This example demonstrates the packet compression without using jzlib[1]. - * - * The ssh protocol adopts zlib[2] for the packet compression. Fortunately, - * JDK has provided wrapper classes for zlib(j.u.z.{Deflater, Inflater}), - * but it does not expose enough functionality of zlib, unfortunately; - * it must not allow to compress data with SYNC_FLUSH. So, JSch has been - * using jzlib by the default. After 12 years of bug parade entry[3] filing, - * Java7 has revised j.u.z.Deflater, and SYNC_FLUSH has been supported at last. - * This example shows how to enable the packet compression by using JDK's - * java.util.zip package. - * - * - * [1] http://www.jcraft.com/jzlib/ - * [2] http://www.zlib.net/ - * [3] https://bugs.openjdk.java.net/browse/JDK-4206909 - */ -public class Compression implements com.jcraft.jsch.Compression { - static private final int BUF_SIZE=4096; - private final int buffer_margin=32+20; // AES256 + HMACSHA1 - private Deflater deflater; - private Inflater inflater; - private byte[] tmpbuf=new byte[BUF_SIZE]; - private byte[] inflated_buf; - private Session session; - - public Compression(){ - } - - private void logMessage(int level, Supplier message) { - Logger logger = session == null ? JSch.getLogger() : session.getLogger(); - if (!logger.isEnabled(level)) { - return; - } - logger.log(level, message.get()); - } - - @Override - public void end() { - inflated_buf=null; - if(inflater!=null){ - inflater.end(); - inflater=null; - } - if(deflater!=null){ - deflater.end(); - deflater=null; - } - session=null; - } - - @Override - public void init(int type, int level, Session session){ - this.session = session; - init(type, level); - } - - @Override - public void init(int type, int level){ - if(type==DEFLATER){ - deflater=new Deflater(level); - } - else if(type==INFLATER){ - inflater=new Inflater(); - inflated_buf=new byte[BUF_SIZE]; - } - logMessage(Logger.DEBUG, () -> "zlib using "+this.getClass().getCanonicalName()); - } - - @Override - public byte[] compress(byte[] buf, int start, int[] end){ - - // There may be a bug in j.u.z.Deflater. - // It seems to me that if the size of buffer for Deflater#deflate() is - // not enough, that method will return weird value ;-( - if(tmpbuf.length0); - } - catch(java.util.zip.DataFormatException e){ - logMessage(Logger.WARN, () -> "an exception during uncompress\n"+e.toString()); - } - - if(buf.length>16)&0xffff; - } - - @Override - public void reset(){ - s1=1L; - s2=0L; - } - - @Override - public long getValue(){ - return ((s2<<16)|s1); - } - - @Override - public void update(byte[] buf, int index, int len){ - - if(len==1){ - s1+=buf[index++]&0xff; s2+=s1; - s1%=BASE; - s2%=BASE; - return; - } - - int len1 = len/NMAX; - int len2 = len%NMAX; - while(len1-->0) { - int k=NMAX; - len-=k; - while(k-->0){ - s1+=buf[index++]&0xff; s2+=s1; - } - s1%=BASE; - s2%=BASE; - } - - int k=len2; - len-=k; - while(k-->0){ - s1+=buf[index++]&0xff; s2+=s1; - } - s1%=BASE; - s2%=BASE; - } - - @Override - public Adler32 copy(){ - Adler32 foo = new Adler32(); - foo.s1 = this.s1; - foo.s2 = this.s2; - return foo; - } - - // The following logic has come from zlib.1.2. - static long combine(long adler1, long adler2, long len2){ - long BASEL = (long)BASE; - long sum1; - long sum2; - long rem; // unsigned int - - rem = len2 % BASEL; - sum1 = adler1 & 0xffffL; - sum2 = rem * sum1; - sum2 %= BASEL; // MOD(sum2); - sum1 += (adler2 & 0xffffL) + BASEL - 1; - sum2 += ((adler1 >> 16) & 0xffffL) + ((adler2 >> 16) & 0xffffL) + BASEL - rem; - if (sum1 >= BASEL) sum1 -= BASEL; - if (sum1 >= BASEL) sum1 -= BASEL; - if (sum2 >= (BASEL << 1)) sum2 -= (BASEL << 1); - if (sum2 >= BASEL) sum2 -= BASEL; - return sum1 | (sum2 << 16); - } - -/* - private java.util.zip.Adler32 adler=new java.util.zip.Adler32(); - void update(byte[] buf, int index, int len){ - if(buf==null) {adler.reset();} - else{adler.update(buf, index, len);} - } - void reset(){ - adler.reset(); - } - void reset(long init){ - if(init==1L){ - adler.reset(); - } - else{ - System.err.println("unsupported operation"); - } - } - long getValue(){ - return adler.getValue(); - } -*/ -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/CRC32.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/CRC32.java deleted file mode 100644 index 969030bc..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/CRC32.java +++ /dev/null @@ -1,184 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jsch.jzlib; - -final class CRC32 implements Checksum { - - /* - * The following logic has come from RFC1952. - */ - private int v = 0; - private static int[] crc_table = null; - static { - crc_table = new int[256]; - for (int n = 0; n < 256; n++) { - int c = n; - for (int k = 8; --k >= 0; ) { - if ((c & 1) != 0) - c = 0xedb88320 ^ (c >>> 1); - else - c = c >>> 1; - } - crc_table[n] = c; - } - } - - @Override - public void update (byte[] buf, int index, int len) { - int c = ~v; - while (--len >= 0) - c = crc_table[(c^buf[index++])&0xff]^(c >>> 8); - v = ~c; - } - - @Override - public void reset(){ - v = 0; - } - - @Override - public void reset(long vv){ - v = (int)(vv&0xffffffffL); - } - - @Override - public long getValue(){ - return v&0xffffffffL; - } - - // The following logic has come from zlib.1.2. - private static final int GF2_DIM = 32; - static long combine(long crc1, long crc2, long len2){ - long row; - long[] even = new long[GF2_DIM]; - long[] odd = new long[GF2_DIM]; - - // degenerate case (also disallow negative lengths) - if (len2 <= 0) - return crc1; - - // put operator for one zero bit in odd - odd[0] = 0xedb88320L; // CRC-32 polynomial - row = 1; - for (int n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } - - // put operator for two zero bits in even - gf2_matrix_square(even, odd); - - // put operator for four zero bits in odd - gf2_matrix_square(odd, even); - - // apply len2 zeros to crc1 (first square will put the operator for one - // zero byte, eight zero bits, in even) - do { - // apply zeros operator for this bit of len2 - gf2_matrix_square(even, odd); - if ((len2 & 1)!=0) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - // if no more bits set, then done - if (len2 == 0) - break; - - // another iteration of the loop with odd and even swapped - gf2_matrix_square(odd, even); - if ((len2 & 1)!=0) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - // if no more bits set, then done - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; - } - - private static long gf2_matrix_times(long[] mat, long vec){ - long sum = 0; - int index = 0; - while (vec!=0) { - if ((vec & 1)!=0) - sum ^= mat[index]; - vec >>= 1; - index++; - } - return sum; - } - - static final void gf2_matrix_square(long[] square, long[] mat) { - for (int n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); - } - - /* - private java.util.zip.CRC32 crc32 = new java.util.zip.CRC32(); - - void update(byte[] buf, int index, int len){ - if(buf==null) {crc32.reset();} - else{crc32.update(buf, index, len);} - } - void reset(){ - crc32.reset(); - } - void reset(long init){ - if(init==0L){ - crc32.reset(); - } - else{ - System.err.println("unsupported operation"); - } - } - long getValue(){ - return crc32.getValue(); - } -*/ - @Override - public CRC32 copy(){ - CRC32 foo = new CRC32(); - foo.v = this.v; - return foo; - } - - static int[] getCRC32Table(){ - int[] tmp = new int[crc_table.length]; - System.arraycopy(crc_table, 0, tmp, 0, tmp.length); - return tmp; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Checksum.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Checksum.java deleted file mode 100644 index 013c1b2f..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Checksum.java +++ /dev/null @@ -1,43 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jsch.jzlib; - -interface Checksum { - void update(byte[] buf, int index, int len); - void reset(); - void reset(long init); - long getValue(); - Checksum copy(); -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Compression.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Compression.java deleted file mode 100644 index 206fe172..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Compression.java +++ /dev/null @@ -1,176 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package com.jcraft.jsch.jzlib; - -import java.util.function.Supplier; -import com.jcraft.jsch.JSch; -import com.jcraft.jsch.Logger; -import com.jcraft.jsch.Session; -import java.io.UncheckedIOException; - -public class Compression implements com.jcraft.jsch.Compression { - static private final int BUF_SIZE=4096; - private final int buffer_margin=32+20; // AES256 + HMACSHA1 - private Deflater deflater; - private Inflater inflater; - private byte[] tmpbuf=new byte[BUF_SIZE]; - private byte[] inflated_buf; - private Session session; - - public Compression(){ - } - - private void logMessage(int level, Supplier message) { - Logger logger = session == null ? JSch.getLogger() : session.getLogger(); - if (!logger.isEnabled(level)) { - return; - } - logger.log(level, message.get()); - } - - @Override - public void end() { - inflated_buf=null; - if(inflater!=null){ - inflater.end(); - inflater=null; - } - if(deflater!=null){ - deflater.end(); - deflater=null; - } - session=null; - } - - @Override - public void init(int type, int level, Session session) { - this.session = session; - init(type, level); - } - - public void init(int type, int level) throws UncheckedIOException { - if(type==DEFLATER){ - try{ - deflater=new Deflater(level); - } - catch(GZIPException e){ - throw new UncheckedIOException(e); - } - } - else if(type==INFLATER){ - inflater=new Inflater(); - inflated_buf=new byte[BUF_SIZE]; - } - logMessage(Logger.DEBUG, () -> "zlib using "+this.getClass().getCanonicalName()); - } - - @Override - public byte[] compress(byte[] buf, int start, int[] len){ - deflater.next_in=buf; - deflater.next_in_index=start; - deflater.avail_in=len[0]-start; - int outputlen=start; - byte[] outputbuf=buf; - int tmp=0; - - do{ - deflater.next_out=tmpbuf; - deflater.next_out_index=0; - deflater.avail_out=BUF_SIZE; - int status=deflater.deflate(JZlib.Z_PARTIAL_FLUSH); - switch(status){ - case JZlib.Z_OK: - tmp=BUF_SIZE-deflater.avail_out; - if(outputbuf.length "compress: deflate returnd "+status); - } - } - while(deflater.avail_out==0); - - len[0]=outputlen; - return outputbuf; - } - - @Override - public byte[] uncompress(byte[] buffer, int start, int[] length){ - int inflated_end=0; - - inflater.next_in=buffer; - inflater.next_in_index=start; - inflater.avail_in=length[0]; - - while(true){ - inflater.next_out=tmpbuf; - inflater.next_out_index=0; - inflater.avail_out=BUF_SIZE; - int status=inflater.inflate(JZlib.Z_PARTIAL_FLUSH); - switch(status){ - case JZlib.Z_OK: - if(inflated_buf.lengthbuffer.length-start){ - byte[] foo=new byte[inflated_end+start]; - System.arraycopy(buffer, 0, foo, 0, start); - System.arraycopy(inflated_buf, 0, foo, start, inflated_end); - buffer=foo; - } - else{ - System.arraycopy(inflated_buf, 0, buffer, start, inflated_end); - } - length[0]=inflated_end; - return buffer; - default: - logMessage(Logger.WARN, () -> "compress: deflate returnd "+status); - return null; - } - } - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Deflate.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Deflate.java deleted file mode 100644 index f30f274e..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Deflate.java +++ /dev/null @@ -1,1756 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jsch.jzlib; - -final class Deflate implements Cloneable { - - static final private int MAX_MEM_LEVEL=9; - - static final private int Z_DEFAULT_COMPRESSION=-1; - - static final private int MAX_WBITS=15; // 32K LZ77 window - static final private int DEF_MEM_LEVEL=8; - - static class Config{ - int good_length; // reduce lazy search above this match length - int max_lazy; // do not perform lazy search above this match length - int nice_length; // quit search above this match length - int max_chain; - int func; - Config(int good_length, int max_lazy, - int nice_length, int max_chain, int func){ - this.good_length=good_length; - this.max_lazy=max_lazy; - this.nice_length=nice_length; - this.max_chain=max_chain; - this.func=func; - } - } - - static final private int STORED=0; - static final private int FAST=1; - static final private int SLOW=2; - static final private Config[] config_table; - static{ - config_table=new Config[10]; - // good lazy nice chain - config_table[0]=new Config(0, 0, 0, 0, STORED); - config_table[1]=new Config(4, 4, 8, 4, FAST); - config_table[2]=new Config(4, 5, 16, 8, FAST); - config_table[3]=new Config(4, 6, 32, 32, FAST); - - config_table[4]=new Config(4, 4, 16, 16, SLOW); - config_table[5]=new Config(8, 16, 32, 32, SLOW); - config_table[6]=new Config(8, 16, 128, 128, SLOW); - config_table[7]=new Config(8, 32, 128, 256, SLOW); - config_table[8]=new Config(32, 128, 258, 1024, SLOW); - config_table[9]=new Config(32, 258, 258, 4096, SLOW); - } - - static final private String[] z_errmsg = { - "need dictionary", // Z_NEED_DICT 2 - "stream end", // Z_STREAM_END 1 - "", // Z_OK 0 - "file error", // Z_ERRNO (-1) - "stream error", // Z_STREAM_ERROR (-2) - "data error", // Z_DATA_ERROR (-3) - "insufficient memory", // Z_MEM_ERROR (-4) - "buffer error", // Z_BUF_ERROR (-5) - "incompatible version",// Z_VERSION_ERROR (-6) - "" - }; - - // block not completed, need more input or more output - static final private int NeedMore=0; - - // block flush performed - static final private int BlockDone=1; - - // finish started, need only more output at next deflate - static final private int FinishStarted=2; - - // finish done, accept no more input or output - static final private int FinishDone=3; - - // preset dictionary flag in zlib header - static final private int PRESET_DICT=0x20; - - static final private int Z_FILTERED=1; - static final private int Z_HUFFMAN_ONLY=2; - static final private int Z_DEFAULT_STRATEGY=0; - - static final private int Z_NO_FLUSH=0; - static final private int Z_PARTIAL_FLUSH=1; - static final private int Z_SYNC_FLUSH=2; - static final private int Z_FULL_FLUSH=3; - static final private int Z_FINISH=4; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - static final private int INIT_STATE=42; - static final private int BUSY_STATE=113; - static final private int FINISH_STATE=666; - - // The deflate compression method - static final private int Z_DEFLATED=8; - - static final private int STORED_BLOCK=0; - static final private int STATIC_TREES=1; - static final private int DYN_TREES=2; - - // The three kinds of block type - static final private int Z_BINARY=0; - static final private int Z_ASCII=1; - static final private int Z_UNKNOWN=2; - - static final private int Buf_size=8*2; - - // repeat previous bit length 3-6 times (2 bits of repeat count) - static final private int REP_3_6=16; - - // repeat a zero length 3-10 times (3 bits of repeat count) - static final private int REPZ_3_10=17; - - // repeat a zero length 11-138 times (7 bits of repeat count) - static final private int REPZ_11_138=18; - - static final private int MIN_MATCH=3; - static final private int MAX_MATCH=258; - static final private int MIN_LOOKAHEAD=(MAX_MATCH+MIN_MATCH+1); - - static final private int MAX_BITS=15; - static final private int D_CODES=30; - static final private int BL_CODES=19; - static final private int LENGTH_CODES=29; - static final private int LITERALS=256; - static final private int L_CODES=(LITERALS+1+LENGTH_CODES); - static final private int HEAP_SIZE=(2*L_CODES+1); - - static final private int END_BLOCK=256; - - ZStream strm; // pointer back to this zlib stream - int status; // as the name implies - byte[] pending_buf; // output still pending - int pending_buf_size; // size of pending_buf - int pending_out; // next pending byte to output to the stream - int pending; // nb of bytes in the pending buffer - int wrap = 1; - byte data_type; // UNKNOWN, BINARY or ASCII - byte method; // STORED (for zip only) or DEFLATED - int last_flush; // value of flush param for previous deflate call - - int w_size; // LZ77 window size (32K by default) - int w_bits; // log2(w_size) (8..16) - int w_mask; // w_size - 1 - - byte[] window; - // Sliding window. Input bytes are read into the second half of the window, - // and move to the first half later to keep a dictionary of at least wSize - // bytes. With this organization, matches are limited to a distance of - // wSize-MAX_MATCH bytes, but this ensures that IO is always - // performed with a length multiple of the block size. Also, it limits - // the window size to 64K, which is quite useful on MSDOS. - // To do: use the user input buffer as sliding window. - - int window_size; - // Actual size of window: 2*wSize, except when the user input buffer - // is directly used as sliding window. - - short[] prev; - // Link to older string with same hash index. To limit the size of this - // array to 64K, this link is maintained only for the last 32K strings. - // An index in this array is thus a window index modulo 32K. - - short[] head; // Heads of the hash chains or NIL. - - int ins_h; // hash index of string to be inserted - int hash_size; // number of elements in hash table - int hash_bits; // log2(hash_size) - int hash_mask; // hash_size-1 - - // Number of bits by which ins_h must be shifted at each input - // step. It must be such that after MIN_MATCH steps, the oldest - // byte no longer takes part in the hash key, that is: - // hash_shift * MIN_MATCH >= hash_bits - int hash_shift; - - // Window position at the beginning of the current output block. Gets - // negative when the window is moved backwards. - - int block_start; - - int match_length; // length of best match - int prev_match; // previous match - int match_available; // set if previous match exists - int strstart; // start of string to insert - int match_start; // start of matching string - int lookahead; // number of valid bytes ahead in window - - // Length of the best match at previous step. Matches not greater than this - // are discarded. This is used in the lazy match evaluation. - int prev_length; - - // To speed up deflation, hash chains are never searched beyond this - // length. A higher limit improves compression ratio but degrades the speed. - int max_chain_length; - - // Attempt to find a better match only when the current match is strictly - // smaller than this value. This mechanism is used only for compression - // levels >= 4. - int max_lazy_match; - - // Insert new strings in the hash table only if the match length is not - // greater than this length. This saves time but degrades compression. - // max_insert_length is used only for compression levels <= 3. - - int level; // compression level (1..9) - int strategy; // favor or force Huffman coding - - // Use a faster search when the previous match is longer than this - int good_match; - - // Stop searching when current match exceeds this - int nice_match; - - short[] dyn_ltree; // literal and length tree - short[] dyn_dtree; // distance tree - short[] bl_tree; // Huffman tree for bit lengths - - Tree l_desc=new Tree(); // desc for literal tree - Tree d_desc=new Tree(); // desc for distance tree - Tree bl_desc=new Tree(); // desc for bit length tree - - // number of codes at each bit length for an optimal tree - short[] bl_count=new short[MAX_BITS+1]; - // working area to be used in Tree#gen_codes() - short[] next_code=new short[MAX_BITS+1]; - - // heap used to build the Huffman trees - int[] heap=new int[2*L_CODES+1]; - - int heap_len; // number of elements in the heap - int heap_max; // element of largest frequency - // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - // The same heap array is used to build all trees. - - // Depth of each subtree used as tie breaker for trees of equal frequency - byte[] depth=new byte[2*L_CODES+1]; - - byte[] l_buf; // index for literals or lengths */ - - // Size of match buffer for literals/lengths. There are 4 reasons for - // limiting lit_bufsize to 64K: - // - frequencies can be kept in 16 bit counters - // - if compression is not successful for the first block, all input - // data is still in the window so we can still emit a stored block even - // when input comes from standard input. (This can also be done for - // all blocks if lit_bufsize is not greater than 32K.) - // - if compression is not successful for a file smaller than 64K, we can - // even emit a stored file instead of a stored block (saving 5 bytes). - // This is applicable only for zip (not gzip or zlib). - // - creating new Huffman trees less frequently may not provide fast - // adaptation to changes in the input data statistics. (Take for - // example a binary file with poorly compressible code followed by - // a highly compressible string table.) Smaller buffer sizes give - // fast adaptation but have of course the overhead of transmitting - // trees more frequently. - // - I can't count above 4 - int lit_bufsize; - - int last_lit; // running index in l_buf - - // Buffer for distances. To simplify the code, d_buf and l_buf have - // the same number of elements. To use different lengths, an extra flag - // array would be necessary. - - int d_buf; // index of pendig_buf - - int opt_len; // bit length of current block with optimal trees - int static_len; // bit length of current block with static trees - int matches; // number of string matches in current block - int last_eob_len; // bit length of EOB code for last block - - // Output buffer. bits are inserted starting at the bottom (least - // significant bits). - short bi_buf; - - // Number of valid bits in bi_buf. All bits above the last valid bit - // are always zero. - int bi_valid; - - GZIPHeader gheader = null; - - Deflate(ZStream strm){ - this.strm=strm; - dyn_ltree=new short[HEAP_SIZE*2]; - dyn_dtree=new short[(2*D_CODES+1)*2]; // distance tree - bl_tree=new short[(2*BL_CODES+1)*2]; // Huffman tree for bit lengths - } - - void lm_init() { - window_size=2*w_size; - - head[hash_size-1]=0; - for(int i=0; i= 3; max_blindex--) { - if (bl_tree[Tree.bl_order[max_blindex]*2+1] != 0) break; - } - // Update opt_len to include the bit length tree and counts - opt_len += 3*(max_blindex+1) + 5+5+4; - - return max_blindex; - } - - - // Send the header for a block using dynamic Huffman trees: the counts, the - // lengths of the bit length codes, the literal tree and the distance tree. - // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - void send_all_trees(int lcodes, int dcodes, int blcodes){ - int rank; // index in bl_order - - send_bits(lcodes-257, 5); // not +255 as stated in appnote.txt - send_bits(dcodes-1, 5); - send_bits(blcodes-4, 4); // not -3 as stated in appnote.txt - for (rank = 0; rank < blcodes; rank++) { - send_bits(bl_tree[Tree.bl_order[rank]*2+1], 3); - } - send_tree(dyn_ltree, lcodes-1); // literal tree - send_tree(dyn_dtree, dcodes-1); // distance tree - } - - // Send a literal or distance tree in compressed form, using the codes in - // bl_tree. - void send_tree (short[] tree,// the tree to be sent - int max_code // and its largest code of non zero frequency - ){ - int n; // iterates over all tree elements - int prevlen = -1; // last emitted length - int curlen; // length of current code - int nextlen = tree[0*2+1]; // length of next code - int count = 0; // repeat count of the current code - int max_count = 7; // max repeat count - int min_count = 4; // min repeat count - - if (nextlen == 0){ max_count = 138; min_count = 3; } - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[(n+1)*2+1]; - if(++count < max_count && curlen == nextlen) { - continue; - } - else if(count < min_count) { - do { send_code(curlen, bl_tree); } while (--count != 0); - } - else if(curlen != 0){ - if(curlen != prevlen){ - send_code(curlen, bl_tree); count--; - } - send_code(REP_3_6, bl_tree); - send_bits(count-3, 2); - } - else if(count <= 10){ - send_code(REPZ_3_10, bl_tree); - send_bits(count-3, 3); - } - else{ - send_code(REPZ_11_138, bl_tree); - send_bits(count-11, 7); - } - count = 0; prevlen = curlen; - if(nextlen == 0){ - max_count = 138; min_count = 3; - } - else if(curlen == nextlen){ - max_count = 6; min_count = 3; - } - else{ - max_count = 7; min_count = 4; - } - } - } - - // Output a byte on the stream. - // IN assertion: there is enough room in pending_buf. - final void put_byte(byte[] p, int start, int len){ - System.arraycopy(p, start, pending_buf, pending, len); - pending+=len; - } - - final void put_byte(byte c){ - pending_buf[pending++]=c; - } - final void put_short(int w) { - put_byte((byte)(w/*&0xff*/)); - put_byte((byte)(w>>>8)); - } - final void putShortMSB(int b){ - put_byte((byte)(b>>8)); - put_byte((byte)(b/*&0xff*/)); - } - - final void send_code(int c, short[] tree){ - int c2=c*2; - send_bits((tree[c2]&0xffff), (tree[c2+1]&0xffff)); - } - - void send_bits(int value, int length){ - int len = length; - if (bi_valid > Buf_size - len) { - int val = value; -// bi_buf |= (val << bi_valid); - bi_buf |= ((val << bi_valid)&0xffff); - put_short(bi_buf); - bi_buf = (short)(val >>> (Buf_size - bi_valid)); - bi_valid += len - Buf_size; - } else { -// bi_buf |= (value) << bi_valid; - bi_buf |= (((value) << bi_valid)&0xffff); - bi_valid += len; - } - } - - // Send one empty static block to give enough lookahead for inflate. - // This takes 10 bits, of which 7 may remain in the bit buffer. - // The current inflate code requires 9 bits of lookahead. If the - // last two codes for the previous block (real code plus EOB) were coded - // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - // the last real code. In this case we send two empty static blocks instead - // of one. (There are no problems if the previous block is stored or fixed.) - // To simplify the code, we assume the worst case of last real code encoded - // on one bit only. - void _tr_align(){ - send_bits(STATIC_TREES<<1, 3); - send_code(END_BLOCK, StaticTree.static_ltree); - - bi_flush(); - - // Of the 10 bits for the empty block, we have already sent - // (10 - bi_valid) bits. The lookahead for the last real code (before - // the EOB of the previous block) was thus at least one plus the length - // of the EOB plus what we have just sent of the empty static block. - if (1 + last_eob_len + 10 - bi_valid < 9) { - send_bits(STATIC_TREES<<1, 3); - send_code(END_BLOCK, StaticTree.static_ltree); - bi_flush(); - } - last_eob_len = 7; - } - - - // Save the match info and tally the frequency counts. Return true if - // the current block must be flushed. - boolean _tr_tally (int dist, // distance of matched string - int lc // match length-MIN_MATCH or unmatched char (if dist==0) - ){ - - pending_buf[d_buf+last_lit*2] = (byte)(dist>>>8); - pending_buf[d_buf+last_lit*2+1] = (byte)dist; - - l_buf[last_lit] = (byte)lc; last_lit++; - - if (dist == 0) { - // lc is the unmatched char - dyn_ltree[lc*2]++; - } - else { - matches++; - // Here, lc is the match length - MIN_MATCH - dist--; // dist = match distance - 1 - dyn_ltree[(Tree._length_code[lc]+LITERALS+1)*2]++; - dyn_dtree[Tree.d_code(dist)*2]++; - } - - if ((last_lit & 0x1fff) == 0 && level > 2) { - // Compute an upper bound for the compressed length - int out_length = last_lit*8; - int in_length = strstart - block_start; - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (int)dyn_dtree[dcode*2] * - (5L+Tree.extra_dbits[dcode]); - } - out_length >>>= 3; - if ((matches < (last_lit/2)) && out_length < in_length/2) return true; - } - - return (last_lit == lit_bufsize-1); - // We avoid equality with lit_bufsize because of wraparound at 64K - // on 16 bit machines and because stored blocks are restricted to - // 64K-1 bytes. - } - - // Send the block data compressed using the given Huffman trees - void compress_block(short[] ltree, short[] dtree){ - int dist; // distance of matched string - int lc; // match length or unmatched char (if dist == 0) - int lx = 0; // running index in l_buf - int code; // the code to send - int extra; // number of extra bits to send - - if (last_lit != 0){ - do{ - dist=((pending_buf[d_buf+lx*2]<<8)&0xff00)| - (pending_buf[d_buf+lx*2+1]&0xff); - lc=(l_buf[lx])&0xff; lx++; - - if(dist == 0){ - send_code(lc, ltree); // send a literal byte - } - else{ - // Here, lc is the match length - MIN_MATCH - code = Tree._length_code[lc]; - - send_code(code+LITERALS+1, ltree); // send the length code - extra = Tree.extra_lbits[code]; - if(extra != 0){ - lc -= Tree.base_length[code]; - send_bits(lc, extra); // send the extra length bits - } - dist--; // dist is now the match distance - 1 - code = Tree.d_code(dist); - - send_code(code, dtree); // send the distance code - extra = Tree.extra_dbits[code]; - if (extra != 0) { - dist -= Tree.base_dist[code]; - send_bits(dist, extra); // send the extra distance bits - } - } // literal or match pair ? - - // Check that the overlay between pending_buf and d_buf+l_buf is ok: - } - while (lx < last_lit); - } - - send_code(END_BLOCK, ltree); - last_eob_len = ltree[END_BLOCK*2+1]; - } - - // Set the data type to ASCII or BINARY, using a crude approximation: - // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. - // IN assertion: the fields freq of dyn_ltree are set and the total of all - // frequencies does not exceed 64K (to fit in an int on 16 bit machines). - void set_data_type(){ - int n = 0; - int ascii_freq = 0; - int bin_freq = 0; - while(n<7){ bin_freq += dyn_ltree[n*2]; n++;} - while(n<128){ ascii_freq += dyn_ltree[n*2]; n++;} - while(n (ascii_freq >>> 2) ? Z_BINARY : Z_ASCII); - } - - // Flush the bit buffer, keeping at most 7 bits in it. - void bi_flush(){ - if (bi_valid == 16) { - put_short(bi_buf); - bi_buf=0; - bi_valid=0; - } - else if (bi_valid >= 8) { - put_byte((byte)bi_buf); - bi_buf>>>=8; - bi_valid-=8; - } - } - - // Flush the bit buffer and align the output on a byte boundary - void bi_windup(){ - if (bi_valid > 8) { - put_short(bi_buf); - } else if (bi_valid > 0) { - put_byte((byte)bi_buf); - } - bi_buf = 0; - bi_valid = 0; - } - - // Copy a stored block, storing first the length and its - // one's complement if requested. - void copy_block(int buf, // the input data - int len, // its length - boolean header // true if block header must be written - ){ - int index=0; - bi_windup(); // align on byte boundary - last_eob_len = 8; // enough lookahead for inflate - - if (header) { - put_short((short)len); - put_short((short)~len); - } - - // while(len--!=0) { - // put_byte(window[buf+index]); - // index++; - // } - put_byte(window, buf, len); - } - - void flush_block_only(boolean eof){ - _tr_flush_block(block_start>=0 ? block_start : -1, - strstart-block_start, - eof); - block_start=strstart; - strm.flush_pending(); - } - - // Copy without compression as much as possible from the input stream, return - // the current block state. - // This function does not insert new strings in the dictionary since - // uncompressible data is probably not useful. This function is used - // only for the level=0 compression option. - // NOTE: this function should be optimized to avoid extra copying from - // window to pending_buf. - int deflate_stored(int flush){ - // Stored blocks are limited to 0xffff bytes, pending_buf is limited - // to pending_buf_size, and each stored block has a 5 byte header: - - int max_block_size = 0xffff; - int max_start; - - if(max_block_size > pending_buf_size - 5) { - max_block_size = pending_buf_size - 5; - } - - // Copy as much as possible from input to output: - while(true){ - // Fill the window as much as possible: - if(lookahead<=1){ - fill_window(); - if(lookahead==0 && flush==Z_NO_FLUSH) return NeedMore; - if(lookahead==0) break; // flush the current block - } - - strstart+=lookahead; - lookahead=0; - - // Emit a stored block if pending_buf will be full: - max_start=block_start+max_block_size; - if(strstart==0|| strstart>=max_start) { - // strstart == 0 is possible when wraparound on 16-bit machine - lookahead = strstart-max_start; - strstart = max_start; - - flush_block_only(false); - if(strm.avail_out==0) return NeedMore; - - } - - // Flush if we may have to slide, otherwise block_start may become - // negative and the data will be gone: - if(strstart-block_start >= w_size-MIN_LOOKAHEAD) { - flush_block_only(false); - if(strm.avail_out==0) return NeedMore; - } - } - - flush_block_only(flush == Z_FINISH); - if(strm.avail_out==0) - return (flush == Z_FINISH) ? FinishStarted : NeedMore; - - return flush == Z_FINISH ? FinishDone : BlockDone; - } - - // Send a stored block - void _tr_stored_block(int buf, // input block - int stored_len, // length of input block - boolean eof // true if this is the last block for a file - ){ - send_bits((STORED_BLOCK<<1)+(eof?1:0), 3); // send block type - copy_block(buf, stored_len, true); // with header - } - - // Determine the best encoding for the current block: dynamic trees, static - // trees or store, and output the encoded block to the zip file. - void _tr_flush_block(int buf, // input block, or NULL if too old - int stored_len, // length of input block - boolean eof // true if this is the last block for a file - ) { - int opt_lenb, static_lenb;// opt_len and static_len in bytes - int max_blindex = 0; // index of last bit length code of non zero freq - - // Build the Huffman trees unless a stored block is forced - if(level > 0) { - // Check if the file is ascii or binary - if(data_type == Z_UNKNOWN) set_data_type(); - - // Construct the literal and distance trees - l_desc.build_tree(this); - - d_desc.build_tree(this); - - // At this point, opt_len and static_len are the total bit lengths of - // the compressed block data, excluding the tree representations. - - // Build the bit length tree for the above two trees, and get the index - // in bl_order of the last bit length code to send. - max_blindex=build_bl_tree(); - - // Determine the best encoding. Compute first the block length in bytes - opt_lenb=(opt_len+3+7)>>>3; - static_lenb=(static_len+3+7)>>>3; - - if(static_lenb<=opt_lenb) opt_lenb=static_lenb; - } - else { - opt_lenb=static_lenb=stored_len+5; // force a stored block - } - - if(stored_len+4<=opt_lenb && buf != -1){ - // 4: two words for the lengths - // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - // Otherwise we can't have processed more than WSIZE input bytes since - // the last block flush, because compression would have been - // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - // transform a block into a stored block. - _tr_stored_block(buf, stored_len, eof); - } - else if(static_lenb == opt_lenb){ - send_bits((STATIC_TREES<<1)+(eof?1:0), 3); - compress_block(StaticTree.static_ltree, StaticTree.static_dtree); - } - else{ - send_bits((DYN_TREES<<1)+(eof?1:0), 3); - send_all_trees(l_desc.max_code+1, d_desc.max_code+1, max_blindex+1); - compress_block(dyn_ltree, dyn_dtree); - } - - // The above check is made mod 2^32, for files larger than 512 MB - // and uLong implemented on 32 bits. - - init_block(); - - if(eof){ - bi_windup(); - } - } - - // Fill the window when the lookahead becomes insufficient. - // Updates strstart and lookahead. - // - // IN assertion: lookahead < MIN_LOOKAHEAD - // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - // At least one byte has been read, or avail_in == 0; reads are - // performed for at least two bytes (required for the zip translate_eol - // option -- not supported here). - void fill_window(){ - int n, m; - int p; - int more; // Amount of free space at the end of the window. - - do{ - more = (window_size-lookahead-strstart); - - // Deal with !@#$% 64K limit: - if(more==0 && strstart==0 && lookahead==0){ - more = w_size; - } - else if(more==-1) { - // Very unlikely, but possible on 16 bit machine if strstart == 0 - // and lookahead == 1 (input done one byte at time) - more--; - - // If the window is almost full and there is insufficient lookahead, - // move the upper half to the lower one to make room in the upper half. - } - else if(strstart >= w_size+ w_size-MIN_LOOKAHEAD) { - System.arraycopy(window, w_size, window, 0, w_size); - match_start-=w_size; - strstart-=w_size; // we now have strstart >= MAX_DIST - block_start-=w_size; - - // Slide the hash table (could be avoided with 32 bit values - // at the expense of memory usage). We slide even when level == 0 - // to keep the hash table consistent if we switch back to level > 0 - // later. (Using level 0 permanently is not an optimal usage of - // zlib, so we don't care about this pathological case.) - - n = hash_size; - p=n; - do { - m = (head[--p]&0xffff); - head[p]=(m>=w_size ? (short)(m-w_size) : 0); - } - while (--n != 0); - - n = w_size; - p = n; - do { - m = (prev[--p]&0xffff); - prev[p] = (m >= w_size ? (short)(m-w_size) : 0); - // If n is not on any hash chain, prev[n] is garbage but - // its value will never be used. - } - while (--n!=0); - more += w_size; - } - - if (strm.avail_in == 0) return; - - // If there was no sliding: - // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - // more == window_size - lookahead - strstart - // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - // => more >= window_size - 2*WSIZE + 2 - // In the BIG_MEM or MMAP case (not yet supported), - // window_size == input_size + MIN_LOOKAHEAD && - // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - // Otherwise, window_size == 2*WSIZE so more >= 2. - // If there was sliding, more >= WSIZE. So in all cases, more >= 2. - - n = strm.read_buf(window, strstart + lookahead, more); - lookahead += n; - - // Initialize the hash value now that we have some input: - if(lookahead >= MIN_MATCH) { - ins_h = window[strstart]&0xff; - ins_h=(((ins_h)<= MIN_MATCH){ - ins_h=(((ins_h)<=MIN_MATCH){ - // check_match(strstart, match_start, match_length); - - bflush=_tr_tally(strstart-match_start, match_length-MIN_MATCH); - - lookahead -= match_length; - - // Insert new strings in the hash table only if the match length - // is not too large. This saves time but degrades compression. - if(match_length <= max_lazy_match && - lookahead >= MIN_MATCH) { - match_length--; // string at strstart already in hash table - do{ - strstart++; - - ins_h=((ins_h<= MIN_MATCH) { - ins_h=(((ins_h)< 4096))) { - - // If prev_match is also MIN_MATCH, match_start is garbage - // but we will ignore the current match anyway. - match_length = MIN_MATCH-1; - } - } - - // If there was a match at the previous step and the current - // match is not better, output the previous match: - if(prev_length >= MIN_MATCH && match_length <= prev_length) { - int max_insert = strstart + lookahead - MIN_MATCH; - // Do not insert strings in hash table beyond this. - - // check_match(strstart-1, prev_match, prev_length); - - bflush=_tr_tally(strstart-1-prev_match, prev_length - MIN_MATCH); - - // Insert in hash table all strings up to the end of the match. - // strstart-1 and strstart are already inserted. If there is not - // enough lookahead, the last two strings are not inserted in - // the hash table. - lookahead -= prev_length-1; - prev_length -= 2; - do{ - if(++strstart <= max_insert) { - ins_h=(((ins_h)<(w_size-MIN_LOOKAHEAD) ? - strstart-(w_size-MIN_LOOKAHEAD) : 0; - int nice_match=this.nice_match; - - // Stop when cur_match becomes <= limit. To simplify the code, - // we prevent matches with the string of window index 0. - - int wmask = w_mask; - - int strend = strstart + MAX_MATCH; - byte scan_end1 = window[scan+best_len-1]; - byte scan_end = window[scan+best_len]; - - // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - // It is easy to get rid of this optimization if necessary. - - // Do not waste too much time if we already have a good match: - if (prev_length >= good_match) { - chain_length >>= 2; - } - - // Do not look for matches beyond the end of the input. This is necessary - // to make deflate deterministic. - if (nice_match > lookahead) nice_match = lookahead; - - do { - match = cur_match; - - // Skip to next match if the match length cannot increase - // or if the match length is less than 2: - if (window[match+best_len] != scan_end || - window[match+best_len-1] != scan_end1 || - window[match] != window[scan] || - window[++match] != window[scan+1]) continue; - - // The check at best_len-1 can be removed because it will be made - // again later. (This heuristic is not always a win.) - // It is not necessary to compare scan[2] and match[2] since they - // are always equal when the other bytes match, given that - // the hash keys are equal and that HASH_BITS >= 8. - scan += 2; match++; - - // We check for insufficient lookahead only every 8th comparison; - // the 256th check will be made at strstart+258. - do { - } while (window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - scan < strend); - - len = MAX_MATCH - strend - scan; - scan = strend - MAX_MATCH; - - if(len>best_len) { - match_start = cur_match; - best_len = len; - if (len >= nice_match) break; - scan_end1 = window[scan+best_len-1]; - scan_end = window[scan+best_len]; - } - - } while ((cur_match = (prev[cur_match & wmask]&0xffff)) > limit - && --chain_length != 0); - - if (best_len <= lookahead) return best_len; - return lookahead; - } - - int deflateInit(int level, int bits, int memlevel){ - return deflateInit(level, Z_DEFLATED, bits, memlevel, - Z_DEFAULT_STRATEGY); - } - - int deflateInit(int level, int bits){ - return deflateInit(level, Z_DEFLATED, bits, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY); - } - int deflateInit(int level){ - return deflateInit(level, MAX_WBITS); - } - private int deflateInit(int level, int method, int windowBits, - int memLevel, int strategy){ - int wrap = 1; - // byte[] my_version=ZLIB_VERSION; - - // - // if (version == null || version[0] != my_version[0] - // || stream_size != sizeof(z_stream)) { - // return Z_VERSION_ERROR; - // } - - strm.msg = null; - - if (level == Z_DEFAULT_COMPRESSION) level = 6; - - if (windowBits < 0) { // undocumented feature: suppress zlib header - wrap = 0; - windowBits = -windowBits; - } - else if(windowBits > 15){ - wrap = 2; - windowBits -= 16; - strm.adler=new CRC32(); - } - - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || - method != Z_DEFLATED || - windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_HUFFMAN_ONLY) { - return Z_STREAM_ERROR; - } - - strm.dstate = this; - - this.wrap = wrap; - w_bits = windowBits; - w_size = 1 << w_bits; - w_mask = w_size - 1; - - hash_bits = memLevel + 7; - hash_size = 1 << hash_bits; - hash_mask = hash_size - 1; - hash_shift = ((hash_bits+MIN_MATCH-1)/MIN_MATCH); - - window = new byte[w_size*2]; - prev = new short[w_size]; - head = new short[hash_size]; - - lit_bufsize = 1 << (memLevel + 6); // 16K elements by default - - // We overlay pending_buf and d_buf+l_buf. This works since the average - // output size for (length,distance) codes is <= 24 bits. - pending_buf = new byte[lit_bufsize*3]; - pending_buf_size = lit_bufsize*3; - - d_buf = lit_bufsize; - l_buf = new byte[lit_bufsize]; - - this.level = level; - - this.strategy = strategy; - this.method = (byte)method; - - return deflateReset(); - } - - int deflateReset(){ - strm.total_in = strm.total_out = 0; - strm.msg = null; // - strm.data_type = Z_UNKNOWN; - - pending = 0; - pending_out = 0; - - if(wrap < 0){ - wrap = -wrap; - } - status = (wrap==0) ? BUSY_STATE : INIT_STATE; - strm.adler.reset(); - - last_flush = Z_NO_FLUSH; - - tr_init(); - lm_init(); - return Z_OK; - } - - int deflateEnd(){ - if(status!=INIT_STATE && status!=BUSY_STATE && status!=FINISH_STATE){ - return Z_STREAM_ERROR; - } - // Deallocate in reverse order of allocations: - pending_buf=null; - l_buf=null; - head=null; - prev=null; - window=null; - // free - // dstate=null; - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; - } - - int deflateParams(int _level, int _strategy){ - int err=Z_OK; - - if(_level == Z_DEFAULT_COMPRESSION){ - _level = 6; - } - if(_level < 0 || _level > 9 || - _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) { - return Z_STREAM_ERROR; - } - - if(config_table[level].func!=config_table[_level].func && - strm.total_in != 0) { - // Flush the last buffer: - err = strm.deflate(Z_PARTIAL_FLUSH); - } - - if(level != _level) { - level = _level; - max_lazy_match = config_table[level].max_lazy; - good_match = config_table[level].good_length; - nice_match = config_table[level].nice_length; - max_chain_length = config_table[level].max_chain; - } - strategy = _strategy; - return err; - } - - int deflateSetDictionary (byte[] dictionary, int dictLength){ - int length = dictLength; - int index=0; - - if(dictionary == null || status != INIT_STATE) - return Z_STREAM_ERROR; - - strm.adler.update(dictionary, 0, dictLength); - - if(length < MIN_MATCH) return Z_OK; - if(length > w_size-MIN_LOOKAHEAD){ - length = w_size-MIN_LOOKAHEAD; - index=dictLength-length; // use the tail of the dictionary - } - System.arraycopy(dictionary, index, window, 0, length); - strstart = length; - block_start = length; - - // Insert all strings in the hash table (except for the last two bytes). - // s->lookahead stays null, so s->ins_h will be recomputed at the next - // call of fill_window. - - ins_h = window[0]&0xff; - ins_h=(((ins_h)<Z_FINISH || flush<0){ - return Z_STREAM_ERROR; - } - - if(strm.next_out == null || - (strm.next_in == null && strm.avail_in != 0) || - (status == FINISH_STATE && flush != Z_FINISH)) { - strm.msg=z_errmsg[Z_NEED_DICT-(Z_STREAM_ERROR)]; - return Z_STREAM_ERROR; - } - if(strm.avail_out == 0){ - strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; - return Z_BUF_ERROR; - } - - old_flush = last_flush; - last_flush = flush; - - // Write the zlib header - if(status == INIT_STATE) { - if(wrap == 2){ - getGZIPHeader().put(this); - status=BUSY_STATE; - strm.adler.reset(); - } - else{ - int header = (Z_DEFLATED+((w_bits-8)<<4))<<8; - int level_flags=((level-1)&0xff)>>1; - - if(level_flags>3) level_flags=3; - header |= (level_flags<<6); - if(strstart!=0) header |= PRESET_DICT; - header+=31-(header % 31); - - status=BUSY_STATE; - putShortMSB(header); - - - // Save the adler32 of the preset dictionary: - if(strstart!=0){ - long adler=strm.adler.getValue(); - putShortMSB((int)(adler>>>16)); - putShortMSB((int)(adler&0xffff)); - } - strm.adler.reset(); - } - } - - // Flush as much pending output as possible - if(pending != 0) { - strm.flush_pending(); - if(strm.avail_out == 0) { - // Since avail_out is 0, deflate will be called again with - // more output space, but possibly with both pending and - // avail_in equal to zero. There won't be anything to do, - // but this is not an error situation so make sure we - // return OK instead of BUF_ERROR at next call of deflate: - last_flush = -1; - return Z_OK; - } - - // Make sure there is something to do and avoid duplicate consecutive - // flushes. For repeated and useless calls with Z_FINISH, we keep - // returning Z_STREAM_END instead of Z_BUFF_ERROR. - } - else if(strm.avail_in==0 && flush <= old_flush && - flush != Z_FINISH) { - strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; - return Z_BUF_ERROR; - } - - // User must not provide more input after the first FINISH: - if(status == FINISH_STATE && strm.avail_in != 0) { - strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; - return Z_BUF_ERROR; - } - - // Start a new block or continue the current one. - if(strm.avail_in!=0 || lookahead!=0 || - (flush != Z_NO_FLUSH && status != FINISH_STATE)) { - int bstate=-1; - switch(config_table[level].func){ - case STORED: - bstate = deflate_stored(flush); - break; - case FAST: - bstate = deflate_fast(flush); - break; - case SLOW: - bstate = deflate_slow(flush); - break; - default: - } - - if (bstate==FinishStarted || bstate==FinishDone) { - status = FINISH_STATE; - } - if (bstate==NeedMore || bstate==FinishStarted) { - if(strm.avail_out == 0) { - last_flush = -1; // avoid BUF_ERROR next call, see above - } - return Z_OK; - // If flush != Z_NO_FLUSH && avail_out == 0, the next call - // of deflate should use the same flush parameter to make sure - // that the flush is complete. So we don't have to output an - // empty block here, this will be done at next call. This also - // ensures that for a very small output buffer, we emit at most - // one empty block. - } - - if (bstate==BlockDone) { - if(flush == Z_PARTIAL_FLUSH) { - _tr_align(); - } - else { // FULL_FLUSH or SYNC_FLUSH - _tr_stored_block(0, 0, false); - // For a full flush, this empty block will be recognized - // as a special marker by inflate_sync(). - if(flush == Z_FULL_FLUSH) { - //state.head[s.hash_size-1]=0; - for(int i=0; i>8)&0xff)); - put_byte((byte)((adler>>16)&0xff)); - put_byte((byte)((adler>>24)&0xff)); - put_byte((byte)(strm.total_in&0xff)); - put_byte((byte)((strm.total_in>>8)&0xff)); - put_byte((byte)((strm.total_in>>16)&0xff)); - put_byte((byte)((strm.total_in>>24)&0xff)); - - getGZIPHeader().setCRC(adler); - } - else{ - // Write the zlib trailer (adler32) - long adler=strm.adler.getValue(); - putShortMSB((int)(adler>>>16)); - putShortMSB((int)(adler&0xffff)); - } - - strm.flush_pending(); - - // If avail_out is zero, the application will call deflate again - // to flush the rest. - - if(wrap > 0) wrap = -wrap; // write the trailer only once! - return pending != 0 ? Z_OK : Z_STREAM_END; - } - - static int deflateCopy(ZStream dest, ZStream src){ - - if(src.dstate == null){ - return Z_STREAM_ERROR; - } - - if(src.next_in!=null){ - dest.next_in = new byte[src.next_in.length]; - System.arraycopy(src.next_in, 0, dest.next_in, 0, src.next_in.length); - } - dest.next_in_index = src.next_in_index; - dest.avail_in = src.avail_in; - dest.total_in = src.total_in; - - if(src.next_out!=null){ - dest.next_out = new byte[src.next_out.length]; - System.arraycopy(src.next_out, 0, dest.next_out ,0 , src.next_out.length); - } - - dest.next_out_index = src.next_out_index; - dest.avail_out = src.avail_out; - dest.total_out = src.total_out; - - dest.msg = src.msg; - dest.data_type = src.data_type; - dest.adler = src.adler.copy(); - - try{ - dest.dstate = (Deflate)src.dstate.clone(); - dest.dstate.strm = dest; - } - catch(CloneNotSupportedException e){ - // - } - return Z_OK; - } - - @Override - public Object clone() throws CloneNotSupportedException { - Deflate dest = (Deflate)super.clone(); - - dest.pending_buf = dup(dest.pending_buf); - dest.l_buf = dup(dest.l_buf); - dest.window = dup(dest.window); - - dest.prev = dup(dest.prev); - dest.head = dup(dest.head); - dest.dyn_ltree = dup(dest.dyn_ltree); - dest.dyn_dtree = dup(dest.dyn_dtree); - dest.bl_tree = dup(dest.bl_tree); - - dest.bl_count = dup(dest.bl_count); - dest.next_code = dup(dest.next_code); - dest.heap = dup(dest.heap); - dest.depth = dup(dest.depth); - - dest.l_desc.dyn_tree = dest.dyn_ltree; - dest.d_desc.dyn_tree = dest.dyn_dtree; - dest.bl_desc.dyn_tree = dest.bl_tree; - - /* - dest.l_desc.stat_desc = StaticTree.static_l_desc; - dest.d_desc.stat_desc = StaticTree.static_d_desc; - dest.bl_desc.stat_desc = StaticTree.static_bl_desc; - */ - - if(dest.gheader!=null){ - dest.gheader = (GZIPHeader)dest.gheader.clone(); - } - - return dest; - } - - private byte[] dup(byte[] buf){ - byte[] foo = new byte[buf.length]; - System.arraycopy(buf, 0, foo, 0, foo.length); - return foo; - } - private short[] dup(short[] buf){ - short[] foo = new short[buf.length]; - System.arraycopy(buf, 0, foo, 0, foo.length); - return foo; - } - private int[] dup(int[] buf){ - int[] foo = new int[buf.length]; - System.arraycopy(buf, 0, foo, 0, foo.length); - return foo; - } - - synchronized GZIPHeader getGZIPHeader(){ - if(gheader==null){ - gheader = new GZIPHeader(); - } - return gheader; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Deflater.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Deflater.java deleted file mode 100644 index f947a704..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Deflater.java +++ /dev/null @@ -1,174 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jsch.jzlib; - -final class Deflater extends ZStream{ - - static final private int MAX_WBITS=15; // 32K LZ77 window - static final private int DEF_WBITS=MAX_WBITS; - - static final private int Z_NO_FLUSH=0; - static final private int Z_PARTIAL_FLUSH=1; - static final private int Z_SYNC_FLUSH=2; - static final private int Z_FULL_FLUSH=3; - static final private int Z_FINISH=4; - - static final private int MAX_MEM_LEVEL=9; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - private boolean finished = false; - - Deflater(){ - super(); - } - - Deflater(int level) throws GZIPException { - this(level, MAX_WBITS); - } - - Deflater(int level, boolean nowrap) throws GZIPException { - this(level, MAX_WBITS, nowrap); - } - - Deflater(int level, int bits) throws GZIPException { - this(level, bits, false); - } - - Deflater(int level, int bits, boolean nowrap) throws GZIPException { - super(); - int ret = init(level, bits, nowrap); - if(ret!=Z_OK) - throw new GZIPException(ret+": "+msg); - } - - Deflater(int level, int bits, int memlevel, JZlib.WrapperType wrapperType) throws GZIPException { - super(); - int ret = init(level, bits, memlevel, wrapperType); - if(ret!=Z_OK) - throw new GZIPException(ret+": "+msg); - } - - Deflater(int level, int bits, int memlevel) throws GZIPException { - super(); - int ret = init(level, bits, memlevel); - if(ret!=Z_OK) - throw new GZIPException(ret+": "+msg); - } - - int init(int level){ - return init(level, MAX_WBITS); - } - int init(int level, boolean nowrap){ - return init(level, MAX_WBITS, nowrap); - } - int init(int level, int bits){ - return init(level, bits, false); - } - int init(int level, int bits, int memlevel, JZlib.WrapperType wrapperType){ - if(bits < 9 || bits > 15){ - return Z_STREAM_ERROR; - } - if(wrapperType == JZlib.W_NONE) { - bits *= -1; - } - else if(wrapperType == JZlib.W_GZIP) { - bits += 16; - } - else if(wrapperType == JZlib.W_ANY) { - return Z_STREAM_ERROR; - } - else if(wrapperType == JZlib.W_ZLIB) { - } - return init(level, bits, memlevel); - } - int init(int level, int bits, int memlevel){ - finished = false; - dstate=new Deflate(this); - return dstate.deflateInit(level, bits, memlevel); - } - int init(int level, int bits, boolean nowrap){ - finished = false; - dstate=new Deflate(this); - return dstate.deflateInit(level, nowrap?-bits:bits); - } - - @Override - int deflate(int flush){ - if(dstate==null){ - return Z_STREAM_ERROR; - } - int ret = dstate.deflate(flush); - if(ret == Z_STREAM_END) - finished = true; - return ret; - } - @Override - int end(){ - finished = true; - if(dstate==null) return Z_STREAM_ERROR; - int ret=dstate.deflateEnd(); - dstate=null; - free(); - return ret; - } - int params(int level, int strategy){ - if(dstate==null) return Z_STREAM_ERROR; - return dstate.deflateParams(level, strategy); - } - int setDictionary (byte[] dictionary, int dictLength){ - if(dstate == null) - return Z_STREAM_ERROR; - return dstate.deflateSetDictionary(dictionary, dictLength); - } - - @Override - boolean finished(){ - return finished; - } - - int copy(Deflater src){ - this.finished = src.finished; - return Deflate.deflateCopy(this, src); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/DeflaterOutputStream.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/DeflaterOutputStream.java deleted file mode 100644 index df89ffa1..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/DeflaterOutputStream.java +++ /dev/null @@ -1,186 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.jcraft.jsch.jzlib; -import java.io.*; - -final class DeflaterOutputStream extends FilterOutputStream { - - protected final Deflater deflater; - - protected byte[] buffer; - - private boolean closed = false; - - private boolean syncFlush = false; - - private final byte[] buf1 = new byte[1]; - - protected boolean mydeflater = false; - - private boolean close_out = true; - - protected static final int DEFAULT_BUFSIZE = 512; - - DeflaterOutputStream(OutputStream out) throws IOException { - this(out, - new Deflater(JZlib.Z_DEFAULT_COMPRESSION), - DEFAULT_BUFSIZE, true); - mydeflater = true; - } - - DeflaterOutputStream(OutputStream out, Deflater def) throws IOException { - this(out, def, DEFAULT_BUFSIZE, true); - } - - DeflaterOutputStream(OutputStream out, - Deflater deflater, - int size) throws IOException { - this(out, deflater, size, true); - } - DeflaterOutputStream(OutputStream out, - Deflater deflater, - int size, - boolean close_out) throws IOException { - super(out); - if (out == null || deflater == null) { - throw new NullPointerException(); - } - else if (size <= 0) { - throw new IllegalArgumentException("buffer size must be greater than 0"); - } - this.deflater = deflater; - buffer = new byte[size]; - this.close_out = close_out; - } - - @Override - public void write(int b) throws IOException { - buf1[0] = (byte)(b & 0xff); - write(buf1, 0, 1); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - if (deflater.finished()) { - throw new IOException("finished"); - } - else if (off<0 || len<0 || off+len>b.length) { - throw new IndexOutOfBoundsException(); - } - else if (len == 0) { - return; - } - else { - int flush = syncFlush ? JZlib.Z_SYNC_FLUSH : JZlib.Z_NO_FLUSH; - deflater.setInput(b, off, len, true); - while (deflater.avail_in>0) { - int err = deflate(flush); - if (err == JZlib.Z_STREAM_END) - break; - } - } - } - - void finish() throws IOException { - while (!deflater.finished()) { - deflate(JZlib.Z_FINISH); - } - } - - @Override - public void close() throws IOException { - if (!closed) { - finish(); - if (mydeflater){ - deflater.end(); - } - if(close_out) - out.close(); - closed = true; - } - } - - @SuppressWarnings("fallthrough") - protected int deflate(int flush) throws IOException { - deflater.setOutput(buffer, 0, buffer.length); - int err = deflater.deflate(flush); - switch(err) { - case JZlib.Z_OK: - case JZlib.Z_STREAM_END: - break; - case JZlib.Z_BUF_ERROR: - if(deflater.avail_in<=0 && flush!=JZlib.Z_FINISH){ - // flush() without any data - break; - } - default: - throw new IOException("failed to deflate: error="+err+" avail_out="+deflater.avail_out); - } - int len = deflater.next_out_index; - if (len > 0) { - out.write(buffer, 0, len); - } - return err; - } - - @Override - public void flush() throws IOException { - if (syncFlush && !deflater.finished()) { - while (true) { - int err = deflate(JZlib.Z_SYNC_FLUSH); - if (deflater.next_out_index < buffer.length) - break; - if (err == JZlib.Z_STREAM_END) - break; - } - } - out.flush(); - } - - long getTotalIn() { - return deflater.getTotalIn(); - } - - long getTotalOut() { - return deflater.getTotalOut(); - } - - void setSyncFlush(boolean syncFlush){ - this.syncFlush = syncFlush; - } - - boolean getSyncFlush(){ - return this.syncFlush; - } - - Deflater getDeflater(){ - return deflater; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/GZIPException.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/GZIPException.java deleted file mode 100644 index 97512b6f..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/GZIPException.java +++ /dev/null @@ -1,47 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jsch.jzlib; - -import java.io.IOException; - -final class GZIPException extends IOException { - private static final long serialVersionUID=-1L; - GZIPException() { - super(); - } - GZIPException(String s) { - super(s); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/GZIPHeader.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/GZIPHeader.java deleted file mode 100644 index 6469e265..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/GZIPHeader.java +++ /dev/null @@ -1,194 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jsch.jzlib; - -import java.nio.charset.StandardCharsets; -import java.util.Arrays; - -/** - * @see http://www.ietf.org/rfc/rfc1952.txt - */ -final class GZIPHeader implements Cloneable { - - static final byte OS_MSDOS = (byte) 0x00; - static final byte OS_AMIGA = (byte) 0x01; - static final byte OS_VMS = (byte) 0x02; - static final byte OS_UNIX = (byte) 0x03; - static final byte OS_ATARI = (byte) 0x05; - static final byte OS_OS2 = (byte) 0x06; - static final byte OS_MACOS = (byte) 0x07; - static final byte OS_TOPS20 = (byte) 0x0a; - static final byte OS_WIN32 = (byte) 0x0b; - static final byte OS_VMCMS = (byte) 0x04; - static final byte OS_ZSYSTEM = (byte) 0x08; - static final byte OS_CPM = (byte) 0x09; - static final byte OS_QDOS = (byte) 0x0c; - static final byte OS_RISCOS = (byte) 0x0d; - static final byte OS_UNKNOWN = (byte) 0xff; - - boolean text = false; - private boolean fhcrc = false; - int xflags; - int os = 255; - byte[] extra; - byte[] name; - byte[] comment; - int hcrc; - long crc; - boolean done = false; - long mtime = 0; - - void setModifiedTime(long mtime) { - this.mtime = mtime; - } - - long getModifiedTime() { - return mtime; - } - - void setOS(int os) { - if((0<=os && os <=13) || os==255) - this.os=os; - else - throw new IllegalArgumentException("os: "+os); - } - - int getOS(){ - return os; - } - - void setName(String name) { - this.name=name.getBytes(StandardCharsets.ISO_8859_1); - } - - String getName(){ - if(name==null) return ""; - return new String(name, StandardCharsets.ISO_8859_1); - } - - void setComment(String comment) { - this.comment=comment.getBytes(StandardCharsets.ISO_8859_1); - } - - String getComment(){ - if(comment==null) return ""; - return new String(comment, StandardCharsets.ISO_8859_1); - } - - void setCRC(long crc){ - this.crc = crc; - } - - long getCRC(){ - return crc; - } - - void put(Deflate d){ - int flag = 0; - if(text){ - flag |= 1; // FTEXT - } - if(fhcrc){ - flag |= 2; // FHCRC - } - if(extra!=null){ - flag |= 4; // FEXTRA - } - if(name!=null){ - flag |= 8; // FNAME - } - if(comment!=null){ - flag |= 16; // FCOMMENT - } - int xfl = 0; - if(d.level == JZlib.Z_BEST_SPEED){ - xfl |= 4; - } - else if (d.level == JZlib.Z_BEST_COMPRESSION){ - xfl |= 2; - } - - d.put_short((short)0x8b1f); // ID1 ID2 - d.put_byte((byte)8); // CM(Compression Method) - d.put_byte((byte)flag); - d.put_byte((byte)mtime); - d.put_byte((byte)(mtime>>8)); - d.put_byte((byte)(mtime>>16)); - d.put_byte((byte)(mtime>>24)); - d.put_byte((byte)xfl); - d.put_byte((byte)os); - - if(extra!=null){ - d.put_byte((byte)extra.length); - d.put_byte((byte)(extra.length>>8)); - d.put_byte(extra, 0, extra.length); - } - - if(name!=null){ - d.put_byte(name, 0, name.length); - d.put_byte((byte)0); - } - - if(comment!=null){ - d.put_byte(comment, 0, comment.length); - d.put_byte((byte)0); - } - } - - @Override - public Object clone() throws CloneNotSupportedException { - GZIPHeader gheader = (GZIPHeader)super.clone(); - byte[] tmp; - if(gheader.extra!=null){ - tmp=new byte[gheader.extra.length]; - System.arraycopy(gheader.extra, 0, tmp, 0, tmp.length); - gheader.extra = tmp; - } - - if(gheader.name!=null){ - tmp=new byte[gheader.name.length]; - System.arraycopy(gheader.name, 0, tmp, 0, tmp.length); - gheader.name = tmp; - } - - if(gheader.comment!=null){ - tmp=new byte[gheader.comment.length]; - System.arraycopy(gheader.comment, 0, tmp, 0, tmp.length); - gheader.comment = tmp; - } - - return gheader; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfBlocks.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfBlocks.java deleted file mode 100644 index ad6514d9..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfBlocks.java +++ /dev/null @@ -1,615 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jsch.jzlib; - -final class InfBlocks{ - static final private int MANY=1440; - - // And'ing with mask[n] masks the lower n bits - static final private int[] inflate_mask = { - 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, - 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, - 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, - 0x00007fff, 0x0000ffff - }; - - // Table for deflate from PKZIP's appnote.txt. - static final int[] border = { // Order of the bit length code lengths - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 - }; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - static final private int TYPE=0; // get type bits (3, including end bit) - static final private int LENS=1; // get lengths for stored - static final private int STORED=2;// processing stored block - static final private int TABLE=3; // get table lengths - static final private int BTREE=4; // get bit lengths tree for a dynamic block - static final private int DTREE=5; // get length, distance trees for a dynamic block - static final private int CODES=6; // processing fixed or dynamic block - static final private int DRY=7; // output remaining window bytes - static final private int DONE=8; // finished last block, done - static final private int BAD=9; // ot a data error--stuck here - - int mode; // current inflate_block mode - - int left; // if STORED, bytes left to copy - - int table; // table lengths (14 bits) - int index; // index into blens (or border) - int[] blens; // bit lengths of codes - int[] bb=new int[1]; // bit length tree depth - int[] tb=new int[1]; // bit length decoding tree - - int[] bl=new int[1]; - int[] bd=new int[1]; - - int[][] tl=new int[1][]; - int[][] td=new int[1][]; - int[] tli=new int[1]; // tl_index - int[] tdi=new int[1]; // td_index - - private final InfCodes codes; // if CODES, current state - - int last; // true if this block is the last block - - // mode independent information - int bitk; // bits in bit buffer - int bitb; // bit buffer - int[] hufts; // single malloc for tree space - byte[] window; // sliding window - int end; // one byte after sliding window - int read; // window read pointer - int write; // window write pointer - private boolean check; - - private final InfTree inftree=new InfTree(); - - private final ZStream z; - - InfBlocks(ZStream z, int w){ - this.z=z; - this.codes=new InfCodes(this.z, this); - hufts=new int[MANY*3]; - window=new byte[w]; - end=w; - this.check = (z.istate.wrap==0) ? false : true; - mode = TYPE; - reset(); - } - - void reset(){ - if(mode==BTREE || mode==DTREE){ - } - if(mode==CODES){ - codes.free(z); - } - mode=TYPE; - bitk=0; - bitb=0; - read=write=0; - if(check){ - z.adler.reset(); - } - } - - @SuppressWarnings("fallthrough") - int proc(int r){ - int t; // temporary storage - int b; // bit buffer - int k; // bits in bit buffer - int p; // input data pointer - int n; // bytes available there - int q; // output window write pointer - int m; // bytes to end of window or read pointer - - // copy input/output information to locals (UPDATE macro restores) - {p=z.next_in_index;n=z.avail_in;b=bitb;k=bitk;} - {q=write;m=(q>> 1){ - case 0: // stored - {b>>>=(3);k-=(3);} - t = k & 7; // go to byte boundary - - {b>>>=(t);k-=(t);} - mode = LENS; // get length of stored block - break; - case 1: // fixed - InfTree.inflate_trees_fixed(bl, bd, tl, td, z); - codes.init(bl[0], bd[0], tl[0], 0, td[0], 0); - - {b>>>=(3);k-=(3);} - - mode = CODES; - break; - case 2: // dynamic - - {b>>>=(3);k-=(3);} - - mode = TABLE; - break; - case 3: // illegal - - {b>>>=(3);k-=(3);} - mode = BAD; - z.msg = "invalid block type"; - r = Z_DATA_ERROR; - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - break; - case LENS: - - while(k<(32)){ - if(n!=0){ - r=Z_OK; - } - else{ - bitb=b; bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - }; - n--; - b|=(z.next_in[p++]&0xff)<>> 16) & 0xffff) != (b & 0xffff)){ - mode = BAD; - z.msg = "invalid stored block lengths"; - r = Z_DATA_ERROR; - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - left = (b & 0xffff); - b = k = 0; // dump bits - mode = left!=0 ? STORED : (last!=0 ? DRY : TYPE); - break; - case STORED: - if (n == 0){ - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - - if(m==0){ - if(q==end&&read!=0){ - q=0; m=(qn) t = n; - if(t>m) t = m; - System.arraycopy(z.next_in, p, window, q, t); - p += t; n -= t; - q += t; m -= t; - if ((left -= t) != 0) - break; - mode = last!=0 ? DRY : TYPE; - break; - case TABLE: - - while(k<(14)){ - if(n!=0){ - r=Z_OK; - } - else{ - bitb=b; bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - }; - n--; - b|=(z.next_in[p++]&0xff)< 29 || ((t >> 5) & 0x1f) > 29) - { - mode = BAD; - z.msg = "too many length or distance symbols"; - r = Z_DATA_ERROR; - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if(blens==null || blens.length>>=(14);k-=(14);} - - index = 0; - mode = BTREE; - case BTREE: - while (index < 4 + (table >>> 10)){ - while(k<(3)){ - if(n!=0){ - r=Z_OK; - } - else{ - bitb=b; bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - }; - n--; - b|=(z.next_in[p++]&0xff)<>>=(3);k-=(3);} - } - - while(index < 19){ - blens[border[index++]] = 0; - } - - bb[0] = 7; - t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z); - if (t != Z_OK){ - r = t; - if (r == Z_DATA_ERROR){ - blens=null; - mode = BAD; - } - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - - index = 0; - mode = DTREE; - case DTREE: - while (true){ - t = table; - if(!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){ - break; - } - - int[] h; - int i, j, c; - - t = bb[0]; - - while(k<(t)){ - if(n!=0){ - r=Z_OK; - } - else{ - bitb=b; bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - }; - n--; - b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); - blens[index++] = c; - } - else { // c == 16..18 - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - - while(k<(t+i)){ - if(n!=0){ - r=Z_OK; - } - else{ - bitb=b; bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - }; - n--; - b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); - - j += (b & inflate_mask[i]); - - b>>>=(i);k-=(i); - - i = index; - t = table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || - (c == 16 && i < 1)){ - blens=null; - mode = BAD; - z.msg = "invalid bit length repeat"; - r = Z_DATA_ERROR; - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - - c = c == 16 ? blens[i-1] : 0; - do{ - blens[i++] = c; - } - while (--j!=0); - index = i; - } - } - - tb[0]=-1; - { - bl[0] = 9; // must be <= 9 for lookahead assumptions - bd[0] = 6; // must be <= 9 for lookahead assumptions - t = table; - t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), - 1 + ((t >> 5) & 0x1f), - blens, bl, bd, tli, tdi, hufts, z); - - if (t != Z_OK){ - if (t == Z_DATA_ERROR){ - blens=null; - mode = BAD; - } - r = t; - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - codes.init(bl[0], bd[0], hufts, tli[0], hufts, tdi[0]); - } - mode = CODES; - case CODES: - bitb=b; bitk=k; - z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - - if ((r = codes.proc(r)) != Z_STREAM_END){ - return inflate_flush(r); - } - r = Z_OK; - codes.free(z); - - p=z.next_in_index; n=z.avail_in;b=bitb;k=bitk; - q=write;m=(q z.avail_out) n = z.avail_out; - if(n!=0 && r == Z_BUF_ERROR) r = Z_OK; - - // update counters - z.avail_out -= n; - z.total_out += n; - - // update check information - if(check && n>0){ - z.adler.update(window, q, n); - } - - // copy as far as end of window - System.arraycopy(window, q, z.next_out, p, n); - p += n; - q += n; - - // see if more to copy at beginning of window - if (q == end){ - // wrap pointers - q = 0; - if (write == end) - write = 0; - - // compute bytes to copy - n = write - q; - if (n > z.avail_out) n = z.avail_out; - if (n!=0 && r == Z_BUF_ERROR) r = Z_OK; - - // update counters - z.avail_out -= n; - z.total_out += n; - - // update check information - if(check && n>0){ - z.adler.update(window, q, n); - } - - // copy - System.arraycopy(window, q, z.next_out, p, n); - p += n; - q += n; - } - - // update pointers - z.next_out_index = p; - read = q; - - // done - return r; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfCodes.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfCodes.java deleted file mode 100644 index 4f411759..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfCodes.java +++ /dev/null @@ -1,611 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jsch.jzlib; - -final class InfCodes{ - - static final private int[] inflate_mask = { - 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, - 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, - 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, - 0x00007fff, 0x0000ffff - }; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - // waiting for "i:"=input, - // "o:"=output, - // "x:"=nothing - static final private int START=0; // x: set up for LEN - static final private int LEN=1; // i: get length/literal/eob next - static final private int LENEXT=2; // i: getting length extra (have base) - static final private int DIST=3; // i: get distance next - static final private int DISTEXT=4;// i: getting distance extra - static final private int COPY=5; // o: copying bytes in window, waiting for space - static final private int LIT=6; // o: got literal, waiting for output space - static final private int WASH=7; // o: got eob, possibly still output waiting - static final private int END=8; // x: got eob and all data flushed - static final private int BADCODE=9;// x: got error - - int mode; // current inflate_codes mode - - // mode dependent information - int len; - - int[] tree; // pointer into tree - int tree_index=0; - int need; // bits needed - - int lit; - - // if EXT or COPY, where and how much - int get; // bits to get for extra - int dist; // distance back to copy from - - byte lbits; // ltree bits decoded per branch - byte dbits; // dtree bits decoder per branch - int[] ltree; // literal/length/eob tree - int ltree_index; // literal/length/eob tree - int[] dtree; // distance tree - int dtree_index; // distance tree - - private final ZStream z; - private final InfBlocks s; - InfCodes(ZStream z, InfBlocks s){ - this.z=z; - this.s=s; - } - - void init(int bl, int bd, - int[] tl, int tl_index, - int[] td, int td_index){ - mode=START; - lbits=(byte)bl; - dbits=(byte)bd; - ltree=tl; - ltree_index=tl_index; - dtree = td; - dtree_index=td_index; - tree=null; - } - - @SuppressWarnings("fallthrough") - int proc(int r){ - int j; // temporary storage - int[] t; // temporary pointer - int tindex; // temporary pointer - int e; // extra bits or operation - int b=0; // bit buffer - int k=0; // bits in bit buffer - int p=0; // input data pointer - int n; // bytes available there - int q; // output window write pointer - int m; // bytes to end of window or read pointer - int f; // pointer to copy strings from - - // copy input/output information to locals (UPDATE macro restores) - p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; - q=s.write;m=q= 258 && n >= 10){ - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - r = inflate_fast(lbits, dbits, - ltree, ltree_index, - dtree, dtree_index, - s, z); - - p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; - q=s.write;m=q>>=(tree[tindex+1]); - k-=(tree[tindex+1]); - - e=tree[tindex]; - - if(e == 0){ // literal - lit = tree[tindex+2]; - mode = LIT; - break; - } - if((e & 16)!=0 ){ // length - get = e & 15; - len = tree[tindex+2]; - mode = LENEXT; - break; - } - if ((e & 64) == 0){ // next table - need = e; - tree_index = tindex/3+tree[tindex+2]; - break; - } - if ((e & 32)!=0){ // end of block - mode = WASH; - break; - } - mode = BADCODE; // invalid code - z.msg = "invalid literal/length code"; - r = Z_DATA_ERROR; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(r); - - case LENEXT: // i: getting length extra (have base) - j = get; - - while(k<(j)){ - if(n!=0)r=Z_OK; - else{ - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(r); - } - n--; b|=(z.next_in[p++]&0xff)<>=j; - k-=j; - - need = dbits; - tree = dtree; - tree_index=dtree_index; - mode = DIST; - case DIST: // i: get distance next - j = need; - - while(k<(j)){ - if(n!=0)r=Z_OK; - else{ - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(r); - } - n--; b|=(z.next_in[p++]&0xff)<>=tree[tindex+1]; - k-=tree[tindex+1]; - - e = (tree[tindex]); - if((e & 16)!=0){ // distance - get = e & 15; - dist = tree[tindex+2]; - mode = DISTEXT; - break; - } - if ((e & 64) == 0){ // next table - need = e; - tree_index = tindex/3 + tree[tindex+2]; - break; - } - mode = BADCODE; // invalid code - z.msg = "invalid distance code"; - r = Z_DATA_ERROR; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(r); - - case DISTEXT: // i: getting distance extra - j = get; - - while(k<(j)){ - if(n!=0)r=Z_OK; - else{ - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(r); - } - n--; b|=(z.next_in[p++]&0xff)<>=j; - k-=j; - - mode = COPY; - case COPY: // o: copying bytes in window, waiting for space - f = q - dist; - while(f < 0){ // modulo window size-"while" instead - f += s.end; // of "if" handles invalid distances - } - while (len!=0){ - - if(m==0){ - if(q==s.end&&s.read!=0){q=0;m=q 7){ // return unused byte, if any - k -= 8; - n++; - p--; // can always return one - } - - s.write=q; r=s.inflate_flush(r); - q=s.write;m=q= 258 && n >= 10 - // get literal/length code - while(k<(20)){ // max bits for literal/length code - n--; - b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); - - s.window[q++] = (byte)tp[tp_index_t_3+2]; - m--; - continue; - } - do { - - b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); - - if((e&16)!=0){ - e &= 15; - c = tp[tp_index_t_3+2] + (b & inflate_mask[e]); - - b>>=e; k-=e; - - // decode distance base of block to copy - while(k<(15)){ // max bits for distance code - n--; - b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); - - if((e&16)!=0){ - // get extra bits to add to distance base - e &= 15; - while(k<(e)){ // get extra bits (up to 13) - n--; - b|=(z.next_in[p++]&0xff)<>=(e); k-=(e); - - // do the copy - m -= c; - if (q >= d){ // offset before dest - // just copy - r=q-d; - if(q-r>0 && 2>(q-r)){ - s.window[q++]=s.window[r++]; // minimum count is three, - s.window[q++]=s.window[r++]; // so unroll loop a little - c-=2; - } - else{ - System.arraycopy(s.window, r, s.window, q, 2); - q+=2; r+=2; c-=2; - } - } - else{ // else offset after destination - r=q-d; - do{ - r+=s.end; // force pointer in window - }while(r<0); // covers invalid distances - e=s.end-r; - if(c>e){ // if source crosses, - c-=e; // wrapped copy - if(q-r>0 && e>(q-r)){ - do{s.window[q++] = s.window[r++];} - while(--e!=0); - } - else{ - System.arraycopy(s.window, r, s.window, q, e); - q+=e; r+=e; e=0; - } - r = 0; // copy rest from start of window - } - - } - - // copy all or what's left - if(q-r>0 && c>(q-r)){ - do{s.window[q++] = s.window[r++];} - while(--c!=0); - } - else{ - System.arraycopy(s.window, r, s.window, q, c); - q+=c; r+=c; c=0; - } - break; - } - else if((e&64)==0){ - t+=tp[tp_index_t_3+2]; - t+=(b&inflate_mask[e]); - tp_index_t_3=(tp_index+t)*3; - e=tp[tp_index_t_3]; - } - else{ - z.msg = "invalid distance code"; - - c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - - return Z_DATA_ERROR; - } - } - while(true); - break; - } - - if((e&64)==0){ - t+=tp[tp_index_t_3+2]; - t+=(b&inflate_mask[e]); - tp_index_t_3=(tp_index+t)*3; - if((e=tp[tp_index_t_3])==0){ - - b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); - - s.window[q++]=(byte)tp[tp_index_t_3+2]; - m--; - break; - } - } - else if((e&32)!=0){ - - c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - - return Z_STREAM_END; - } - else{ - z.msg="invalid literal/length code"; - - c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - - return Z_DATA_ERROR; - } - } - while(true); - } - while(m>=258 && n>= 10); - - // not enough input or output--restore pointers and return - c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - - return Z_OK; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfTree.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfTree.java deleted file mode 100644 index 409672cf..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfTree.java +++ /dev/null @@ -1,518 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jsch.jzlib; - -final class InfTree{ - - static final private int MANY=1440; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - static final int fixed_bl = 9; - static final int fixed_bd = 5; - - static final int[] fixed_tl = { - 96,7,256, 0,8,80, 0,8,16, 84,8,115, - 82,7,31, 0,8,112, 0,8,48, 0,9,192, - 80,7,10, 0,8,96, 0,8,32, 0,9,160, - 0,8,0, 0,8,128, 0,8,64, 0,9,224, - 80,7,6, 0,8,88, 0,8,24, 0,9,144, - 83,7,59, 0,8,120, 0,8,56, 0,9,208, - 81,7,17, 0,8,104, 0,8,40, 0,9,176, - 0,8,8, 0,8,136, 0,8,72, 0,9,240, - 80,7,4, 0,8,84, 0,8,20, 85,8,227, - 83,7,43, 0,8,116, 0,8,52, 0,9,200, - 81,7,13, 0,8,100, 0,8,36, 0,9,168, - 0,8,4, 0,8,132, 0,8,68, 0,9,232, - 80,7,8, 0,8,92, 0,8,28, 0,9,152, - 84,7,83, 0,8,124, 0,8,60, 0,9,216, - 82,7,23, 0,8,108, 0,8,44, 0,9,184, - 0,8,12, 0,8,140, 0,8,76, 0,9,248, - 80,7,3, 0,8,82, 0,8,18, 85,8,163, - 83,7,35, 0,8,114, 0,8,50, 0,9,196, - 81,7,11, 0,8,98, 0,8,34, 0,9,164, - 0,8,2, 0,8,130, 0,8,66, 0,9,228, - 80,7,7, 0,8,90, 0,8,26, 0,9,148, - 84,7,67, 0,8,122, 0,8,58, 0,9,212, - 82,7,19, 0,8,106, 0,8,42, 0,9,180, - 0,8,10, 0,8,138, 0,8,74, 0,9,244, - 80,7,5, 0,8,86, 0,8,22, 192,8,0, - 83,7,51, 0,8,118, 0,8,54, 0,9,204, - 81,7,15, 0,8,102, 0,8,38, 0,9,172, - 0,8,6, 0,8,134, 0,8,70, 0,9,236, - 80,7,9, 0,8,94, 0,8,30, 0,9,156, - 84,7,99, 0,8,126, 0,8,62, 0,9,220, - 82,7,27, 0,8,110, 0,8,46, 0,9,188, - 0,8,14, 0,8,142, 0,8,78, 0,9,252, - 96,7,256, 0,8,81, 0,8,17, 85,8,131, - 82,7,31, 0,8,113, 0,8,49, 0,9,194, - 80,7,10, 0,8,97, 0,8,33, 0,9,162, - 0,8,1, 0,8,129, 0,8,65, 0,9,226, - 80,7,6, 0,8,89, 0,8,25, 0,9,146, - 83,7,59, 0,8,121, 0,8,57, 0,9,210, - 81,7,17, 0,8,105, 0,8,41, 0,9,178, - 0,8,9, 0,8,137, 0,8,73, 0,9,242, - 80,7,4, 0,8,85, 0,8,21, 80,8,258, - 83,7,43, 0,8,117, 0,8,53, 0,9,202, - 81,7,13, 0,8,101, 0,8,37, 0,9,170, - 0,8,5, 0,8,133, 0,8,69, 0,9,234, - 80,7,8, 0,8,93, 0,8,29, 0,9,154, - 84,7,83, 0,8,125, 0,8,61, 0,9,218, - 82,7,23, 0,8,109, 0,8,45, 0,9,186, - 0,8,13, 0,8,141, 0,8,77, 0,9,250, - 80,7,3, 0,8,83, 0,8,19, 85,8,195, - 83,7,35, 0,8,115, 0,8,51, 0,9,198, - 81,7,11, 0,8,99, 0,8,35, 0,9,166, - 0,8,3, 0,8,131, 0,8,67, 0,9,230, - 80,7,7, 0,8,91, 0,8,27, 0,9,150, - 84,7,67, 0,8,123, 0,8,59, 0,9,214, - 82,7,19, 0,8,107, 0,8,43, 0,9,182, - 0,8,11, 0,8,139, 0,8,75, 0,9,246, - 80,7,5, 0,8,87, 0,8,23, 192,8,0, - 83,7,51, 0,8,119, 0,8,55, 0,9,206, - 81,7,15, 0,8,103, 0,8,39, 0,9,174, - 0,8,7, 0,8,135, 0,8,71, 0,9,238, - 80,7,9, 0,8,95, 0,8,31, 0,9,158, - 84,7,99, 0,8,127, 0,8,63, 0,9,222, - 82,7,27, 0,8,111, 0,8,47, 0,9,190, - 0,8,15, 0,8,143, 0,8,79, 0,9,254, - 96,7,256, 0,8,80, 0,8,16, 84,8,115, - 82,7,31, 0,8,112, 0,8,48, 0,9,193, - - 80,7,10, 0,8,96, 0,8,32, 0,9,161, - 0,8,0, 0,8,128, 0,8,64, 0,9,225, - 80,7,6, 0,8,88, 0,8,24, 0,9,145, - 83,7,59, 0,8,120, 0,8,56, 0,9,209, - 81,7,17, 0,8,104, 0,8,40, 0,9,177, - 0,8,8, 0,8,136, 0,8,72, 0,9,241, - 80,7,4, 0,8,84, 0,8,20, 85,8,227, - 83,7,43, 0,8,116, 0,8,52, 0,9,201, - 81,7,13, 0,8,100, 0,8,36, 0,9,169, - 0,8,4, 0,8,132, 0,8,68, 0,9,233, - 80,7,8, 0,8,92, 0,8,28, 0,9,153, - 84,7,83, 0,8,124, 0,8,60, 0,9,217, - 82,7,23, 0,8,108, 0,8,44, 0,9,185, - 0,8,12, 0,8,140, 0,8,76, 0,9,249, - 80,7,3, 0,8,82, 0,8,18, 85,8,163, - 83,7,35, 0,8,114, 0,8,50, 0,9,197, - 81,7,11, 0,8,98, 0,8,34, 0,9,165, - 0,8,2, 0,8,130, 0,8,66, 0,9,229, - 80,7,7, 0,8,90, 0,8,26, 0,9,149, - 84,7,67, 0,8,122, 0,8,58, 0,9,213, - 82,7,19, 0,8,106, 0,8,42, 0,9,181, - 0,8,10, 0,8,138, 0,8,74, 0,9,245, - 80,7,5, 0,8,86, 0,8,22, 192,8,0, - 83,7,51, 0,8,118, 0,8,54, 0,9,205, - 81,7,15, 0,8,102, 0,8,38, 0,9,173, - 0,8,6, 0,8,134, 0,8,70, 0,9,237, - 80,7,9, 0,8,94, 0,8,30, 0,9,157, - 84,7,99, 0,8,126, 0,8,62, 0,9,221, - 82,7,27, 0,8,110, 0,8,46, 0,9,189, - 0,8,14, 0,8,142, 0,8,78, 0,9,253, - 96,7,256, 0,8,81, 0,8,17, 85,8,131, - 82,7,31, 0,8,113, 0,8,49, 0,9,195, - 80,7,10, 0,8,97, 0,8,33, 0,9,163, - 0,8,1, 0,8,129, 0,8,65, 0,9,227, - 80,7,6, 0,8,89, 0,8,25, 0,9,147, - 83,7,59, 0,8,121, 0,8,57, 0,9,211, - 81,7,17, 0,8,105, 0,8,41, 0,9,179, - 0,8,9, 0,8,137, 0,8,73, 0,9,243, - 80,7,4, 0,8,85, 0,8,21, 80,8,258, - 83,7,43, 0,8,117, 0,8,53, 0,9,203, - 81,7,13, 0,8,101, 0,8,37, 0,9,171, - 0,8,5, 0,8,133, 0,8,69, 0,9,235, - 80,7,8, 0,8,93, 0,8,29, 0,9,155, - 84,7,83, 0,8,125, 0,8,61, 0,9,219, - 82,7,23, 0,8,109, 0,8,45, 0,9,187, - 0,8,13, 0,8,141, 0,8,77, 0,9,251, - 80,7,3, 0,8,83, 0,8,19, 85,8,195, - 83,7,35, 0,8,115, 0,8,51, 0,9,199, - 81,7,11, 0,8,99, 0,8,35, 0,9,167, - 0,8,3, 0,8,131, 0,8,67, 0,9,231, - 80,7,7, 0,8,91, 0,8,27, 0,9,151, - 84,7,67, 0,8,123, 0,8,59, 0,9,215, - 82,7,19, 0,8,107, 0,8,43, 0,9,183, - 0,8,11, 0,8,139, 0,8,75, 0,9,247, - 80,7,5, 0,8,87, 0,8,23, 192,8,0, - 83,7,51, 0,8,119, 0,8,55, 0,9,207, - 81,7,15, 0,8,103, 0,8,39, 0,9,175, - 0,8,7, 0,8,135, 0,8,71, 0,9,239, - 80,7,9, 0,8,95, 0,8,31, 0,9,159, - 84,7,99, 0,8,127, 0,8,63, 0,9,223, - 82,7,27, 0,8,111, 0,8,47, 0,9,191, - 0,8,15, 0,8,143, 0,8,79, 0,9,255 - }; - static final int[] fixed_td = { - 80,5,1, 87,5,257, 83,5,17, 91,5,4097, - 81,5,5, 89,5,1025, 85,5,65, 93,5,16385, - 80,5,3, 88,5,513, 84,5,33, 92,5,8193, - 82,5,9, 90,5,2049, 86,5,129, 192,5,24577, - 80,5,2, 87,5,385, 83,5,25, 91,5,6145, - 81,5,7, 89,5,1537, 85,5,97, 93,5,24577, - 80,5,4, 88,5,769, 84,5,49, 92,5,12289, - 82,5,13, 90,5,3073, 86,5,193, 192,5,24577 - }; - - // Tables for deflate from PKZIP's appnote.txt. - static final int[] cplens = { // Copy lengths for literal codes 257..285 - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 - }; - - // see note #13 above about 258 - static final int[] cplext = { // Extra bits for literal codes 257..285 - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid - }; - - static final int[] cpdist = { // Copy offsets for distance codes 0..29 - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577 - }; - - static final int[] cpdext = { // Extra bits for distance codes - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13}; - - // If BMAX needs to be larger than 16, then h and x[] should be uLong. - static final int BMAX=15; // maximum bit length of any code - - int[] hn = null; // hufts used in space - int[] v = null; // work area for huft_build - int[] c = null; // bit length count table - int[] r = null; // table entry for structure assignment - int[] u = null; // table stack - int[] x = null; // bit offsets, then code stack - - private int huft_build(int[] b, // code lengths in bits (all assumed <= BMAX) - int bindex, - int n, // number of codes (assumed <= 288) - int s, // number of simple-valued codes (0..s-1) - int[] d, // list of base values for non-simple codes - int[] e, // list of extra bits for non-simple codes - int[] t, // result: starting table - int[] m, // maximum lookup bits, returns actual - int[] hp,// space for trees - int[] hn,// hufts used in space - int[] v // working area: values in order of bit length - ){ - // Given a list of code lengths and a maximum table size, make a set of - // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - // if the given code set is incomplete (the tables are still built in this - // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of - // lengths), or Z_MEM_ERROR if not enough memory. - - int a; // counter for codes of length k - int f; // i repeats in table every f entries - int g; // maximum code length - int h; // table level - int i; // counter, current code - int j; // counter - int k; // number of bits in current code - int l; // bits per table (returned in m) - int mask; // (1 << w) - 1, to avoid cc -O bug on HP - int p; // pointer into c[], b[], or v[] - int q; // points to current table - int w; // bits before this table == (l * h) - int xp; // pointer into x - int y; // number of dummy codes added - int z; // number of entries in current table - - // Generate counts for each bit length - - p = 0; i = n; - do { - c[b[bindex+p]]++; p++; i--; // assume all entries <= BMAX - }while(i!=0); - - if(c[0] == n){ // null input--all zero length codes - t[0] = -1; - m[0] = 0; - return Z_OK; - } - - // Find minimum and maximum length, bound *m by those - l = m[0]; - for (j = 1; j <= BMAX; j++) - if(c[j]!=0) break; - k = j; // minimum code length - if(l < j){ - l = j; - } - for (i = BMAX; i!=0; i--){ - if(c[i]!=0) break; - } - g = i; // maximum code length - if(l > i){ - l = i; - } - m[0] = l; - - // Adjust last length count to fill out codes, if needed - for (y = 1 << j; j < i; j++, y <<= 1){ - if ((y -= c[j]) < 0){ - return Z_DATA_ERROR; - } - } - if ((y -= c[i]) < 0){ - return Z_DATA_ERROR; - } - c[i] += y; - - // Generate starting offsets into the value table for each length - x[1] = j = 0; - p = 1; xp = 2; - while (--i!=0) { // note that i == g from above - x[xp] = (j += c[p]); - xp++; - p++; - } - - // Make a table of values in order of bit lengths - i = 0; p = 0; - do { - if ((j = b[bindex+p]) != 0){ - v[x[j]++] = i; - } - p++; - } - while (++i < n); - n = x[g]; // set n to length of v - - // Generate the Huffman codes and for each, make the table entries - x[0] = i = 0; // first Huffman code is zero - p = 0; // grab values in bit order - h = -1; // no tables yet--level -1 - w = -l; // bits decoded == (l * h) - u[0] = 0; // just to keep compilers happy - q = 0; // ditto - z = 0; // ditto - - // go through the bit lengths (k already is bits in shortest code) - for (; k <= g; k++){ - a = c[k]; - while (a--!=0){ - // here i is the Huffman code of length k bits for value *p - // make tables up to required level - while (k > w + l){ - h++; - w += l; // previous table always l bits - // compute minimum size table less than or equal to l bits - z = g - w; - z = (z > l) ? l : z; // table size upper limit - if((f=1<<(j=k-w))>a+1){ // try a k-w bit table - // too few codes for k-w bit table - f -= a + 1; // deduct codes from patterns left - xp = k; - if(j < z){ - while (++j < z){ // try smaller tables up to z bits - if((f <<= 1) <= c[++xp]) - break; // enough codes to use up j bits - f -= c[xp]; // else deduct codes from patterns - } - } - } - z = 1 << j; // table entries for j-bit table - - // allocate new table - if (hn[0] + z > MANY){ // (note: doesn't matter for fixed) - return Z_DATA_ERROR; // overflow of MANY - } - u[h] = q = /*hp+*/ hn[0]; // DEBUG - hn[0] += z; - - // connect to last table, if there is one - if(h!=0){ - x[h]=i; // save pattern for backing up - r[0]=(byte)j; // bits in this table - r[1]=(byte)l; // bits to dump before this table - j=i>>>(w - l); - r[2] = q - u[h-1] - j; // offset to this table - System.arraycopy(r, 0, hp, (u[h-1]+j)*3, 3); // connect to last table - } - else{ - t[0] = q; // first table is returned result - } - } - - // set up table entry in r - r[1] = (byte)(k - w); - if (p >= n){ - r[0] = 128 + 64; // out of values--invalid code - } - else if (v[p] < s){ - r[0] = (byte)(v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block - r[2] = v[p++]; // simple code is just the value - } - else{ - r[0]=(byte)(e[v[p]-s]+16+64); // non-simple--look up in lists - r[2]=d[v[p++] - s]; - } - - // fill code-like entries with r - f=1<<(k-w); - for (j=i>>>w;j>>= 1){ - i ^= j; - } - i ^= j; - - // backup over finished tables - mask = (1 << w) - 1; // needed on HP, cc -O bug - while ((i & mask) != x[h]){ - h--; // don't need to update q - w -= l; - mask = (1 << w) - 1; - } - } - } - // Return Z_BUF_ERROR if we were given an incomplete table - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; - } - - int inflate_trees_bits(int[] c, // 19 code lengths - int[] bb, // bits tree desired/actual depth - int[] tb, // bits tree result - int[] hp, // space for trees - ZStream z // for messages - ){ - int result; - initWorkArea(19); - hn[0]=0; - result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); - - if(result == Z_DATA_ERROR){ - z.msg = "oversubscribed dynamic bit lengths tree"; - } - else if(result == Z_BUF_ERROR || bb[0] == 0){ - z.msg = "incomplete dynamic bit lengths tree"; - result = Z_DATA_ERROR; - } - return result; - } - - int inflate_trees_dynamic(int nl, // number of literal/length codes - int nd, // number of distance codes - int[] c, // that many (total) code lengths - int[] bl, // literal desired/actual bit depth - int[] bd, // distance desired/actual bit depth - int[] tl, // literal/length tree result - int[] td, // distance tree result - int[] hp, // space for trees - ZStream z // for messages - ){ - int result; - - // build literal/length tree - initWorkArea(288); - hn[0]=0; - result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); - if (result != Z_OK || bl[0] == 0){ - if(result == Z_DATA_ERROR){ - z.msg = "oversubscribed literal/length tree"; - } - else if (result != Z_MEM_ERROR){ - z.msg = "incomplete literal/length tree"; - result = Z_DATA_ERROR; - } - return result; - } - - // build distance tree - initWorkArea(288); - result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); - - if (result != Z_OK || (bd[0] == 0 && nl > 257)){ - if (result == Z_DATA_ERROR){ - z.msg = "oversubscribed distance tree"; - } - else if (result == Z_BUF_ERROR) { - z.msg = "incomplete distance tree"; - result = Z_DATA_ERROR; - } - else if (result != Z_MEM_ERROR){ - z.msg = "empty distance tree with lengths"; - result = Z_DATA_ERROR; - } - return result; - } - - return Z_OK; - } - - static int inflate_trees_fixed(int[] bl, //literal desired/actual bit depth - int[] bd, //distance desired/actual bit depth - int[][] tl,//literal/length tree result - int[][] td,//distance tree result - ZStream z //for memory allocation - ){ - bl[0]=fixed_bl; - bd[0]=fixed_bd; - tl[0]=fixed_tl; - td[0]=fixed_td; - return Z_OK; - } - - private void initWorkArea(int vsize){ - if(hn==null){ - hn=new int[1]; - v=new int[vsize]; - c=new int[BMAX+1]; - r=new int[3]; - u=new int[BMAX]; - x=new int[BMAX+1]; - } - if(v.length> 4) + 1; - if(w < 48) - w &= 15; - } - - if(w<8 ||w>15){ - inflateEnd(); - return Z_STREAM_ERROR; - } - if(blocks != null && wbits != w){ - blocks.free(); - blocks=null; - } - - // set window size - wbits=w; - - this.blocks=new InfBlocks(z, 1<>8))&0xff; - - if(((wrap&1)==0 || // check if zlib header allowed - (((this.method << 8)+b) % 31)!=0) && - (this.method&0xf)!=Z_DEFLATED){ - if(wrap == 4){ - z.next_in_index -= 2; - z.avail_in += 2; - z.total_in -= 2; - wrap = 0; - this.mode = BLOCKS; - break; - } - this.mode = BAD; - z.msg = "incorrect header check"; - // since zlib 1.2, it is allowted to inflateSync for this case. - /* - this.marker = 5; // can't try inflateSync - */ - break; - } - - if((this.method&0xf)!=Z_DEFLATED){ - this.mode = BAD; - z.msg="unknown compression method"; - // since zlib 1.2, it is allowted to inflateSync for this case. - /* - this.marker = 5; // can't try inflateSync - */ - break; - } - - if(wrap == 4){ - wrap = 1; - } - - if((this.method>>4)+8>this.wbits){ - this.mode = BAD; - z.msg="invalid window size"; - // since zlib 1.2, it is allowted to inflateSync for this case. - /* - this.marker = 5; // can't try inflateSync - */ - break; - } - - z.adler=new Adler32(); - - if((b&PRESET_DICT)==0){ - this.mode = BLOCKS; - break; - } - this.mode = DICT4; - case DICT4: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; - this.mode=DICT3; - case DICT3: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; - this.mode=DICT2; - case DICT2: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; - this.mode=DICT1; - case DICT1: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need += (z.next_in[z.next_in_index++]&0xffL); - z.adler.reset(this.need); - this.mode = DICT0; - return Z_NEED_DICT; - case DICT0: - this.mode = BAD; - z.msg = "need dictionary"; - this.marker = 0; // can try inflateSync - return Z_STREAM_ERROR; - case BLOCKS: - r = this.blocks.proc(r); - if(r == Z_DATA_ERROR){ - this.mode = BAD; - this.marker = 0; // can try inflateSync - break; - } - if(r == Z_OK){ - r = f; - } - if(r != Z_STREAM_END){ - return r; - } - r = f; - this.was=z.adler.getValue(); - this.blocks.reset(); - if(this.wrap==0){ - this.mode=DONE; - break; - } - this.mode=CHECK4; - case CHECK4: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; - this.mode=CHECK3; - case CHECK3: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; - this.mode = CHECK2; - case CHECK2: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; - this.mode = CHECK1; - case CHECK1: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=(z.next_in[z.next_in_index++]&0xffL); - - if(flags!=0){ // gzip - this.need = ((this.need&0xff000000)>>24 | - (this.need&0x00ff0000)>>8 | - (this.need&0x0000ff00)<<8 | - (this.need&0x0000ffff)<<24)&0xffffffffL; - } - - if(((int)(this.was)) != ((int)(this.need))){ - z.msg = "incorrect data check"; - // chack is delayed - /* - this.mode = BAD; - this.marker = 5; // can't try inflateSync - break; - */ - } - else if(flags!=0 && gheader!=null){ - gheader.crc = this.need; - } - - this.mode = LENGTH; - case LENGTH: - if (wrap!=0 && flags!=0) { - - try { r=readBytes(4, r, f); } - catch(Return e){ return e.r; } - - if(z.msg!=null && z.msg.equals("incorrect data check")){ - this.mode = BAD; - this.marker = 5; // can't try inflateSync - break; - } - - if (this.need != (z.total_out & 0xffffffffL)) { - z.msg = "incorrect length check"; - this.mode = BAD; - break; - } - z.msg = null; - } - else { - if(z.msg!=null && z.msg.equals("incorrect data check")){ - this.mode = BAD; - this.marker = 5; // can't try inflateSync - break; - } - } - - this.mode = DONE; - case DONE: - return Z_STREAM_END; - case BAD: - return Z_DATA_ERROR; - - case FLAGS: - - try { r=readBytes(2, r, f); } - catch(Return e){ return e.r; } - - flags = ((int)this.need)&0xffff; - - if ((flags & 0xff) != Z_DEFLATED) { - z.msg = "unknown compression method"; - this.mode = BAD; - break; - } - if ((flags & 0xe000)!=0) { - z.msg = "unknown header flags set"; - this.mode = BAD; - break; - } - - if ((flags & 0x0200)!=0){ - checksum(2, this.need); - } - - this.mode = TIME; - - case TIME: - try { r=readBytes(4, r, f); } - catch(Return e){ return e.r; } - if(gheader!=null){ - gheader.setModifiedTime(this.need); - } - if ((flags & 0x0200)!=0){ - checksum(4, this.need); - } - this.mode = OS; - case OS: - try { r=readBytes(2, r, f); } - catch(Return e){ return e.r; } - if(gheader!=null){ - gheader.xflags = ((int)this.need)&0xff; - gheader.os = (((int)this.need)>>8)&0xff; - } - if ((flags & 0x0200)!=0){ - checksum(2, this.need); - } - this.mode = EXLEN; - case EXLEN: - if ((flags & 0x0400)!=0) { - try { r=readBytes(2, r, f); } - catch(Return e){ return e.r; } - if(gheader!=null){ - gheader.extra = new byte[((int)this.need)&0xffff]; - } - if ((flags & 0x0200)!=0){ - checksum(2, this.need); - } - } - else if(gheader!=null){ - gheader.extra=null; - } - this.mode = EXTRA; - - case EXTRA: - if ((flags & 0x0400)!=0) { - try { - r=readBytes(r, f); - if(gheader!=null){ - byte[] foo = tmp_string.toByteArray(); - tmp_string=null; - if(foo.length == gheader.extra.length){ - System.arraycopy(foo, 0, gheader.extra, 0, foo.length); - } - else{ - z.msg = "bad extra field length"; - this.mode = BAD; - break; - } - } - } - catch(Return e){ return e.r; } - } - else if(gheader!=null){ - gheader.extra=null; - } - this.mode = NAME; - case NAME: - if ((flags & 0x0800)!=0) { - try { - r=readString(r, f); - if(gheader!=null){ - gheader.name=tmp_string.toByteArray(); - } - tmp_string=null; - } - catch(Return e){ return e.r; } - } - else if(gheader!=null){ - gheader.name=null; - } - this.mode = COMMENT; - case COMMENT: - if ((flags & 0x1000)!=0) { - try { - r=readString(r, f); - if(gheader!=null){ - gheader.comment=tmp_string.toByteArray(); - } - tmp_string=null; - } - catch(Return e){ return e.r; } - } - else if(gheader!=null){ - gheader.comment=null; - } - this.mode = HCRC; - case HCRC: - if ((flags & 0x0200)!=0) { - try { r=readBytes(2, r, f); } - catch(Return e){ return e.r; } - if(gheader!=null){ - gheader.hcrc=(int)(this.need&0xffff); - } - if(this.need != (z.adler.getValue()&0xffffL)){ - this.mode = BAD; - z.msg = "header crc mismatch"; - this.marker = 5; // can't try inflateSync - break; - } - } - z.adler = new CRC32(); - - this.mode = BLOCKS; - break; - default: - return Z_STREAM_ERROR; - } - } - } - - int inflateSetDictionary(byte[] dictionary, int dictLength){ - if(z==null || (this.mode != DICT0 && this.wrap != 0)){ - return Z_STREAM_ERROR; - } - - int index=0; - int length = dictLength; - - if(this.mode==DICT0){ - long adler_need=z.adler.getValue(); - z.adler.reset(); - z.adler.update(dictionary, 0, dictLength); - if(z.adler.getValue()!=adler_need){ - return Z_DATA_ERROR; - } - } - - z.adler.reset(); - - if(length >= (1<0){ - if(z.avail_in==0){ throw new Return(r); }; r=f; - z.avail_in--; z.total_in++; - this.need = this.need | - ((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8)); - need_bytes--; - } - if(n==2){ - this.need&=0xffffL; - } - else if(n==4) { - this.need&=0xffffffffL; - } - need_bytes=-1; - return r; - } - static class Return extends Exception{ - private static final long serialVersionUID=-1L; - int r; - Return(int r){this.r=r; } - } - - private ByteArrayOutputStream tmp_string = null; - private int readString(int r, int f) throws Return{ - if(tmp_string == null){ - tmp_string=new ByteArrayOutputStream(); - } - int b=0; - do { - if(z.avail_in==0){ throw new Return(r); }; r=f; - z.avail_in--; z.total_in++; - b = z.next_in[z.next_in_index]; - if(b!=0) tmp_string.write(z.next_in, z.next_in_index, 1); - z.adler.update(z.next_in, z.next_in_index, 1); - z.next_in_index++; - }while(b!=0); - return r; - } - - private int readBytes(int r, int f) throws Return{ - if(tmp_string == null){ - tmp_string=new ByteArrayOutputStream(); - } - int b=0; - while(this.need>0){ - if(z.avail_in==0){ throw new Return(r); }; r=f; - z.avail_in--; z.total_in++; - b = z.next_in[z.next_in_index]; - tmp_string.write(z.next_in, z.next_in_index, 1); - z.adler.update(z.next_in, z.next_in_index, 1); - z.next_in_index++; - this.need--; - } - return r; - } - - private void checksum(int n, long v){ - for(int i=0; i>=8; - } - z.adler.update(crcbuf, 0, n); - } - - GZIPHeader getGZIPHeader(){ - return gheader; - } - - boolean inParsingHeader(){ - switch(mode){ - case HEAD: - case DICT4: - case DICT3: - case DICT2: - case DICT1: - case FLAGS: - case TIME: - case OS: - case EXLEN: - case EXTRA: - case NAME: - case COMMENT: - case HCRC: - return true; - default: - return false; - } - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Inflater.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Inflater.java deleted file mode 100644 index 84d22ce8..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Inflater.java +++ /dev/null @@ -1,189 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jsch.jzlib; - -final class Inflater extends ZStream{ - - static final private int MAX_WBITS=15; // 32K LZ77 window - static final private int DEF_WBITS=MAX_WBITS; - - static final private int Z_NO_FLUSH=0; - static final private int Z_PARTIAL_FLUSH=1; - static final private int Z_SYNC_FLUSH=2; - static final private int Z_FULL_FLUSH=3; - static final private int Z_FINISH=4; - - static final private int MAX_MEM_LEVEL=9; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - private int param_w = -1; - private JZlib.WrapperType param_wrapperType = null; - private boolean param_nowrap = false; - - Inflater() { - super(); - init(); - } - - Inflater(JZlib.WrapperType wrapperType) throws GZIPException { - this(DEF_WBITS, wrapperType); - } - - Inflater(int w, JZlib.WrapperType wrapperType) throws GZIPException { - super(); - param_w = w; - param_wrapperType = wrapperType; - int ret = init(w, wrapperType); - if(ret!=Z_OK) - throw new GZIPException(ret+": "+msg); - } - - Inflater(int w) throws GZIPException { - this(w, false); - } - - Inflater(boolean nowrap) throws GZIPException { - this(DEF_WBITS, nowrap); - } - - Inflater(int w, boolean nowrap) throws GZIPException { - super(); - param_w = w; - param_nowrap = nowrap; - int ret = init(w, nowrap); - if(ret!=Z_OK) - throw new GZIPException(ret+": "+msg); - } - - void reset() { - finished = false; - if(param_wrapperType != null){ - init(param_w, param_wrapperType); - } - else { - init(param_w, param_nowrap); - } - } - - private boolean finished = false; - - int init(){ - return init(DEF_WBITS); - } - - int init(JZlib.WrapperType wrapperType){ - return init(DEF_WBITS, wrapperType); - } - - int init(int w, JZlib.WrapperType wrapperType) { - boolean nowrap = false; - if(wrapperType == JZlib.W_NONE){ - nowrap = true; - } - else if(wrapperType == JZlib.W_GZIP) { - w += 16; - } - else if(wrapperType == JZlib.W_ANY) { - w |= Inflate.INFLATE_ANY; - } - else if(wrapperType == JZlib.W_ZLIB) { - } - return init(w, nowrap); - } - - int init(boolean nowrap){ - return init(DEF_WBITS, nowrap); - } - - int init(int w){ - return init(w, false); - } - - int init(int w, boolean nowrap){ - finished = false; - istate=new Inflate(this); - return istate.inflateInit(nowrap?-w:w); - } - - @Override - int inflate(int f){ - if(istate==null) return Z_STREAM_ERROR; - int ret = istate.inflate(f); - if(ret == Z_STREAM_END) - finished = true; - return ret; - } - - @Override - int end(){ - finished = true; - if(istate==null) return Z_STREAM_ERROR; - int ret=istate.inflateEnd(); -// istate = null; - return ret; - } - - int sync(){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSync(); - } - - int syncPoint(){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSyncPoint(); - } - - int setDictionary(byte[] dictionary, int dictLength){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSetDictionary(dictionary, dictLength); - } - - @Override - boolean finished(){ - return istate.mode==12 /*DONE*/; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InflaterInputStream.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InflaterInputStream.java deleted file mode 100644 index 2dcbf82f..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InflaterInputStream.java +++ /dev/null @@ -1,255 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.jcraft.jsch.jzlib; -import java.io.*; - -final class InflaterInputStream extends FilterInputStream { - protected final Inflater inflater; - protected byte[] buf; - - private boolean closed = false; - - protected boolean eof = false; - - private boolean close_in = true; - - protected static final int DEFAULT_BUFSIZE = 512; - - InflaterInputStream(InputStream in) throws IOException { - this(in, false); - } - - InflaterInputStream(InputStream in, boolean nowrap) throws IOException { - this(in, new Inflater(nowrap)); - myinflater = true; - } - - InflaterInputStream(InputStream in, Inflater inflater) throws IOException { - this(in, inflater, DEFAULT_BUFSIZE); - } - - InflaterInputStream(InputStream in, - Inflater inflater, int size) throws IOException { - this(in, inflater, size, true); - } - - InflaterInputStream(InputStream in, - Inflater inflater, - int size, boolean close_in) throws IOException { - super(in); - if (in == null || inflater == null) { - throw new NullPointerException(); - } - else if (size <= 0) { - throw new IllegalArgumentException("buffer size must be greater than 0"); - } - this.inflater = inflater; - buf = new byte[size]; - this.close_in = close_in; - } - - protected boolean myinflater = false; - - private byte[] byte1 = new byte[1]; - - @Override - public int read() throws IOException { - if (closed) { throw new IOException("Stream closed"); } - return read(byte1, 0, 1) == -1 ? -1 : byte1[0] & 0xff; - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - if (closed) { throw new IOException("Stream closed"); } - if (b == null) { - throw new NullPointerException(); - } - else if (off < 0 || len < 0 || len > b.length - off) { - throw new IndexOutOfBoundsException(); - } - else if (len == 0) { - return 0; - } - else if (eof) { - return -1; - } - - int n = 0; - inflater.setOutput(b, off, len); - while(!eof) { - if(inflater.avail_in==0) - fill(); - int err = inflater.inflate(JZlib.Z_NO_FLUSH); - n += inflater.next_out_index - off; - off = inflater.next_out_index; - switch(err) { - case JZlib.Z_DATA_ERROR: - throw new IOException(inflater.msg); - case JZlib.Z_STREAM_END: - case JZlib.Z_NEED_DICT: - eof = true; - if(err == JZlib.Z_NEED_DICT) - return -1; - break; - default: - } - if(inflater.avail_out==0) - break; - } - return n; - } - - @Override - public int available() throws IOException { - if (closed) { throw new IOException("Stream closed"); } - if (eof) { - return 0; - } - else { - return 1; - } - } - - private byte[] b = new byte[512]; - - @Override - public long skip(long n) throws IOException { - if (n < 0) { - throw new IllegalArgumentException("negative skip length"); - } - - if (closed) { throw new IOException("Stream closed"); } - - int max = (int)Math.min(n, Integer.MAX_VALUE); - int total = 0; - while (total < max) { - int len = max - total; - if (len > b.length) { - len = b.length; - } - len = read(b, 0, len); - if (len == -1) { - eof = true; - break; - } - total += len; - } - return total; - } - - @Override - public void close() throws IOException { - if (!closed) { - if (myinflater) - inflater.end(); - if(close_in) - in.close(); - closed = true; - } - } - - protected void fill() throws IOException { - if (closed) { throw new IOException("Stream closed"); } - int len = in.read(buf, 0, buf.length); - if (len == -1) { - if(inflater.istate.wrap == 0 && - !inflater.finished()){ - buf[0]=0; - len=1; - } - else if(inflater.istate.was != -1){ // in reading trailer - throw new IOException("footer is not found"); - } - else{ - throw new EOFException("Unexpected end of ZLIB input stream"); - } - } - inflater.setInput(buf, 0, len, true); - } - - @Override - public boolean markSupported() { - return false; - } - - @Override - public synchronized void mark(int readlimit) { - } - - @Override - public synchronized void reset() throws IOException { - throw new IOException("mark/reset not supported"); - } - - long getTotalIn() { - return inflater.getTotalIn(); - } - - long getTotalOut() { - return inflater.getTotalOut(); - } - - byte[] getAvailIn() { - if(inflater.avail_in<=0) - return null; - byte[] tmp = new byte[inflater.avail_in]; - System.arraycopy(inflater.next_in, inflater.next_in_index, - tmp, 0, inflater.avail_in); - return tmp; - } - - void readHeader() throws IOException { - - byte[] empty = "".getBytes(); - inflater.setInput(empty, 0, 0, false); - inflater.setOutput(empty, 0, 0); - - int err = inflater.inflate(JZlib.Z_NO_FLUSH); - if(!inflater.istate.inParsingHeader()){ - return; - } - - byte[] b1 = new byte[1]; - do{ - int i = in.read(b1); - if(i<=0) - throw new IOException("no input"); - inflater.setInput(b1); - err = inflater.inflate(JZlib.Z_NO_FLUSH); - if(err!=0/*Z_OK*/) - throw new IOException(inflater.msg); - } - while(inflater.istate.inParsingHeader()); - } - - Inflater getInflater(){ - return inflater; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/JZlib.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/JZlib.java deleted file mode 100644 index 1d127559..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/JZlib.java +++ /dev/null @@ -1,92 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jsch.jzlib; - -final class JZlib{ - private static final String version="1.1.3"; - static String version(){return version;} - - static final int MAX_WBITS=15; // 32K LZ77 window - static final int DEF_WBITS=MAX_WBITS; - - enum WrapperType { - NONE, ZLIB, GZIP, ANY - } - - static final WrapperType W_NONE = WrapperType.NONE; - static final WrapperType W_ZLIB = WrapperType.ZLIB; - static final WrapperType W_GZIP = WrapperType.GZIP; - static final WrapperType W_ANY = WrapperType.ANY; - - // compression levels - static final int Z_NO_COMPRESSION=0; - static final int Z_BEST_SPEED=1; - static final int Z_BEST_COMPRESSION=9; - static final int Z_DEFAULT_COMPRESSION=(-1); - - // compression strategy - static final int Z_FILTERED=1; - static final int Z_HUFFMAN_ONLY=2; - static final int Z_DEFAULT_STRATEGY=0; - - static final int Z_NO_FLUSH=0; - static final int Z_PARTIAL_FLUSH=1; - static final int Z_SYNC_FLUSH=2; - static final int Z_FULL_FLUSH=3; - static final int Z_FINISH=4; - - static final int Z_OK=0; - static final int Z_STREAM_END=1; - static final int Z_NEED_DICT=2; - static final int Z_ERRNO=-1; - static final int Z_STREAM_ERROR=-2; - static final int Z_DATA_ERROR=-3; - static final int Z_MEM_ERROR=-4; - static final int Z_BUF_ERROR=-5; - static final int Z_VERSION_ERROR=-6; - - // The three kinds of block type - static final byte Z_BINARY = 0; - static final byte Z_ASCII = 1; - static final byte Z_UNKNOWN = 2; - - static long adler32_combine(long adler1, long adler2, long len2){ - return Adler32.combine(adler1, adler2, len2); - } - - static long crc32_combine(long crc1, long crc2, long len2){ - return CRC32.combine(crc1, crc2, len2); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/StaticTree.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/StaticTree.java deleted file mode 100644 index 219c72b4..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/StaticTree.java +++ /dev/null @@ -1,148 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jsch.jzlib; - -final class StaticTree{ - static final private int MAX_BITS=15; - - static final private int BL_CODES=19; - static final private int D_CODES=30; - static final private int LITERALS=256; - static final private int LENGTH_CODES=29; - static final private int L_CODES=(LITERALS+1+LENGTH_CODES); - - // Bit length codes must not exceed MAX_BL_BITS bits - static final int MAX_BL_BITS=7; - - static final short[] static_ltree = { - 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, - 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, - 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, - 252, 8, 2, 8, 130, 8, 66, 8, 194, 8, - 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, - 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, - 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, - 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, - 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, - 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, - 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, - 230, 8, 22, 8, 150, 8, 86, 8, 214, 8, - 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, - 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, - 110, 8, 238, 8, 30, 8, 158, 8, 94, 8, - 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, - 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, - 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, - 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, - 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, - 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, - 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, - 121, 8, 249, 8, 5, 8, 133, 8, 69, 8, - 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, - 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, - 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, - 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, - 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, - 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, - 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, - 211, 9, 467, 9, 51, 9, 307, 9, 179, 9, - 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, - 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, - 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, - 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, - 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, - 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, - 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, - 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, - 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, - 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, - 359, 9, 231, 9, 487, 9, 23, 9, 279, 9, - 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, - 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, - 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, - 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, - 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, - 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, - 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, - 351, 9, 223, 9, 479, 9, 63, 9, 319, 9, - 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, - 511, 9, 0, 7, 64, 7, 32, 7, 96, 7, - 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, - 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, - 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, - 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, - 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, - 163, 8, 99, 8, 227, 8 - }; - - static final short[] static_dtree = { - 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, - 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, - 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, - 30, 5, 1, 5, 17, 5, 9, 5, 25, 5, - 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, - 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 - }; - - static StaticTree static_l_desc = - new StaticTree(static_ltree, Tree.extra_lbits, - LITERALS+1, L_CODES, MAX_BITS); - - static StaticTree static_d_desc = - new StaticTree(static_dtree, Tree.extra_dbits, - 0, D_CODES, MAX_BITS); - - static StaticTree static_bl_desc = - new StaticTree(null, Tree.extra_blbits, - 0, BL_CODES, MAX_BL_BITS); - - short[] static_tree; // static tree or null - int[] extra_bits; // extra bits for each code or null - int extra_base; // base index for extra_bits - int elems; // max number of elements in the tree - int max_length; // max bit length for the codes - - private StaticTree(short[] static_tree, - int[] extra_bits, - int extra_base, - int elems, - int max_length){ - this.static_tree=static_tree; - this.extra_bits=extra_bits; - this.extra_base=extra_base; - this.elems=elems; - this.max_length=max_length; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Tree.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Tree.java deleted file mode 100644 index 1bb87be2..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Tree.java +++ /dev/null @@ -1,367 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jsch.jzlib; - -final class Tree{ - static final private int MAX_BITS=15; - static final private int BL_CODES=19; - static final private int D_CODES=30; - static final private int LITERALS=256; - static final private int LENGTH_CODES=29; - static final private int L_CODES=(LITERALS+1+LENGTH_CODES); - static final private int HEAP_SIZE=(2*L_CODES+1); - - // Bit length codes must not exceed MAX_BL_BITS bits - static final int MAX_BL_BITS=7; - - // end of block literal code - static final int END_BLOCK=256; - - // repeat previous bit length 3-6 times (2 bits of repeat count) - static final int REP_3_6=16; - - // repeat a zero length 3-10 times (3 bits of repeat count) - static final int REPZ_3_10=17; - - // repeat a zero length 11-138 times (7 bits of repeat count) - static final int REPZ_11_138=18; - - // extra bits for each length code - static final int[] extra_lbits={ - 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0 - }; - - // extra bits for each distance code - static final int[] extra_dbits={ - 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 - }; - - // extra bits for each bit length code - static final int[] extra_blbits={ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7 - }; - - static final byte[] bl_order={ - 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; - - - // The lengths of the bit length codes are sent in order of decreasing - // probability, to avoid transmitting the lengths for unused bit - // length codes. - - static final int Buf_size=8*2; - - // see definition of array dist_code below - static final int DIST_CODE_LEN=512; - - static final byte[] _dist_code = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, - 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, - 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 - }; - - static final byte[] _length_code={ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, - 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, - 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, - 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 - }; - - static final int[] base_length = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, - 64, 80, 96, 112, 128, 160, 192, 224, 0 - }; - - static final int[] base_dist = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 - }; - - // Mapping from a distance to a distance code. dist is the distance - 1 and - // must not have side effects. _dist_code[256] and _dist_code[257] are never - // used. - static int d_code(int dist){ - return ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>>7)]); - } - - short[] dyn_tree; // the dynamic tree - int max_code; // largest code with non zero frequency - StaticTree stat_desc; // the corresponding static tree - - // Compute the optimal bit lengths for a tree and update the total bit length - // for the current block. - // IN assertion: the fields freq and dad are set, heap[heap_max] and - // above are the tree nodes sorted by increasing frequency. - // OUT assertions: the field len is set to the optimal bit length, the - // array bl_count contains the frequencies for each bit length. - // The length opt_len is updated; static_len is also updated if stree is - // not null. - void gen_bitlen(Deflate s){ - short[] tree = dyn_tree; - short[] stree = stat_desc.static_tree; - int[] extra = stat_desc.extra_bits; - int base = stat_desc.extra_base; - int max_length = stat_desc.max_length; - int h; // heap index - int n, m; // iterate over the tree elements - int bits; // bit length - int xbits; // extra bits - short f; // frequency - int overflow = 0; // number of elements with bit length too large - - for (bits = 0; bits <= MAX_BITS; bits++) s.bl_count[bits] = 0; - - // In a first pass, compute the optimal bit lengths (which may - // overflow in the case of the bit length tree). - tree[s.heap[s.heap_max]*2+1] = 0; // root of the heap - - for(h=s.heap_max+1; h max_length){ bits = max_length; overflow++; } - tree[n*2+1] = (short)bits; - // We overwrite tree[n*2+1] which is no longer needed - - if (n > max_code) continue; // not a leaf node - - s.bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n*2]; - s.opt_len += f * (bits + xbits); - if (stree!=null) s.static_len += f * (stree[n*2+1] + xbits); - } - if (overflow == 0) return; - - // This happens for example on obj2 and pic of the Calgary corpus - // Find the first bit length which could increase: - do { - bits = max_length-1; - while(s.bl_count[bits]==0) bits--; - s.bl_count[bits]--; // move one leaf down the tree - s.bl_count[bits+1]+=2; // move one overflow item as its brother - s.bl_count[max_length]--; - // The brother of the overflow item also moves one step up, - // but this does not affect bl_count[max_length] - overflow -= 2; - } - while (overflow > 0); - - for (bits = max_length; bits != 0; bits--) { - n = s.bl_count[bits]; - while (n != 0) { - m = s.heap[--h]; - if (m > max_code) continue; - if (tree[m*2+1] != bits) { - s.opt_len += ((long)bits - (long)tree[m*2+1])*(long)tree[m*2]; - tree[m*2+1] = (short)bits; - } - n--; - } - } - } - - // Construct one Huffman tree and assigns the code bit strings and lengths. - // Update the total bit length for the current block. - // IN assertion: the field freq is set for all tree elements. - // OUT assertions: the fields len and code are set to the optimal bit length - // and corresponding code. The length opt_len is updated; static_len is - // also updated if stree is not null. The field max_code is set. - void build_tree(Deflate s){ - short[] tree=dyn_tree; - short[] stree=stat_desc.static_tree; - int elems=stat_desc.elems; - int n, m; // iterate over heap elements - int max_code=-1; // largest code with non zero frequency - int node; // new node being created - - // Construct the initial heap, with least frequent element in - // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - // heap[0] is not used. - s.heap_len = 0; - s.heap_max = HEAP_SIZE; - - for(n=0; n=1; n--) - s.pqdownheap(tree, n); - - // Construct the Huffman tree by repeatedly combining the least two - // frequent nodes. - - node=elems; // next internal node of the tree - do{ - // n = node of least frequency - n=s.heap[1]; - s.heap[1]=s.heap[s.heap_len--]; - s.pqdownheap(tree, 1); - m=s.heap[1]; // m = node of next least frequency - - s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency - s.heap[--s.heap_max] = m; - - // Create a new node father of n and m - tree[node*2] = (short)(tree[n*2] + tree[m*2]); - s.depth[node] = (byte)(Math.max(s.depth[n],s.depth[m])+1); - tree[n*2+1] = tree[m*2+1] = (short)node; - - // and insert the new node in the heap - s.heap[1] = node++; - s.pqdownheap(tree, 1); - } - while(s.heap_len>=2); - - s.heap[--s.heap_max] = s.heap[1]; - - // At this point, the fields freq and dad are set. We can now - // generate the bit lengths. - - gen_bitlen(s); - - // The field len is now set, we can generate the bit codes - gen_codes(tree, max_code, s.bl_count, s.next_code); - } - - // Generate the codes for a given tree and bit counts (which need not be - // optimal). - // IN assertion: the array bl_count contains the bit length statistics for - // the given tree and the field len is set for all tree elements. - // OUT assertion: the field code is set for all tree elements of non - // zero code length. - private final static void gen_codes( - short[] tree, // the tree to decorate - int max_code, // largest code with non zero frequency - short[] bl_count, // number of codes at each bit length - short[] next_code){ - short code = 0; // running code value - int bits; // bit index - int n; // code index - - // The distribution counts are first used to generate the code values - // without bit reversal. - next_code[0]=0; - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (short)((code + bl_count[bits-1]) << 1); - } - - // Check that the bit counts in bl_count are consistent. The last code - // must be all ones. - //Assert (code + bl_count[MAX_BITS]-1 == (1<>>=1; - res<<=1; - } - while(--len>0); - return res>>>1; - } -} - diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/ZStream.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/ZStream.java deleted file mode 100644 index efa79b41..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/ZStream.java +++ /dev/null @@ -1,369 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jsch.jzlib; - -class ZStream{ - - static final private int MAX_WBITS=15; // 32K LZ77 window - static final private int DEF_WBITS=MAX_WBITS; - - static final private int Z_NO_FLUSH=0; - static final private int Z_PARTIAL_FLUSH=1; - static final private int Z_SYNC_FLUSH=2; - static final private int Z_FULL_FLUSH=3; - static final private int Z_FINISH=4; - - static final private int MAX_MEM_LEVEL=9; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - byte[] next_in; // next input byte - int next_in_index; - int avail_in; // number of bytes available at next_in - long total_in; // total nb of input bytes read so far - - byte[] next_out; // next output byte should be put there - int next_out_index; - int avail_out; // remaining free space at next_out - long total_out; // total nb of bytes output so far - - String msg; - - Deflate dstate; - Inflate istate; - - int data_type; // best guess about the data type: ascii or binary - - Checksum adler; - - ZStream(){ - this(new Adler32()); - } - - ZStream(Checksum adler){ - this.adler=adler; - } - - int inflateInit(){ - return inflateInit(DEF_WBITS); - } - int inflateInit(boolean nowrap){ - return inflateInit(DEF_WBITS, nowrap); - } - int inflateInit(int w){ - return inflateInit(w, false); - } - int inflateInit(JZlib.WrapperType wrapperType) { - return inflateInit(DEF_WBITS, wrapperType); - } - int inflateInit(int w, JZlib.WrapperType wrapperType) { - boolean nowrap = false; - if(wrapperType == JZlib.W_NONE){ - nowrap = true; - } - else if(wrapperType == JZlib.W_GZIP) { - w += 16; - } - else if(wrapperType == JZlib.W_ANY) { - w |= Inflate.INFLATE_ANY; - } - else if(wrapperType == JZlib.W_ZLIB) { - } - return inflateInit(w, nowrap); - } - int inflateInit(int w, boolean nowrap){ - istate=new Inflate(this); - return istate.inflateInit(nowrap?-w:w); - } - - int inflate(int f){ - if(istate==null) return Z_STREAM_ERROR; - return istate.inflate(f); - } - int inflateEnd(){ - if(istate==null) return Z_STREAM_ERROR; - int ret=istate.inflateEnd(); -// istate = null; - return ret; - } - int inflateSync(){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSync(); - } - int inflateSyncPoint(){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSyncPoint(); - } - int inflateSetDictionary(byte[] dictionary, int dictLength){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSetDictionary(dictionary, dictLength); - } - boolean inflateFinished(){ - return istate.mode==12 /*DONE*/; - } - - int deflateInit(int level){ - return deflateInit(level, MAX_WBITS); - } - int deflateInit(int level, boolean nowrap){ - return deflateInit(level, MAX_WBITS, nowrap); - } - int deflateInit(int level, int bits){ - return deflateInit(level, bits, false); - } - int deflateInit(int level, int bits, int memlevel, JZlib.WrapperType wrapperType){ - if(bits < 9 || bits > 15){ - return Z_STREAM_ERROR; - } - if(wrapperType == JZlib.W_NONE) { - bits *= -1; - } - else if(wrapperType == JZlib.W_GZIP) { - bits += 16; - } - else if(wrapperType == JZlib.W_ANY) { - return Z_STREAM_ERROR; - } - else if(wrapperType == JZlib.W_ZLIB) { - } - return this.deflateInit(level, bits, memlevel); - } - int deflateInit(int level, int bits, int memlevel){ - dstate=new Deflate(this); - return dstate.deflateInit(level, bits, memlevel); - } - int deflateInit(int level, int bits, boolean nowrap){ - dstate=new Deflate(this); - return dstate.deflateInit(level, nowrap?-bits:bits); - } - int deflate(int flush){ - if(dstate==null){ - return Z_STREAM_ERROR; - } - return dstate.deflate(flush); - } - int deflateEnd(){ - if(dstate==null) return Z_STREAM_ERROR; - int ret=dstate.deflateEnd(); - dstate=null; - return ret; - } - int deflateParams(int level, int strategy){ - if(dstate==null) return Z_STREAM_ERROR; - return dstate.deflateParams(level, strategy); - } - int deflateSetDictionary (byte[] dictionary, int dictLength){ - if(dstate == null) - return Z_STREAM_ERROR; - return dstate.deflateSetDictionary(dictionary, dictLength); - } - - // Flush as much pending output as possible. All deflate() output goes - // through this function so some applications may wish to modify it - // to avoid allocating a large strm->next_out buffer and copying into it. - // (See also read_buf()). - void flush_pending(){ - int len=dstate.pending; - - if(len>avail_out) len=avail_out; - if(len==0) return; - - if(dstate.pending_buf.length<=dstate.pending_out || - next_out.length<=next_out_index || - dstate.pending_buf.length<(dstate.pending_out+len) || - next_out.length<(next_out_index+len)){ - //System.out.println(dstate.pending_buf.length+", "+dstate.pending_out+ - // ", "+next_out.length+", "+next_out_index+", "+len); - //System.out.println("avail_out="+avail_out); - } - - System.arraycopy(dstate.pending_buf, dstate.pending_out, - next_out, next_out_index, len); - - next_out_index+=len; - dstate.pending_out+=len; - total_out+=len; - avail_out-=len; - dstate.pending-=len; - if(dstate.pending==0){ - dstate.pending_out=0; - } - } - - // Read a new buffer from the current input stream, update the adler32 - // and total number of bytes read. All deflate() input goes through - // this function so some applications may wish to modify it to avoid - // allocating a large strm->next_in buffer and copying from it. - // (See also flush_pending()). - int read_buf(byte[] buf, int start, int size) { - int len=avail_in; - - if(len>size) len=size; - if(len==0) return 0; - - avail_in-=len; - - if(dstate.wrap!=0) { - adler.update(next_in, next_in_index, len); - } - System.arraycopy(next_in, next_in_index, buf, start, len); - next_in_index += len; - total_in += len; - return len; - } - - long getAdler(){ - return adler.getValue(); - } - - void free(){ - next_in=null; - next_out=null; - msg=null; - } - - void setOutput(byte[] buf){ - setOutput(buf, 0, buf.length); - } - - void setOutput(byte[] buf, int off, int len){ - next_out = buf; - next_out_index = off; - avail_out = len; - } - - void setInput(byte[] buf){ - setInput(buf, 0, buf.length, false); - } - - void setInput(byte[] buf, boolean append){ - setInput(buf, 0, buf.length, append); - } - - void setInput(byte[] buf, int off, int len, boolean append){ - if(len<=0 && append && next_in!=null) return; - - if(avail_in>0 && append){ - byte[] tmp = new byte[avail_in+len]; - System.arraycopy(next_in, next_in_index, tmp, 0, avail_in); - System.arraycopy(buf, off, tmp, avail_in, len); - next_in=tmp; - next_in_index=0; - avail_in+=len; - } - else{ - next_in=buf; - next_in_index=off; - avail_in=len; - } - } - - byte[] getNextIn(){ - return next_in; - } - - void setNextIn(byte[] next_in){ - this.next_in = next_in; - } - - int getNextInIndex(){ - return next_in_index; - } - - void setNextInIndex(int next_in_index){ - this.next_in_index = next_in_index; - } - - int getAvailIn(){ - return avail_in; - } - - void setAvailIn(int avail_in){ - this.avail_in = avail_in; - } - - byte[] getNextOut(){ - return next_out; - } - - void setNextOut(byte[] next_out){ - this.next_out = next_out; - } - - int getNextOutIndex(){ - return next_out_index; - } - - void setNextOutIndex(int next_out_index){ - this.next_out_index = next_out_index; - } - - int getAvailOut(){ - return avail_out; - - } - - void setAvailOut(int avail_out){ - this.avail_out = avail_out; - } - - long getTotalOut(){ - return total_out; - } - - long getTotalIn(){ - return total_in; - } - - String getMessage(){ - return msg; - } - - // Those methods are expected to be override by Inflater and Deflater. - // In the future, they will become abstract methods. - int end(){ return Z_OK; } - boolean finished(){ return false; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Adler32.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Adler32.java deleted file mode 100644 index a789a5a1..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Adler32.java +++ /dev/null @@ -1,139 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jzlib; - -final public class Adler32 implements Checksum { - - // largest prime smaller than 65536 - static final private int BASE=65521; - // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 - static final private int NMAX=5552; - - private long s1=1L; - private long s2=0L; - - public void reset(long init){ - s1=init&0xffff; - s2=(init>>16)&0xffff; - } - - public void reset(){ - s1=1L; - s2=0L; - } - - public long getValue(){ - return ((s2<<16)|s1); - } - - public void update(byte[] buf, int index, int len){ - - if(len==1){ - s1+=buf[index++]&0xff; s2+=s1; - s1%=BASE; - s2%=BASE; - return; - } - - int len1 = len/NMAX; - int len2 = len%NMAX; - while(len1-->0) { - int k=NMAX; - len-=k; - while(k-->0){ - s1+=buf[index++]&0xff; s2+=s1; - } - s1%=BASE; - s2%=BASE; - } - - int k=len2; - len-=k; - while(k-->0){ - s1+=buf[index++]&0xff; s2+=s1; - } - s1%=BASE; - s2%=BASE; - } - - public Adler32 copy(){ - Adler32 foo = new Adler32(); - foo.s1 = this.s1; - foo.s2 = this.s2; - return foo; - } - - // The following logic has come from zlib.1.2. - static long combine(long adler1, long adler2, long len2){ - long BASEL = (long)BASE; - long sum1; - long sum2; - long rem; // unsigned int - - rem = len2 % BASEL; - sum1 = adler1 & 0xffffL; - sum2 = rem * sum1; - sum2 %= BASEL; // MOD(sum2); - sum1 += (adler2 & 0xffffL) + BASEL - 1; - sum2 += ((adler1 >> 16) & 0xffffL) + ((adler2 >> 16) & 0xffffL) + BASEL - rem; - if (sum1 >= BASEL) sum1 -= BASEL; - if (sum1 >= BASEL) sum1 -= BASEL; - if (sum2 >= (BASEL << 1)) sum2 -= (BASEL << 1); - if (sum2 >= BASEL) sum2 -= BASEL; - return sum1 | (sum2 << 16); - } - -/* - private java.util.zip.Adler32 adler=new java.util.zip.Adler32(); - public void update(byte[] buf, int index, int len){ - if(buf==null) {adler.reset();} - else{adler.update(buf, index, len);} - } - public void reset(){ - adler.reset(); - } - public void reset(long init){ - if(init==1L){ - adler.reset(); - } - else{ - System.err.println("unsupported operation"); - } - } - public long getValue(){ - return adler.getValue(); - } -*/ -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/CRC32.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/CRC32.java deleted file mode 100644 index 30457968..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/CRC32.java +++ /dev/null @@ -1,179 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jzlib; - -final public class CRC32 implements Checksum { - - /* - * The following logic has come from RFC1952. - */ - private int v = 0; - private static int[] crc_table = null; - static { - crc_table = new int[256]; - for (int n = 0; n < 256; n++) { - int c = n; - for (int k = 8; --k >= 0; ) { - if ((c & 1) != 0) - c = 0xedb88320 ^ (c >>> 1); - else - c = c >>> 1; - } - crc_table[n] = c; - } - } - - public void update (byte[] buf, int index, int len) { - int c = ~v; - while (--len >= 0) - c = crc_table[(c^buf[index++])&0xff]^(c >>> 8); - v = ~c; - } - - public void reset(){ - v = 0; - } - - public void reset(long vv){ - v = (int)(vv&0xffffffffL); - } - - public long getValue(){ - return (long)(v&0xffffffffL); - } - - // The following logic has come from zlib.1.2. - private static final int GF2_DIM = 32; - static long combine(long crc1, long crc2, long len2){ - long row; - long[] even = new long[GF2_DIM]; - long[] odd = new long[GF2_DIM]; - - // degenerate case (also disallow negative lengths) - if (len2 <= 0) - return crc1; - - // put operator for one zero bit in odd - odd[0] = 0xedb88320L; // CRC-32 polynomial - row = 1; - for (int n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } - - // put operator for two zero bits in even - gf2_matrix_square(even, odd); - - // put operator for four zero bits in odd - gf2_matrix_square(odd, even); - - // apply len2 zeros to crc1 (first square will put the operator for one - // zero byte, eight zero bits, in even) - do { - // apply zeros operator for this bit of len2 - gf2_matrix_square(even, odd); - if ((len2 & 1)!=0) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - // if no more bits set, then done - if (len2 == 0) - break; - - // another iteration of the loop with odd and even swapped - gf2_matrix_square(odd, even); - if ((len2 & 1)!=0) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - // if no more bits set, then done - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; - } - - private static long gf2_matrix_times(long[] mat, long vec){ - long sum = 0; - int index = 0; - while (vec!=0) { - if ((vec & 1)!=0) - sum ^= mat[index]; - vec >>= 1; - index++; - } - return sum; - } - - static final void gf2_matrix_square(long[] square, long[] mat) { - for (int n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); - } - - /* - private java.util.zip.CRC32 crc32 = new java.util.zip.CRC32(); - - public void update(byte[] buf, int index, int len){ - if(buf==null) {crc32.reset();} - else{crc32.update(buf, index, len);} - } - public void reset(){ - crc32.reset(); - } - public void reset(long init){ - if(init==0L){ - crc32.reset(); - } - else{ - System.err.println("unsupported operation"); - } - } - public long getValue(){ - return crc32.getValue(); - } -*/ - public CRC32 copy(){ - CRC32 foo = new CRC32(); - foo.v = this.v; - return foo; - } - - public static int[] getCRC32Table(){ - int[] tmp = new int[crc_table.length]; - System.arraycopy(crc_table, 0, tmp, 0, tmp.length); - return tmp; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Checksum.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Checksum.java deleted file mode 100644 index 1139093c..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Checksum.java +++ /dev/null @@ -1,43 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jzlib; - -interface Checksum { - void update(byte[] buf, int index, int len); - void reset(); - void reset(long init); - long getValue(); - Checksum copy(); -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Deflate.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Deflate.java deleted file mode 100644 index 47ad4423..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Deflate.java +++ /dev/null @@ -1,1754 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jzlib; - -public -final class Deflate implements Cloneable { - - static final private int MAX_MEM_LEVEL=9; - - static final private int Z_DEFAULT_COMPRESSION=-1; - - static final private int MAX_WBITS=15; // 32K LZ77 window - static final private int DEF_MEM_LEVEL=8; - - static class Config{ - int good_length; // reduce lazy search above this match length - int max_lazy; // do not perform lazy search above this match length - int nice_length; // quit search above this match length - int max_chain; - int func; - Config(int good_length, int max_lazy, - int nice_length, int max_chain, int func){ - this.good_length=good_length; - this.max_lazy=max_lazy; - this.nice_length=nice_length; - this.max_chain=max_chain; - this.func=func; - } - } - - static final private int STORED=0; - static final private int FAST=1; - static final private int SLOW=2; - static final private Config[] config_table; - static{ - config_table=new Config[10]; - // good lazy nice chain - config_table[0]=new Config(0, 0, 0, 0, STORED); - config_table[1]=new Config(4, 4, 8, 4, FAST); - config_table[2]=new Config(4, 5, 16, 8, FAST); - config_table[3]=new Config(4, 6, 32, 32, FAST); - - config_table[4]=new Config(4, 4, 16, 16, SLOW); - config_table[5]=new Config(8, 16, 32, 32, SLOW); - config_table[6]=new Config(8, 16, 128, 128, SLOW); - config_table[7]=new Config(8, 32, 128, 256, SLOW); - config_table[8]=new Config(32, 128, 258, 1024, SLOW); - config_table[9]=new Config(32, 258, 258, 4096, SLOW); - } - - static final private String[] z_errmsg = { - "need dictionary", // Z_NEED_DICT 2 - "stream end", // Z_STREAM_END 1 - "", // Z_OK 0 - "file error", // Z_ERRNO (-1) - "stream error", // Z_STREAM_ERROR (-2) - "data error", // Z_DATA_ERROR (-3) - "insufficient memory", // Z_MEM_ERROR (-4) - "buffer error", // Z_BUF_ERROR (-5) - "incompatible version",// Z_VERSION_ERROR (-6) - "" - }; - - // block not completed, need more input or more output - static final private int NeedMore=0; - - // block flush performed - static final private int BlockDone=1; - - // finish started, need only more output at next deflate - static final private int FinishStarted=2; - - // finish done, accept no more input or output - static final private int FinishDone=3; - - // preset dictionary flag in zlib header - static final private int PRESET_DICT=0x20; - - static final private int Z_FILTERED=1; - static final private int Z_HUFFMAN_ONLY=2; - static final private int Z_DEFAULT_STRATEGY=0; - - static final private int Z_NO_FLUSH=0; - static final private int Z_PARTIAL_FLUSH=1; - static final private int Z_SYNC_FLUSH=2; - static final private int Z_FULL_FLUSH=3; - static final private int Z_FINISH=4; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - static final private int INIT_STATE=42; - static final private int BUSY_STATE=113; - static final private int FINISH_STATE=666; - - // The deflate compression method - static final private int Z_DEFLATED=8; - - static final private int STORED_BLOCK=0; - static final private int STATIC_TREES=1; - static final private int DYN_TREES=2; - - // The three kinds of block type - static final private int Z_BINARY=0; - static final private int Z_ASCII=1; - static final private int Z_UNKNOWN=2; - - static final private int Buf_size=8*2; - - // repeat previous bit length 3-6 times (2 bits of repeat count) - static final private int REP_3_6=16; - - // repeat a zero length 3-10 times (3 bits of repeat count) - static final private int REPZ_3_10=17; - - // repeat a zero length 11-138 times (7 bits of repeat count) - static final private int REPZ_11_138=18; - - static final private int MIN_MATCH=3; - static final private int MAX_MATCH=258; - static final private int MIN_LOOKAHEAD=(MAX_MATCH+MIN_MATCH+1); - - static final private int MAX_BITS=15; - static final private int D_CODES=30; - static final private int BL_CODES=19; - static final private int LENGTH_CODES=29; - static final private int LITERALS=256; - static final private int L_CODES=(LITERALS+1+LENGTH_CODES); - static final private int HEAP_SIZE=(2*L_CODES+1); - - static final private int END_BLOCK=256; - - ZStream strm; // pointer back to this zlib stream - int status; // as the name implies - byte[] pending_buf; // output still pending - int pending_buf_size; // size of pending_buf - int pending_out; // next pending byte to output to the stream - int pending; // nb of bytes in the pending buffer - int wrap = 1; - byte data_type; // UNKNOWN, BINARY or ASCII - byte method; // STORED (for zip only) or DEFLATED - int last_flush; // value of flush param for previous deflate call - - int w_size; // LZ77 window size (32K by default) - int w_bits; // log2(w_size) (8..16) - int w_mask; // w_size - 1 - - byte[] window; - // Sliding window. Input bytes are read into the second half of the window, - // and move to the first half later to keep a dictionary of at least wSize - // bytes. With this organization, matches are limited to a distance of - // wSize-MAX_MATCH bytes, but this ensures that IO is always - // performed with a length multiple of the block size. Also, it limits - // the window size to 64K, which is quite useful on MSDOS. - // To do: use the user input buffer as sliding window. - - int window_size; - // Actual size of window: 2*wSize, except when the user input buffer - // is directly used as sliding window. - - short[] prev; - // Link to older string with same hash index. To limit the size of this - // array to 64K, this link is maintained only for the last 32K strings. - // An index in this array is thus a window index modulo 32K. - - short[] head; // Heads of the hash chains or NIL. - - int ins_h; // hash index of string to be inserted - int hash_size; // number of elements in hash table - int hash_bits; // log2(hash_size) - int hash_mask; // hash_size-1 - - // Number of bits by which ins_h must be shifted at each input - // step. It must be such that after MIN_MATCH steps, the oldest - // byte no longer takes part in the hash key, that is: - // hash_shift * MIN_MATCH >= hash_bits - int hash_shift; - - // Window position at the beginning of the current output block. Gets - // negative when the window is moved backwards. - - int block_start; - - int match_length; // length of best match - int prev_match; // previous match - int match_available; // set if previous match exists - int strstart; // start of string to insert - int match_start; // start of matching string - int lookahead; // number of valid bytes ahead in window - - // Length of the best match at previous step. Matches not greater than this - // are discarded. This is used in the lazy match evaluation. - int prev_length; - - // To speed up deflation, hash chains are never searched beyond this - // length. A higher limit improves compression ratio but degrades the speed. - int max_chain_length; - - // Attempt to find a better match only when the current match is strictly - // smaller than this value. This mechanism is used only for compression - // levels >= 4. - int max_lazy_match; - - // Insert new strings in the hash table only if the match length is not - // greater than this length. This saves time but degrades compression. - // max_insert_length is used only for compression levels <= 3. - - int level; // compression level (1..9) - int strategy; // favor or force Huffman coding - - // Use a faster search when the previous match is longer than this - int good_match; - - // Stop searching when current match exceeds this - int nice_match; - - short[] dyn_ltree; // literal and length tree - short[] dyn_dtree; // distance tree - short[] bl_tree; // Huffman tree for bit lengths - - Tree l_desc=new Tree(); // desc for literal tree - Tree d_desc=new Tree(); // desc for distance tree - Tree bl_desc=new Tree(); // desc for bit length tree - - // number of codes at each bit length for an optimal tree - short[] bl_count=new short[MAX_BITS+1]; - // working area to be used in Tree#gen_codes() - short[] next_code=new short[MAX_BITS+1]; - - // heap used to build the Huffman trees - int[] heap=new int[2*L_CODES+1]; - - int heap_len; // number of elements in the heap - int heap_max; // element of largest frequency - // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - // The same heap array is used to build all trees. - - // Depth of each subtree used as tie breaker for trees of equal frequency - byte[] depth=new byte[2*L_CODES+1]; - - int l_buf; // index for literals or lengths */ - - // Size of match buffer for literals/lengths. There are 4 reasons for - // limiting lit_bufsize to 64K: - // - frequencies can be kept in 16 bit counters - // - if compression is not successful for the first block, all input - // data is still in the window so we can still emit a stored block even - // when input comes from standard input. (This can also be done for - // all blocks if lit_bufsize is not greater than 32K.) - // - if compression is not successful for a file smaller than 64K, we can - // even emit a stored file instead of a stored block (saving 5 bytes). - // This is applicable only for zip (not gzip or zlib). - // - creating new Huffman trees less frequently may not provide fast - // adaptation to changes in the input data statistics. (Take for - // example a binary file with poorly compressible code followed by - // a highly compressible string table.) Smaller buffer sizes give - // fast adaptation but have of course the overhead of transmitting - // trees more frequently. - // - I can't count above 4 - int lit_bufsize; - - int last_lit; // running index in l_buf - - // Buffer for distances. To simplify the code, d_buf and l_buf have - // the same number of elements. To use different lengths, an extra flag - // array would be necessary. - - int d_buf; // index of pendig_buf - - int opt_len; // bit length of current block with optimal trees - int static_len; // bit length of current block with static trees - int matches; // number of string matches in current block - int last_eob_len; // bit length of EOB code for last block - - // Output buffer. bits are inserted starting at the bottom (least - // significant bits). - short bi_buf; - - // Number of valid bits in bi_buf. All bits above the last valid bit - // are always zero. - int bi_valid; - - GZIPHeader gheader = null; - - Deflate(ZStream strm){ - this.strm=strm; - dyn_ltree=new short[HEAP_SIZE*2]; - dyn_dtree=new short[(2*D_CODES+1)*2]; // distance tree - bl_tree=new short[(2*BL_CODES+1)*2]; // Huffman tree for bit lengths - } - - void lm_init() { - window_size=2*w_size; - - head[hash_size-1]=0; - for(int i=0; i= 3; max_blindex--) { - if (bl_tree[Tree.bl_order[max_blindex]*2+1] != 0) break; - } - // Update opt_len to include the bit length tree and counts - opt_len += 3*(max_blindex+1) + 5+5+4; - - return max_blindex; - } - - - // Send the header for a block using dynamic Huffman trees: the counts, the - // lengths of the bit length codes, the literal tree and the distance tree. - // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - void send_all_trees(int lcodes, int dcodes, int blcodes){ - int rank; // index in bl_order - - send_bits(lcodes-257, 5); // not +255 as stated in appnote.txt - send_bits(dcodes-1, 5); - send_bits(blcodes-4, 4); // not -3 as stated in appnote.txt - for (rank = 0; rank < blcodes; rank++) { - send_bits(bl_tree[Tree.bl_order[rank]*2+1], 3); - } - send_tree(dyn_ltree, lcodes-1); // literal tree - send_tree(dyn_dtree, dcodes-1); // distance tree - } - - // Send a literal or distance tree in compressed form, using the codes in - // bl_tree. - void send_tree (short[] tree,// the tree to be sent - int max_code // and its largest code of non zero frequency - ){ - int n; // iterates over all tree elements - int prevlen = -1; // last emitted length - int curlen; // length of current code - int nextlen = tree[0*2+1]; // length of next code - int count = 0; // repeat count of the current code - int max_count = 7; // max repeat count - int min_count = 4; // min repeat count - - if (nextlen == 0){ max_count = 138; min_count = 3; } - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[(n+1)*2+1]; - if(++count < max_count && curlen == nextlen) { - continue; - } - else if(count < min_count) { - do { send_code(curlen, bl_tree); } while (--count != 0); - } - else if(curlen != 0){ - if(curlen != prevlen){ - send_code(curlen, bl_tree); count--; - } - send_code(REP_3_6, bl_tree); - send_bits(count-3, 2); - } - else if(count <= 10){ - send_code(REPZ_3_10, bl_tree); - send_bits(count-3, 3); - } - else{ - send_code(REPZ_11_138, bl_tree); - send_bits(count-11, 7); - } - count = 0; prevlen = curlen; - if(nextlen == 0){ - max_count = 138; min_count = 3; - } - else if(curlen == nextlen){ - max_count = 6; min_count = 3; - } - else{ - max_count = 7; min_count = 4; - } - } - } - - // Output a byte on the stream. - // IN assertion: there is enough room in pending_buf. - final void put_byte(byte[] p, int start, int len){ - System.arraycopy(p, start, pending_buf, pending, len); - pending+=len; - } - - final void put_byte(byte c){ - pending_buf[pending++]=c; - } - final void put_short(int w) { - put_byte((byte)(w/*&0xff*/)); - put_byte((byte)(w>>>8)); - } - final void putShortMSB(int b){ - put_byte((byte)(b>>8)); - put_byte((byte)(b/*&0xff*/)); - } - - final void send_code(int c, short[] tree){ - int c2=c*2; - send_bits((tree[c2]&0xffff), (tree[c2+1]&0xffff)); - } - - void send_bits(int value, int length){ - int len = length; - if (bi_valid > (int)Buf_size - len) { - int val = value; -// bi_buf |= (val << bi_valid); - bi_buf |= ((val << bi_valid)&0xffff); - put_short(bi_buf); - bi_buf = (short)(val >>> (Buf_size - bi_valid)); - bi_valid += len - Buf_size; - } else { -// bi_buf |= (value) << bi_valid; - bi_buf |= (((value) << bi_valid)&0xffff); - bi_valid += len; - } - } - - // Send one empty static block to give enough lookahead for inflate. - // This takes 10 bits, of which 7 may remain in the bit buffer. - // The current inflate code requires 9 bits of lookahead. If the - // last two codes for the previous block (real code plus EOB) were coded - // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - // the last real code. In this case we send two empty static blocks instead - // of one. (There are no problems if the previous block is stored or fixed.) - // To simplify the code, we assume the worst case of last real code encoded - // on one bit only. - void _tr_align(){ - send_bits(STATIC_TREES<<1, 3); - send_code(END_BLOCK, StaticTree.static_ltree); - - bi_flush(); - - // Of the 10 bits for the empty block, we have already sent - // (10 - bi_valid) bits. The lookahead for the last real code (before - // the EOB of the previous block) was thus at least one plus the length - // of the EOB plus what we have just sent of the empty static block. - if (1 + last_eob_len + 10 - bi_valid < 9) { - send_bits(STATIC_TREES<<1, 3); - send_code(END_BLOCK, StaticTree.static_ltree); - bi_flush(); - } - last_eob_len = 7; - } - - - // Save the match info and tally the frequency counts. Return true if - // the current block must be flushed. - boolean _tr_tally (int dist, // distance of matched string - int lc // match length-MIN_MATCH or unmatched char (if dist==0) - ){ - - pending_buf[d_buf+last_lit*2] = (byte)(dist>>>8); - pending_buf[d_buf+last_lit*2+1] = (byte)dist; - - pending_buf[l_buf+last_lit] = (byte)lc; last_lit++; - - if (dist == 0) { - // lc is the unmatched char - dyn_ltree[lc*2]++; - } - else { - matches++; - // Here, lc is the match length - MIN_MATCH - dist--; // dist = match distance - 1 - dyn_ltree[(Tree._length_code[lc]+LITERALS+1)*2]++; - dyn_dtree[Tree.d_code(dist)*2]++; - } - - if ((last_lit & 0x1fff) == 0 && level > 2) { - // Compute an upper bound for the compressed length - int out_length = last_lit*8; - int in_length = strstart - block_start; - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (int)dyn_dtree[dcode*2] * - (5L+Tree.extra_dbits[dcode]); - } - out_length >>>= 3; - if ((matches < (last_lit/2)) && out_length < in_length/2) return true; - } - - return (last_lit == lit_bufsize-1); - // We avoid equality with lit_bufsize because of wraparound at 64K - // on 16 bit machines and because stored blocks are restricted to - // 64K-1 bytes. - } - - // Send the block data compressed using the given Huffman trees - void compress_block(short[] ltree, short[] dtree){ - int dist; // distance of matched string - int lc; // match length or unmatched char (if dist == 0) - int lx = 0; // running index in l_buf - int code; // the code to send - int extra; // number of extra bits to send - - if (last_lit != 0){ - do{ - dist=((pending_buf[d_buf+lx*2]<<8)&0xff00)| - (pending_buf[d_buf+lx*2+1]&0xff); - lc=(pending_buf[l_buf+lx])&0xff; lx++; - - if(dist == 0){ - send_code(lc, ltree); // send a literal byte - } - else{ - // Here, lc is the match length - MIN_MATCH - code = Tree._length_code[lc]; - - send_code(code+LITERALS+1, ltree); // send the length code - extra = Tree.extra_lbits[code]; - if(extra != 0){ - lc -= Tree.base_length[code]; - send_bits(lc, extra); // send the extra length bits - } - dist--; // dist is now the match distance - 1 - code = Tree.d_code(dist); - - send_code(code, dtree); // send the distance code - extra = Tree.extra_dbits[code]; - if (extra != 0) { - dist -= Tree.base_dist[code]; - send_bits(dist, extra); // send the extra distance bits - } - } // literal or match pair ? - - // Check that the overlay between pending_buf and d_buf+l_buf is ok: - } - while (lx < last_lit); - } - - send_code(END_BLOCK, ltree); - last_eob_len = ltree[END_BLOCK*2+1]; - } - - // Set the data type to ASCII or BINARY, using a crude approximation: - // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. - // IN assertion: the fields freq of dyn_ltree are set and the total of all - // frequencies does not exceed 64K (to fit in an int on 16 bit machines). - void set_data_type(){ - int n = 0; - int ascii_freq = 0; - int bin_freq = 0; - while(n<7){ bin_freq += dyn_ltree[n*2]; n++;} - while(n<128){ ascii_freq += dyn_ltree[n*2]; n++;} - while(n (ascii_freq >>> 2) ? Z_BINARY : Z_ASCII); - } - - // Flush the bit buffer, keeping at most 7 bits in it. - void bi_flush(){ - if (bi_valid == 16) { - put_short(bi_buf); - bi_buf=0; - bi_valid=0; - } - else if (bi_valid >= 8) { - put_byte((byte)bi_buf); - bi_buf>>>=8; - bi_valid-=8; - } - } - - // Flush the bit buffer and align the output on a byte boundary - void bi_windup(){ - if (bi_valid > 8) { - put_short(bi_buf); - } else if (bi_valid > 0) { - put_byte((byte)bi_buf); - } - bi_buf = 0; - bi_valid = 0; - } - - // Copy a stored block, storing first the length and its - // one's complement if requested. - void copy_block(int buf, // the input data - int len, // its length - boolean header // true if block header must be written - ){ - int index=0; - bi_windup(); // align on byte boundary - last_eob_len = 8; // enough lookahead for inflate - - if (header) { - put_short((short)len); - put_short((short)~len); - } - - // while(len--!=0) { - // put_byte(window[buf+index]); - // index++; - // } - put_byte(window, buf, len); - } - - void flush_block_only(boolean eof){ - _tr_flush_block(block_start>=0 ? block_start : -1, - strstart-block_start, - eof); - block_start=strstart; - strm.flush_pending(); - } - - // Copy without compression as much as possible from the input stream, return - // the current block state. - // This function does not insert new strings in the dictionary since - // uncompressible data is probably not useful. This function is used - // only for the level=0 compression option. - // NOTE: this function should be optimized to avoid extra copying from - // window to pending_buf. - int deflate_stored(int flush){ - // Stored blocks are limited to 0xffff bytes, pending_buf is limited - // to pending_buf_size, and each stored block has a 5 byte header: - - int max_block_size = 0xffff; - int max_start; - - if(max_block_size > pending_buf_size - 5) { - max_block_size = pending_buf_size - 5; - } - - // Copy as much as possible from input to output: - while(true){ - // Fill the window as much as possible: - if(lookahead<=1){ - fill_window(); - if(lookahead==0 && flush==Z_NO_FLUSH) return NeedMore; - if(lookahead==0) break; // flush the current block - } - - strstart+=lookahead; - lookahead=0; - - // Emit a stored block if pending_buf will be full: - max_start=block_start+max_block_size; - if(strstart==0|| strstart>=max_start) { - // strstart == 0 is possible when wraparound on 16-bit machine - lookahead = (int)(strstart-max_start); - strstart = (int)max_start; - - flush_block_only(false); - if(strm.avail_out==0) return NeedMore; - - } - - // Flush if we may have to slide, otherwise block_start may become - // negative and the data will be gone: - if(strstart-block_start >= w_size-MIN_LOOKAHEAD) { - flush_block_only(false); - if(strm.avail_out==0) return NeedMore; - } - } - - flush_block_only(flush == Z_FINISH); - if(strm.avail_out==0) - return (flush == Z_FINISH) ? FinishStarted : NeedMore; - - return flush == Z_FINISH ? FinishDone : BlockDone; - } - - // Send a stored block - void _tr_stored_block(int buf, // input block - int stored_len, // length of input block - boolean eof // true if this is the last block for a file - ){ - send_bits((STORED_BLOCK<<1)+(eof?1:0), 3); // send block type - copy_block(buf, stored_len, true); // with header - } - - // Determine the best encoding for the current block: dynamic trees, static - // trees or store, and output the encoded block to the zip file. - void _tr_flush_block(int buf, // input block, or NULL if too old - int stored_len, // length of input block - boolean eof // true if this is the last block for a file - ) { - int opt_lenb, static_lenb;// opt_len and static_len in bytes - int max_blindex = 0; // index of last bit length code of non zero freq - - // Build the Huffman trees unless a stored block is forced - if(level > 0) { - // Check if the file is ascii or binary - if(data_type == Z_UNKNOWN) set_data_type(); - - // Construct the literal and distance trees - l_desc.build_tree(this); - - d_desc.build_tree(this); - - // At this point, opt_len and static_len are the total bit lengths of - // the compressed block data, excluding the tree representations. - - // Build the bit length tree for the above two trees, and get the index - // in bl_order of the last bit length code to send. - max_blindex=build_bl_tree(); - - // Determine the best encoding. Compute first the block length in bytes - opt_lenb=(opt_len+3+7)>>>3; - static_lenb=(static_len+3+7)>>>3; - - if(static_lenb<=opt_lenb) opt_lenb=static_lenb; - } - else { - opt_lenb=static_lenb=stored_len+5; // force a stored block - } - - if(stored_len+4<=opt_lenb && buf != -1){ - // 4: two words for the lengths - // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - // Otherwise we can't have processed more than WSIZE input bytes since - // the last block flush, because compression would have been - // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - // transform a block into a stored block. - _tr_stored_block(buf, stored_len, eof); - } - else if(static_lenb == opt_lenb){ - send_bits((STATIC_TREES<<1)+(eof?1:0), 3); - compress_block(StaticTree.static_ltree, StaticTree.static_dtree); - } - else{ - send_bits((DYN_TREES<<1)+(eof?1:0), 3); - send_all_trees(l_desc.max_code+1, d_desc.max_code+1, max_blindex+1); - compress_block(dyn_ltree, dyn_dtree); - } - - // The above check is made mod 2^32, for files larger than 512 MB - // and uLong implemented on 32 bits. - - init_block(); - - if(eof){ - bi_windup(); - } - } - - // Fill the window when the lookahead becomes insufficient. - // Updates strstart and lookahead. - // - // IN assertion: lookahead < MIN_LOOKAHEAD - // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - // At least one byte has been read, or avail_in == 0; reads are - // performed for at least two bytes (required for the zip translate_eol - // option -- not supported here). - void fill_window(){ - int n, m; - int p; - int more; // Amount of free space at the end of the window. - - do{ - more = (window_size-lookahead-strstart); - - // Deal with !@#$% 64K limit: - if(more==0 && strstart==0 && lookahead==0){ - more = w_size; - } - else if(more==-1) { - // Very unlikely, but possible on 16 bit machine if strstart == 0 - // and lookahead == 1 (input done one byte at time) - more--; - - // If the window is almost full and there is insufficient lookahead, - // move the upper half to the lower one to make room in the upper half. - } - else if(strstart >= w_size+ w_size-MIN_LOOKAHEAD) { - System.arraycopy(window, w_size, window, 0, w_size); - match_start-=w_size; - strstart-=w_size; // we now have strstart >= MAX_DIST - block_start-=w_size; - - // Slide the hash table (could be avoided with 32 bit values - // at the expense of memory usage). We slide even when level == 0 - // to keep the hash table consistent if we switch back to level > 0 - // later. (Using level 0 permanently is not an optimal usage of - // zlib, so we don't care about this pathological case.) - - n = hash_size; - p=n; - do { - m = (head[--p]&0xffff); - head[p]=(m>=w_size ? (short)(m-w_size) : 0); - } - while (--n != 0); - - n = w_size; - p = n; - do { - m = (prev[--p]&0xffff); - prev[p] = (m >= w_size ? (short)(m-w_size) : 0); - // If n is not on any hash chain, prev[n] is garbage but - // its value will never be used. - } - while (--n!=0); - more += w_size; - } - - if (strm.avail_in == 0) return; - - // If there was no sliding: - // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - // more == window_size - lookahead - strstart - // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - // => more >= window_size - 2*WSIZE + 2 - // In the BIG_MEM or MMAP case (not yet supported), - // window_size == input_size + MIN_LOOKAHEAD && - // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - // Otherwise, window_size == 2*WSIZE so more >= 2. - // If there was sliding, more >= WSIZE. So in all cases, more >= 2. - - n = strm.read_buf(window, strstart + lookahead, more); - lookahead += n; - - // Initialize the hash value now that we have some input: - if(lookahead >= MIN_MATCH) { - ins_h = window[strstart]&0xff; - ins_h=(((ins_h)<= MIN_MATCH){ - ins_h=(((ins_h)<=MIN_MATCH){ - // check_match(strstart, match_start, match_length); - - bflush=_tr_tally(strstart-match_start, match_length-MIN_MATCH); - - lookahead -= match_length; - - // Insert new strings in the hash table only if the match length - // is not too large. This saves time but degrades compression. - if(match_length <= max_lazy_match && - lookahead >= MIN_MATCH) { - match_length--; // string at strstart already in hash table - do{ - strstart++; - - ins_h=((ins_h<= MIN_MATCH) { - ins_h=(((ins_h)< 4096))) { - - // If prev_match is also MIN_MATCH, match_start is garbage - // but we will ignore the current match anyway. - match_length = MIN_MATCH-1; - } - } - - // If there was a match at the previous step and the current - // match is not better, output the previous match: - if(prev_length >= MIN_MATCH && match_length <= prev_length) { - int max_insert = strstart + lookahead - MIN_MATCH; - // Do not insert strings in hash table beyond this. - - // check_match(strstart-1, prev_match, prev_length); - - bflush=_tr_tally(strstart-1-prev_match, prev_length - MIN_MATCH); - - // Insert in hash table all strings up to the end of the match. - // strstart-1 and strstart are already inserted. If there is not - // enough lookahead, the last two strings are not inserted in - // the hash table. - lookahead -= prev_length-1; - prev_length -= 2; - do{ - if(++strstart <= max_insert) { - ins_h=(((ins_h)<(w_size-MIN_LOOKAHEAD) ? - strstart-(w_size-MIN_LOOKAHEAD) : 0; - int nice_match=this.nice_match; - - // Stop when cur_match becomes <= limit. To simplify the code, - // we prevent matches with the string of window index 0. - - int wmask = w_mask; - - int strend = strstart + MAX_MATCH; - byte scan_end1 = window[scan+best_len-1]; - byte scan_end = window[scan+best_len]; - - // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - // It is easy to get rid of this optimization if necessary. - - // Do not waste too much time if we already have a good match: - if (prev_length >= good_match) { - chain_length >>= 2; - } - - // Do not look for matches beyond the end of the input. This is necessary - // to make deflate deterministic. - if (nice_match > lookahead) nice_match = lookahead; - - do { - match = cur_match; - - // Skip to next match if the match length cannot increase - // or if the match length is less than 2: - if (window[match+best_len] != scan_end || - window[match+best_len-1] != scan_end1 || - window[match] != window[scan] || - window[++match] != window[scan+1]) continue; - - // The check at best_len-1 can be removed because it will be made - // again later. (This heuristic is not always a win.) - // It is not necessary to compare scan[2] and match[2] since they - // are always equal when the other bytes match, given that - // the hash keys are equal and that HASH_BITS >= 8. - scan += 2; match++; - - // We check for insufficient lookahead only every 8th comparison; - // the 256th check will be made at strstart+258. - do { - } while (window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - scan < strend); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - - if(len>best_len) { - match_start = cur_match; - best_len = len; - if (len >= nice_match) break; - scan_end1 = window[scan+best_len-1]; - scan_end = window[scan+best_len]; - } - - } while ((cur_match = (prev[cur_match & wmask]&0xffff)) > limit - && --chain_length != 0); - - if (best_len <= lookahead) return best_len; - return lookahead; - } - - int deflateInit(int level, int bits, int memlevel){ - return deflateInit(level, Z_DEFLATED, bits, memlevel, - Z_DEFAULT_STRATEGY); - } - - int deflateInit(int level, int bits){ - return deflateInit(level, Z_DEFLATED, bits, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY); - } - int deflateInit(int level){ - return deflateInit(level, MAX_WBITS); - } - private int deflateInit(int level, int method, int windowBits, - int memLevel, int strategy){ - int wrap = 1; - // byte[] my_version=ZLIB_VERSION; - - // - // if (version == null || version[0] != my_version[0] - // || stream_size != sizeof(z_stream)) { - // return Z_VERSION_ERROR; - // } - - strm.msg = null; - - if (level == Z_DEFAULT_COMPRESSION) level = 6; - - if (windowBits < 0) { // undocumented feature: suppress zlib header - wrap = 0; - windowBits = -windowBits; - } - else if(windowBits > 15){ - wrap = 2; - windowBits -= 16; - strm.adler=new CRC32(); - } - - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || - method != Z_DEFLATED || - windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_HUFFMAN_ONLY) { - return Z_STREAM_ERROR; - } - - strm.dstate = (Deflate)this; - - this.wrap = wrap; - w_bits = windowBits; - w_size = 1 << w_bits; - w_mask = w_size - 1; - - hash_bits = memLevel + 7; - hash_size = 1 << hash_bits; - hash_mask = hash_size - 1; - hash_shift = ((hash_bits+MIN_MATCH-1)/MIN_MATCH); - - window = new byte[w_size*2]; - prev = new short[w_size]; - head = new short[hash_size]; - - lit_bufsize = 1 << (memLevel + 6); // 16K elements by default - - // We overlay pending_buf and d_buf+l_buf. This works since the average - // output size for (length,distance) codes is <= 24 bits. - pending_buf = new byte[lit_bufsize*4]; - pending_buf_size = lit_bufsize*4; - - d_buf = lit_bufsize/2; - l_buf = (1+2)*lit_bufsize; - - this.level = level; - - this.strategy = strategy; - this.method = (byte)method; - - return deflateReset(); - } - - int deflateReset(){ - strm.total_in = strm.total_out = 0; - strm.msg = null; // - strm.data_type = Z_UNKNOWN; - - pending = 0; - pending_out = 0; - - if(wrap < 0){ - wrap = -wrap; - } - status = (wrap==0) ? BUSY_STATE : INIT_STATE; - strm.adler.reset(); - - last_flush = Z_NO_FLUSH; - - tr_init(); - lm_init(); - return Z_OK; - } - - int deflateEnd(){ - if(status!=INIT_STATE && status!=BUSY_STATE && status!=FINISH_STATE){ - return Z_STREAM_ERROR; - } - // Deallocate in reverse order of allocations: - pending_buf=null; - head=null; - prev=null; - window=null; - // free - // dstate=null; - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; - } - - int deflateParams(int _level, int _strategy){ - int err=Z_OK; - - if(_level == Z_DEFAULT_COMPRESSION){ - _level = 6; - } - if(_level < 0 || _level > 9 || - _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) { - return Z_STREAM_ERROR; - } - - if(config_table[level].func!=config_table[_level].func && - strm.total_in != 0) { - // Flush the last buffer: - err = strm.deflate(Z_PARTIAL_FLUSH); - } - - if(level != _level) { - level = _level; - max_lazy_match = config_table[level].max_lazy; - good_match = config_table[level].good_length; - nice_match = config_table[level].nice_length; - max_chain_length = config_table[level].max_chain; - } - strategy = _strategy; - return err; - } - - int deflateSetDictionary (byte[] dictionary, int dictLength){ - int length = dictLength; - int index=0; - - if(dictionary == null || status != INIT_STATE) - return Z_STREAM_ERROR; - - strm.adler.update(dictionary, 0, dictLength); - - if(length < MIN_MATCH) return Z_OK; - if(length > w_size-MIN_LOOKAHEAD){ - length = w_size-MIN_LOOKAHEAD; - index=dictLength-length; // use the tail of the dictionary - } - System.arraycopy(dictionary, index, window, 0, length); - strstart = length; - block_start = length; - - // Insert all strings in the hash table (except for the last two bytes). - // s->lookahead stays null, so s->ins_h will be recomputed at the next - // call of fill_window. - - ins_h = window[0]&0xff; - ins_h=(((ins_h)<Z_FINISH || flush<0){ - return Z_STREAM_ERROR; - } - - if(strm.next_out == null || - (strm.next_in == null && strm.avail_in != 0) || - (status == FINISH_STATE && flush != Z_FINISH)) { - strm.msg=z_errmsg[Z_NEED_DICT-(Z_STREAM_ERROR)]; - return Z_STREAM_ERROR; - } - if(strm.avail_out == 0){ - strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; - return Z_BUF_ERROR; - } - - old_flush = last_flush; - last_flush = flush; - - // Write the zlib header - if(status == INIT_STATE) { - if(wrap == 2){ - getGZIPHeader().put(this); - status=BUSY_STATE; - strm.adler.reset(); - } - else{ - int header = (Z_DEFLATED+((w_bits-8)<<4))<<8; - int level_flags=((level-1)&0xff)>>1; - - if(level_flags>3) level_flags=3; - header |= (level_flags<<6); - if(strstart!=0) header |= PRESET_DICT; - header+=31-(header % 31); - - status=BUSY_STATE; - putShortMSB(header); - - - // Save the adler32 of the preset dictionary: - if(strstart!=0){ - long adler=strm.adler.getValue(); - putShortMSB((int)(adler>>>16)); - putShortMSB((int)(adler&0xffff)); - } - strm.adler.reset(); - } - } - - // Flush as much pending output as possible - if(pending != 0) { - strm.flush_pending(); - if(strm.avail_out == 0) { - // Since avail_out is 0, deflate will be called again with - // more output space, but possibly with both pending and - // avail_in equal to zero. There won't be anything to do, - // but this is not an error situation so make sure we - // return OK instead of BUF_ERROR at next call of deflate: - last_flush = -1; - return Z_OK; - } - - // Make sure there is something to do and avoid duplicate consecutive - // flushes. For repeated and useless calls with Z_FINISH, we keep - // returning Z_STREAM_END instead of Z_BUFF_ERROR. - } - else if(strm.avail_in==0 && flush <= old_flush && - flush != Z_FINISH) { - strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; - return Z_BUF_ERROR; - } - - // User must not provide more input after the first FINISH: - if(status == FINISH_STATE && strm.avail_in != 0) { - strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; - return Z_BUF_ERROR; - } - - // Start a new block or continue the current one. - if(strm.avail_in!=0 || lookahead!=0 || - (flush != Z_NO_FLUSH && status != FINISH_STATE)) { - int bstate=-1; - switch(config_table[level].func){ - case STORED: - bstate = deflate_stored(flush); - break; - case FAST: - bstate = deflate_fast(flush); - break; - case SLOW: - bstate = deflate_slow(flush); - break; - default: - } - - if (bstate==FinishStarted || bstate==FinishDone) { - status = FINISH_STATE; - } - if (bstate==NeedMore || bstate==FinishStarted) { - if(strm.avail_out == 0) { - last_flush = -1; // avoid BUF_ERROR next call, see above - } - return Z_OK; - // If flush != Z_NO_FLUSH && avail_out == 0, the next call - // of deflate should use the same flush parameter to make sure - // that the flush is complete. So we don't have to output an - // empty block here, this will be done at next call. This also - // ensures that for a very small output buffer, we emit at most - // one empty block. - } - - if (bstate==BlockDone) { - if(flush == Z_PARTIAL_FLUSH) { - _tr_align(); - } - else { // FULL_FLUSH or SYNC_FLUSH - _tr_stored_block(0, 0, false); - // For a full flush, this empty block will be recognized - // as a special marker by inflate_sync(). - if(flush == Z_FULL_FLUSH) { - //state.head[s.hash_size-1]=0; - for(int i=0; i>8)&0xff)); - put_byte((byte)((adler>>16)&0xff)); - put_byte((byte)((adler>>24)&0xff)); - put_byte((byte)(strm.total_in&0xff)); - put_byte((byte)((strm.total_in>>8)&0xff)); - put_byte((byte)((strm.total_in>>16)&0xff)); - put_byte((byte)((strm.total_in>>24)&0xff)); - - getGZIPHeader().setCRC(adler); - } - else{ - // Write the zlib trailer (adler32) - long adler=strm.adler.getValue(); - putShortMSB((int)(adler>>>16)); - putShortMSB((int)(adler&0xffff)); - } - - strm.flush_pending(); - - // If avail_out is zero, the application will call deflate again - // to flush the rest. - - if(wrap > 0) wrap = -wrap; // write the trailer only once! - return pending != 0 ? Z_OK : Z_STREAM_END; - } - - static int deflateCopy(ZStream dest, ZStream src){ - - if(src.dstate == null){ - return Z_STREAM_ERROR; - } - - if(src.next_in!=null){ - dest.next_in = new byte[src.next_in.length]; - System.arraycopy(src.next_in, 0, dest.next_in, 0, src.next_in.length); - } - dest.next_in_index = src.next_in_index; - dest.avail_in = src.avail_in; - dest.total_in = src.total_in; - - if(src.next_out!=null){ - dest.next_out = new byte[src.next_out.length]; - System.arraycopy(src.next_out, 0, dest.next_out ,0 , src.next_out.length); - } - - dest.next_out_index = src.next_out_index; - dest.avail_out = src.avail_out; - dest.total_out = src.total_out; - - dest.msg = src.msg; - dest.data_type = src.data_type; - dest.adler = src.adler.copy(); - - try{ - dest.dstate = (Deflate)src.dstate.clone(); - dest.dstate.strm = dest; - } - catch(CloneNotSupportedException e){ - // - } - return Z_OK; - } - - public Object clone() throws CloneNotSupportedException { - Deflate dest = (Deflate)super.clone(); - - dest.pending_buf = dup(dest.pending_buf); - dest.window = dup(dest.window); - - dest.prev = dup(dest.prev); - dest.head = dup(dest.head); - dest.dyn_ltree = dup(dest.dyn_ltree); - dest.dyn_dtree = dup(dest.dyn_dtree); - dest.bl_tree = dup(dest.bl_tree); - - dest.bl_count = dup(dest.bl_count); - dest.next_code = dup(dest.next_code); - dest.heap = dup(dest.heap); - dest.depth = dup(dest.depth); - - dest.l_desc.dyn_tree = dest.dyn_ltree; - dest.d_desc.dyn_tree = dest.dyn_dtree; - dest.bl_desc.dyn_tree = dest.bl_tree; - - /* - dest.l_desc.stat_desc = StaticTree.static_l_desc; - dest.d_desc.stat_desc = StaticTree.static_d_desc; - dest.bl_desc.stat_desc = StaticTree.static_bl_desc; - */ - - if(dest.gheader!=null){ - dest.gheader = (GZIPHeader)dest.gheader.clone(); - } - - return dest; - } - - private byte[] dup(byte[] buf){ - byte[] foo = new byte[buf.length]; - System.arraycopy(buf, 0, foo, 0, foo.length); - return foo; - } - private short[] dup(short[] buf){ - short[] foo = new short[buf.length]; - System.arraycopy(buf, 0, foo, 0, foo.length); - return foo; - } - private int[] dup(int[] buf){ - int[] foo = new int[buf.length]; - System.arraycopy(buf, 0, foo, 0, foo.length); - return foo; - } - - synchronized GZIPHeader getGZIPHeader(){ - if(gheader==null){ - gheader = new GZIPHeader(); - } - return gheader; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Deflater.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Deflater.java deleted file mode 100644 index ce0580dd..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Deflater.java +++ /dev/null @@ -1,171 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jzlib; - -final public class Deflater extends ZStream{ - - static final private int MAX_WBITS=15; // 32K LZ77 window - static final private int DEF_WBITS=MAX_WBITS; - - static final private int Z_NO_FLUSH=0; - static final private int Z_PARTIAL_FLUSH=1; - static final private int Z_SYNC_FLUSH=2; - static final private int Z_FULL_FLUSH=3; - static final private int Z_FINISH=4; - - static final private int MAX_MEM_LEVEL=9; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - private boolean finished = false; - - public Deflater(){ - super(); - } - - public Deflater(int level) throws GZIPException { - this(level, MAX_WBITS); - } - - public Deflater(int level, boolean nowrap) throws GZIPException { - this(level, MAX_WBITS, nowrap); - } - - public Deflater(int level, int bits) throws GZIPException { - this(level, bits, false); - } - - public Deflater(int level, int bits, boolean nowrap) throws GZIPException { - super(); - int ret = init(level, bits, nowrap); - if(ret!=Z_OK) - throw new GZIPException(ret+": "+msg); - } - - public Deflater(int level, int bits, int memlevel, JZlib.WrapperType wrapperType) throws GZIPException { - super(); - int ret = init(level, bits, memlevel, wrapperType); - if(ret!=Z_OK) - throw new GZIPException(ret+": "+msg); - } - - public Deflater(int level, int bits, int memlevel) throws GZIPException { - super(); - int ret = init(level, bits, memlevel); - if(ret!=Z_OK) - throw new GZIPException(ret+": "+msg); - } - - public int init(int level){ - return init(level, MAX_WBITS); - } - public int init(int level, boolean nowrap){ - return init(level, MAX_WBITS, nowrap); - } - public int init(int level, int bits){ - return init(level, bits, false); - } - public int init(int level, int bits, int memlevel, JZlib.WrapperType wrapperType){ - if(bits < 9 || bits > 15){ - return Z_STREAM_ERROR; - } - if(wrapperType == JZlib.W_NONE) { - bits *= -1; - } - else if(wrapperType == JZlib.W_GZIP) { - bits += 16; - } - else if(wrapperType == JZlib.W_ANY) { - return Z_STREAM_ERROR; - } - else if(wrapperType == JZlib.W_ZLIB) { - } - return init(level, bits, memlevel); - } - public int init(int level, int bits, int memlevel){ - finished = false; - dstate=new Deflate(this); - return dstate.deflateInit(level, bits, memlevel); - } - public int init(int level, int bits, boolean nowrap){ - finished = false; - dstate=new Deflate(this); - return dstate.deflateInit(level, nowrap?-bits:bits); - } - - public int deflate(int flush){ - if(dstate==null){ - return Z_STREAM_ERROR; - } - int ret = dstate.deflate(flush); - if(ret == Z_STREAM_END) - finished = true; - return ret; - } - public int end(){ - finished = true; - if(dstate==null) return Z_STREAM_ERROR; - int ret=dstate.deflateEnd(); - dstate=null; - free(); - return ret; - } - public int params(int level, int strategy){ - if(dstate==null) return Z_STREAM_ERROR; - return dstate.deflateParams(level, strategy); - } - public int setDictionary (byte[] dictionary, int dictLength){ - if(dstate == null) - return Z_STREAM_ERROR; - return dstate.deflateSetDictionary(dictionary, dictLength); - } - - public boolean finished(){ - return finished; - } - - public int copy(Deflater src){ - this.finished = src.finished; - return Deflate.deflateCopy(this, src); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/DeflaterOutputStream.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/DeflaterOutputStream.java deleted file mode 100644 index 4c9f0d25..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/DeflaterOutputStream.java +++ /dev/null @@ -1,181 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.jcraft.jzlib; -import java.io.*; - -public class DeflaterOutputStream extends FilterOutputStream { - - protected final Deflater deflater; - - protected byte[] buffer; - - private boolean closed = false; - - private boolean syncFlush = false; - - private final byte[] buf1 = new byte[1]; - - protected boolean mydeflater = false; - - private boolean close_out = true; - - protected static final int DEFAULT_BUFSIZE = 512; - - public DeflaterOutputStream(OutputStream out) throws IOException { - this(out, - new Deflater(JZlib.Z_DEFAULT_COMPRESSION), - DEFAULT_BUFSIZE, true); - mydeflater = true; - } - - public DeflaterOutputStream(OutputStream out, Deflater def) throws IOException { - this(out, def, DEFAULT_BUFSIZE, true); - } - - public DeflaterOutputStream(OutputStream out, - Deflater deflater, - int size) throws IOException { - this(out, deflater, size, true); - } - public DeflaterOutputStream(OutputStream out, - Deflater deflater, - int size, - boolean close_out) throws IOException { - super(out); - if (out == null || deflater == null) { - throw new NullPointerException(); - } - else if (size <= 0) { - throw new IllegalArgumentException("buffer size must be greater than 0"); - } - this.deflater = deflater; - buffer = new byte[size]; - this.close_out = close_out; - } - - public void write(int b) throws IOException { - buf1[0] = (byte)(b & 0xff); - write(buf1, 0, 1); - } - - public void write(byte[] b, int off, int len) throws IOException { - if (deflater.finished()) { - throw new IOException("finished"); - } - else if (off<0 | len<0 | off+len>b.length) { - throw new IndexOutOfBoundsException(); - } - else if (len == 0) { - return; - } - else { - int flush = syncFlush ? JZlib.Z_SYNC_FLUSH : JZlib.Z_NO_FLUSH; - deflater.setInput(b, off, len, true); - while (deflater.avail_in>0) { - int err = deflate(flush); - if (err == JZlib.Z_STREAM_END) - break; - } - } - } - - public void finish() throws IOException { - while (!deflater.finished()) { - deflate(JZlib.Z_FINISH); - } - } - - public void close() throws IOException { - if (!closed) { - finish(); - if (mydeflater){ - deflater.end(); - } - if(close_out) - out.close(); - closed = true; - } - } - - protected int deflate(int flush) throws IOException { - deflater.setOutput(buffer, 0, buffer.length); - int err = deflater.deflate(flush); - switch(err) { - case JZlib.Z_OK: - case JZlib.Z_STREAM_END: - break; - case JZlib.Z_BUF_ERROR: - if(deflater.avail_in<=0 && flush!=JZlib.Z_FINISH){ - // flush() without any data - break; - } - default: - throw new IOException("failed to deflate"); - } - int len = deflater.next_out_index; - if (len > 0) { - out.write(buffer, 0, len); - } - return err; - } - - public void flush() throws IOException { - if (syncFlush && !deflater.finished()) { - while (true) { - int err = deflate(JZlib.Z_SYNC_FLUSH); - if (deflater.next_out_index < buffer.length) - break; - if (err == JZlib.Z_STREAM_END) - break; - } - } - out.flush(); - } - - public long getTotalIn() { - return deflater.getTotalIn(); - } - - public long getTotalOut() { - return deflater.getTotalOut(); - } - - public void setSyncFlush(boolean syncFlush){ - this.syncFlush = syncFlush; - } - - public boolean getSyncFlush(){ - return this.syncFlush; - } - - public Deflater getDeflater(){ - return deflater; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/GZIPException.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/GZIPException.java deleted file mode 100644 index 0beef40d..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/GZIPException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jzlib; - -public class GZIPException extends java.io.IOException { - public GZIPException() { - super(); - } - public GZIPException(String s) { - super(s); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/GZIPHeader.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/GZIPHeader.java deleted file mode 100644 index 0405e00b..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/GZIPHeader.java +++ /dev/null @@ -1,214 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jzlib; - -import java.io.UnsupportedEncodingException; - -/** - * @see "http://www.ietf.org/rfc/rfc1952.txt" - */ -public class GZIPHeader implements Cloneable { - - public static final byte OS_MSDOS = (byte) 0x00; - public static final byte OS_AMIGA = (byte) 0x01; - public static final byte OS_VMS = (byte) 0x02; - public static final byte OS_UNIX = (byte) 0x03; - public static final byte OS_ATARI = (byte) 0x05; - public static final byte OS_OS2 = (byte) 0x06; - public static final byte OS_MACOS = (byte) 0x07; - public static final byte OS_TOPS20 = (byte) 0x0a; - public static final byte OS_WIN32 = (byte) 0x0b; - public static final byte OS_VMCMS = (byte) 0x04; - public static final byte OS_ZSYSTEM = (byte) 0x08; - public static final byte OS_CPM = (byte) 0x09; - public static final byte OS_QDOS = (byte) 0x0c; - public static final byte OS_RISCOS = (byte) 0x0d; - public static final byte OS_UNKNOWN = (byte) 0xff; - - boolean text = false; - private boolean fhcrc = false; - long time; - int xflags; - int os = 255; - byte[] extra; - byte[] name; - byte[] comment; - int hcrc; - long crc; - boolean done = false; - long mtime = 0; - - public void setModifiedTime(long mtime) { - this.mtime = mtime; - } - - public long getModifiedTime() { - return mtime; - } - - public void setOS(int os) { - if((0<=os && os <=13) || os==255) - this.os=os; - else - throw new IllegalArgumentException("os: "+os); - } - - public int getOS(){ - return os; - } - - public void setName(String name) { - try{ - this.name=name.getBytes("ISO-8859-1"); - } - catch(UnsupportedEncodingException e){ - throw new IllegalArgumentException("name must be in ISO-8859-1 "+name); - } - } - - public String getName(){ - if(name==null) return ""; - try { - return new String(name, "ISO-8859-1"); - } - catch (UnsupportedEncodingException e) { - throw new InternalError(e.toString()); - } - } - - public void setComment(String comment) { - try{ - this.comment=comment.getBytes("ISO-8859-1"); - } - catch(UnsupportedEncodingException e){ - throw new IllegalArgumentException("comment must be in ISO-8859-1 "+name); - } - } - - public String getComment(){ - if(comment==null) return ""; - try { - return new String(comment, "ISO-8859-1"); - } - catch (UnsupportedEncodingException e) { - throw new InternalError(e.toString()); - } - } - - public void setCRC(long crc){ - this.crc = crc; - } - - public long getCRC(){ - return crc; - } - - void put(Deflate d){ - int flag = 0; - if(text){ - flag |= 1; // FTEXT - } - if(fhcrc){ - flag |= 2; // FHCRC - } - if(extra!=null){ - flag |= 4; // FEXTRA - } - if(name!=null){ - flag |= 8; // FNAME - } - if(comment!=null){ - flag |= 16; // FCOMMENT - } - int xfl = 0; - if(d.level == JZlib.Z_BEST_SPEED){ - xfl |= 4; - } - else if (d.level == JZlib.Z_BEST_COMPRESSION){ - xfl |= 2; - } - - d.put_short((short)0x8b1f); // ID1 ID2 - d.put_byte((byte)8); // CM(Compression Method) - d.put_byte((byte)flag); - d.put_byte((byte)mtime); - d.put_byte((byte)(mtime>>8)); - d.put_byte((byte)(mtime>>16)); - d.put_byte((byte)(mtime>>24)); - d.put_byte((byte)xfl); - d.put_byte((byte)os); - - if(extra!=null){ - d.put_byte((byte)extra.length); - d.put_byte((byte)(extra.length>>8)); - d.put_byte(extra, 0, extra.length); - } - - if(name!=null){ - d.put_byte(name, 0, name.length); - d.put_byte((byte)0); - } - - if(comment!=null){ - d.put_byte(comment, 0, comment.length); - d.put_byte((byte)0); - } - } - - @Override - public Object clone() throws CloneNotSupportedException { - GZIPHeader gheader = (GZIPHeader)super.clone(); - byte[] tmp; - if(gheader.extra!=null){ - tmp=new byte[gheader.extra.length]; - System.arraycopy(gheader.extra, 0, tmp, 0, tmp.length); - gheader.extra = tmp; - } - - if(gheader.name!=null){ - tmp=new byte[gheader.name.length]; - System.arraycopy(gheader.name, 0, tmp, 0, tmp.length); - gheader.name = tmp; - } - - if(gheader.comment!=null){ - tmp=new byte[gheader.comment.length]; - System.arraycopy(gheader.comment, 0, tmp, 0, tmp.length); - gheader.comment = tmp; - } - - return gheader; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/GZIPInputStream.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/GZIPInputStream.java deleted file mode 100644 index 5d29dca7..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/GZIPInputStream.java +++ /dev/null @@ -1,145 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.jcraft.jzlib; -import java.io.*; - -public class GZIPInputStream extends InflaterInputStream { - - public GZIPInputStream(InputStream in) throws IOException { - this(in, DEFAULT_BUFSIZE, true); - } - - public GZIPInputStream(InputStream in, - int size, - boolean close_in) throws IOException { - this(in, new Inflater(15+16), size, close_in); - myinflater = true; - } - - public GZIPInputStream(InputStream in, - Inflater inflater, - int size, - boolean close_in) throws IOException { - super(in, inflater, size, close_in); - } - - public long getModifiedtime() { - return inflater.istate.getGZIPHeader().getModifiedTime(); - } - - public int getOS() { - return inflater.istate.getGZIPHeader().getOS(); - } - - public String getName() { - return inflater.istate.getGZIPHeader().getName(); - } - - public String getComment() { - return inflater.istate.getGZIPHeader().getComment(); - } - - public long getCRC() throws GZIPException { - if(inflater.istate.mode != 12 /*DONE*/) - throw new GZIPException("checksum is not calculated yet."); - return inflater.istate.getGZIPHeader().getCRC(); - } - - public void readHeader() throws IOException { - - byte[] empty = "".getBytes(); - inflater.setOutput(empty, 0, 0); - inflater.setInput(empty, 0, 0, false); - - byte[] b = new byte[10]; - - int n = fill(b); - if(n!=10){ - if(n>0){ - inflater.setInput(b, 0, n, false); - //inflater.next_in_index = n; - inflater.next_in_index = 0; - inflater.avail_in = n; - } - throw new IOException("no input"); - } - - inflater.setInput(b, 0, n, false); - - byte[] b1 = new byte[1]; - do{ - if(inflater.avail_in<=0){ - int i = in.read(b1); - if(i<=0) - throw new IOException("no input"); - inflater.setInput(b1, 0, 1, true); - } - - int err = inflater.inflate(JZlib.Z_NO_FLUSH); - - if(err!=0/*Z_OK*/){ - int len = 2048-inflater.next_in.length; - if(len>0){ - byte[] tmp = new byte[len]; - n = fill(tmp); - if(n>0){ - inflater.avail_in += inflater.next_in_index; - inflater.next_in_index = 0; - inflater.setInput(tmp, 0, n, true); - } - } - //inflater.next_in_index = inflater.next_in.length; - inflater.avail_in += inflater.next_in_index; - inflater.next_in_index = 0; - throw new IOException(inflater.msg); - } - } - while(inflater.istate.inParsingHeader()); - } - - private int fill(byte[] buf) { - int len = buf.length; - int n = 0; - do{ - int i = -1; - try { - i = in.read(buf, n, buf.length - n); - } - catch(IOException e){ - } - if(i == -1){ - break; - } - n+=i; - } - while(n>> 1){ - case 0: // stored - {b>>>=(3);k-=(3);} - t = k & 7; // go to byte boundary - - {b>>>=(t);k-=(t);} - mode = LENS; // get length of stored block - break; - case 1: // fixed - InfTree.inflate_trees_fixed(bl, bd, tl, td, z); - codes.init(bl[0], bd[0], tl[0], 0, td[0], 0); - - {b>>>=(3);k-=(3);} - - mode = CODES; - break; - case 2: // dynamic - - {b>>>=(3);k-=(3);} - - mode = TABLE; - break; - case 3: // illegal - - {b>>>=(3);k-=(3);} - mode = BAD; - z.msg = "invalid block type"; - r = Z_DATA_ERROR; - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - break; - case LENS: - - while(k<(32)){ - if(n!=0){ - r=Z_OK; - } - else{ - bitb=b; bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - }; - n--; - b|=(z.next_in[p++]&0xff)<>> 16) & 0xffff) != (b & 0xffff)){ - mode = BAD; - z.msg = "invalid stored block lengths"; - r = Z_DATA_ERROR; - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - left = (b & 0xffff); - b = k = 0; // dump bits - mode = left!=0 ? STORED : (last!=0 ? DRY : TYPE); - break; - case STORED: - if (n == 0){ - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - - if(m==0){ - if(q==end&&read!=0){ - q=0; m=(int)(qn) t = n; - if(t>m) t = m; - System.arraycopy(z.next_in, p, window, q, t); - p += t; n -= t; - q += t; m -= t; - if ((left -= t) != 0) - break; - mode = last!=0 ? DRY : TYPE; - break; - case TABLE: - - while(k<(14)){ - if(n!=0){ - r=Z_OK; - } - else{ - bitb=b; bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - }; - n--; - b|=(z.next_in[p++]&0xff)< 29 || ((t >> 5) & 0x1f) > 29) - { - mode = BAD; - z.msg = "too many length or distance symbols"; - r = Z_DATA_ERROR; - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if(blens==null || blens.length>>=(14);k-=(14);} - - index = 0; - mode = BTREE; - case BTREE: - while (index < 4 + (table >>> 10)){ - while(k<(3)){ - if(n!=0){ - r=Z_OK; - } - else{ - bitb=b; bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - }; - n--; - b|=(z.next_in[p++]&0xff)<>>=(3);k-=(3);} - } - - while(index < 19){ - blens[border[index++]] = 0; - } - - bb[0] = 7; - t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z); - if (t != Z_OK){ - r = t; - if (r == Z_DATA_ERROR){ - blens=null; - mode = BAD; - } - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - - index = 0; - mode = DTREE; - case DTREE: - while (true){ - t = table; - if(!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){ - break; - } - - int[] h; - int i, j, c; - - t = bb[0]; - - while(k<(t)){ - if(n!=0){ - r=Z_OK; - } - else{ - bitb=b; bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - }; - n--; - b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); - blens[index++] = c; - } - else { // c == 16..18 - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - - while(k<(t+i)){ - if(n!=0){ - r=Z_OK; - } - else{ - bitb=b; bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - }; - n--; - b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); - - j += (b & inflate_mask[i]); - - b>>>=(i);k-=(i); - - i = index; - t = table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || - (c == 16 && i < 1)){ - blens=null; - mode = BAD; - z.msg = "invalid bit length repeat"; - r = Z_DATA_ERROR; - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - - c = c == 16 ? blens[i-1] : 0; - do{ - blens[i++] = c; - } - while (--j!=0); - index = i; - } - } - - tb[0]=-1; - { - bl[0] = 9; // must be <= 9 for lookahead assumptions - bd[0] = 6; // must be <= 9 for lookahead assumptions - t = table; - t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), - 1 + ((t >> 5) & 0x1f), - blens, bl, bd, tli, tdi, hufts, z); - - if (t != Z_OK){ - if (t == Z_DATA_ERROR){ - blens=null; - mode = BAD; - } - r = t; - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - codes.init(bl[0], bd[0], hufts, tli[0], hufts, tdi[0]); - } - mode = CODES; - case CODES: - bitb=b; bitk=k; - z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - - if ((r = codes.proc(r)) != Z_STREAM_END){ - return inflate_flush(r); - } - r = Z_OK; - codes.free(z); - - p=z.next_in_index; n=z.avail_in;b=bitb;k=bitk; - q=write;m=(int)(q z.avail_out) n = z.avail_out; - if(n!=0 && r == Z_BUF_ERROR) r = Z_OK; - - // update counters - z.avail_out -= n; - z.total_out += n; - - // update check information - if(check && n>0){ - z.adler.update(window, q, n); - } - - // copy as far as end of window - System.arraycopy(window, q, z.next_out, p, n); - p += n; - q += n; - - // see if more to copy at beginning of window - if (q == end){ - // wrap pointers - q = 0; - if (write == end) - write = 0; - - // compute bytes to copy - n = write - q; - if (n > z.avail_out) n = z.avail_out; - if (n!=0 && r == Z_BUF_ERROR) r = Z_OK; - - // update counters - z.avail_out -= n; - z.total_out += n; - - // update check information - if(check && n>0){ - z.adler.update(window, q, n); - } - - // copy - System.arraycopy(window, q, z.next_out, p, n); - p += n; - q += n; - } - - // update pointers - z.next_out_index = p; - read = q; - - // done - return r; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/InfCodes.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/InfCodes.java deleted file mode 100644 index aaf69cd4..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/InfCodes.java +++ /dev/null @@ -1,610 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jzlib; - -final class InfCodes{ - - static final private int[] inflate_mask = { - 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, - 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, - 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, - 0x00007fff, 0x0000ffff - }; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - // waiting for "i:"=input, - // "o:"=output, - // "x:"=nothing - static final private int START=0; // x: set up for LEN - static final private int LEN=1; // i: get length/literal/eob next - static final private int LENEXT=2; // i: getting length extra (have base) - static final private int DIST=3; // i: get distance next - static final private int DISTEXT=4;// i: getting distance extra - static final private int COPY=5; // o: copying bytes in window, waiting for space - static final private int LIT=6; // o: got literal, waiting for output space - static final private int WASH=7; // o: got eob, possibly still output waiting - static final private int END=8; // x: got eob and all data flushed - static final private int BADCODE=9;// x: got error - - int mode; // current inflate_codes mode - - // mode dependent information - int len; - - int[] tree; // pointer into tree - int tree_index=0; - int need; // bits needed - - int lit; - - // if EXT or COPY, where and how much - int get; // bits to get for extra - int dist; // distance back to copy from - - byte lbits; // ltree bits decoded per branch - byte dbits; // dtree bits decoder per branch - int[] ltree; // literal/length/eob tree - int ltree_index; // literal/length/eob tree - int[] dtree; // distance tree - int dtree_index; // distance tree - - private final ZStream z; - private final InfBlocks s; - InfCodes(ZStream z, InfBlocks s){ - this.z=z; - this.s=s; - } - - void init(int bl, int bd, - int[] tl, int tl_index, - int[] td, int td_index){ - mode=START; - lbits=(byte)bl; - dbits=(byte)bd; - ltree=tl; - ltree_index=tl_index; - dtree = td; - dtree_index=td_index; - tree=null; - } - - int proc(int r){ - int j; // temporary storage - int[] t; // temporary pointer - int tindex; // temporary pointer - int e; // extra bits or operation - int b=0; // bit buffer - int k=0; // bits in bit buffer - int p=0; // input data pointer - int n; // bytes available there - int q; // output window write pointer - int m; // bytes to end of window or read pointer - int f; // pointer to copy strings from - - // copy input/output information to locals (UPDATE macro restores) - p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; - q=s.write;m=q= 258 && n >= 10){ - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - r = inflate_fast(lbits, dbits, - ltree, ltree_index, - dtree, dtree_index, - s, z); - - p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; - q=s.write;m=q>>=(tree[tindex+1]); - k-=(tree[tindex+1]); - - e=tree[tindex]; - - if(e == 0){ // literal - lit = tree[tindex+2]; - mode = LIT; - break; - } - if((e & 16)!=0 ){ // length - get = e & 15; - len = tree[tindex+2]; - mode = LENEXT; - break; - } - if ((e & 64) == 0){ // next table - need = e; - tree_index = tindex/3+tree[tindex+2]; - break; - } - if ((e & 32)!=0){ // end of block - mode = WASH; - break; - } - mode = BADCODE; // invalid code - z.msg = "invalid literal/length code"; - r = Z_DATA_ERROR; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(r); - - case LENEXT: // i: getting length extra (have base) - j = get; - - while(k<(j)){ - if(n!=0)r=Z_OK; - else{ - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(r); - } - n--; b|=(z.next_in[p++]&0xff)<>=j; - k-=j; - - need = dbits; - tree = dtree; - tree_index=dtree_index; - mode = DIST; - case DIST: // i: get distance next - j = need; - - while(k<(j)){ - if(n!=0)r=Z_OK; - else{ - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(r); - } - n--; b|=(z.next_in[p++]&0xff)<>=tree[tindex+1]; - k-=tree[tindex+1]; - - e = (tree[tindex]); - if((e & 16)!=0){ // distance - get = e & 15; - dist = tree[tindex+2]; - mode = DISTEXT; - break; - } - if ((e & 64) == 0){ // next table - need = e; - tree_index = tindex/3 + tree[tindex+2]; - break; - } - mode = BADCODE; // invalid code - z.msg = "invalid distance code"; - r = Z_DATA_ERROR; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(r); - - case DISTEXT: // i: getting distance extra - j = get; - - while(k<(j)){ - if(n!=0)r=Z_OK; - else{ - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(r); - } - n--; b|=(z.next_in[p++]&0xff)<>=j; - k-=j; - - mode = COPY; - case COPY: // o: copying bytes in window, waiting for space - f = q - dist; - while(f < 0){ // modulo window size-"while" instead - f += s.end; // of "if" handles invalid distances - } - while (len!=0){ - - if(m==0){ - if(q==s.end&&s.read!=0){q=0;m=q 7){ // return unused byte, if any - k -= 8; - n++; - p--; // can always return one - } - - s.write=q; r=s.inflate_flush(r); - q=s.write;m=q= 258 && n >= 10 - // get literal/length code - while(k<(20)){ // max bits for literal/length code - n--; - b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); - - s.window[q++] = (byte)tp[tp_index_t_3+2]; - m--; - continue; - } - do { - - b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); - - if((e&16)!=0){ - e &= 15; - c = tp[tp_index_t_3+2] + ((int)b & inflate_mask[e]); - - b>>=e; k-=e; - - // decode distance base of block to copy - while(k<(15)){ // max bits for distance code - n--; - b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); - - if((e&16)!=0){ - // get extra bits to add to distance base - e &= 15; - while(k<(e)){ // get extra bits (up to 13) - n--; - b|=(z.next_in[p++]&0xff)<>=(e); k-=(e); - - // do the copy - m -= c; - if (q >= d){ // offset before dest - // just copy - r=q-d; - if(q-r>0 && 2>(q-r)){ - s.window[q++]=s.window[r++]; // minimum count is three, - s.window[q++]=s.window[r++]; // so unroll loop a little - c-=2; - } - else{ - System.arraycopy(s.window, r, s.window, q, 2); - q+=2; r+=2; c-=2; - } - } - else{ // else offset after destination - r=q-d; - do{ - r+=s.end; // force pointer in window - }while(r<0); // covers invalid distances - e=s.end-r; - if(c>e){ // if source crosses, - c-=e; // wrapped copy - if(q-r>0 && e>(q-r)){ - do{s.window[q++] = s.window[r++];} - while(--e!=0); - } - else{ - System.arraycopy(s.window, r, s.window, q, e); - q+=e; r+=e; e=0; - } - r = 0; // copy rest from start of window - } - - } - - // copy all or what's left - if(q-r>0 && c>(q-r)){ - do{s.window[q++] = s.window[r++];} - while(--c!=0); - } - else{ - System.arraycopy(s.window, r, s.window, q, c); - q+=c; r+=c; c=0; - } - break; - } - else if((e&64)==0){ - t+=tp[tp_index_t_3+2]; - t+=(b&inflate_mask[e]); - tp_index_t_3=(tp_index+t)*3; - e=tp[tp_index_t_3]; - } - else{ - z.msg = "invalid distance code"; - - c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - - return Z_DATA_ERROR; - } - } - while(true); - break; - } - - if((e&64)==0){ - t+=tp[tp_index_t_3+2]; - t+=(b&inflate_mask[e]); - tp_index_t_3=(tp_index+t)*3; - if((e=tp[tp_index_t_3])==0){ - - b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); - - s.window[q++]=(byte)tp[tp_index_t_3+2]; - m--; - break; - } - } - else if((e&32)!=0){ - - c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - - return Z_STREAM_END; - } - else{ - z.msg="invalid literal/length code"; - - c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - - return Z_DATA_ERROR; - } - } - while(true); - } - while(m>=258 && n>= 10); - - // not enough input or output--restore pointers and return - c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - - return Z_OK; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/InfTree.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/InfTree.java deleted file mode 100644 index 80a2b7b6..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/InfTree.java +++ /dev/null @@ -1,518 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jzlib; - -final class InfTree{ - - static final private int MANY=1440; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - static final int fixed_bl = 9; - static final int fixed_bd = 5; - - static final int[] fixed_tl = { - 96,7,256, 0,8,80, 0,8,16, 84,8,115, - 82,7,31, 0,8,112, 0,8,48, 0,9,192, - 80,7,10, 0,8,96, 0,8,32, 0,9,160, - 0,8,0, 0,8,128, 0,8,64, 0,9,224, - 80,7,6, 0,8,88, 0,8,24, 0,9,144, - 83,7,59, 0,8,120, 0,8,56, 0,9,208, - 81,7,17, 0,8,104, 0,8,40, 0,9,176, - 0,8,8, 0,8,136, 0,8,72, 0,9,240, - 80,7,4, 0,8,84, 0,8,20, 85,8,227, - 83,7,43, 0,8,116, 0,8,52, 0,9,200, - 81,7,13, 0,8,100, 0,8,36, 0,9,168, - 0,8,4, 0,8,132, 0,8,68, 0,9,232, - 80,7,8, 0,8,92, 0,8,28, 0,9,152, - 84,7,83, 0,8,124, 0,8,60, 0,9,216, - 82,7,23, 0,8,108, 0,8,44, 0,9,184, - 0,8,12, 0,8,140, 0,8,76, 0,9,248, - 80,7,3, 0,8,82, 0,8,18, 85,8,163, - 83,7,35, 0,8,114, 0,8,50, 0,9,196, - 81,7,11, 0,8,98, 0,8,34, 0,9,164, - 0,8,2, 0,8,130, 0,8,66, 0,9,228, - 80,7,7, 0,8,90, 0,8,26, 0,9,148, - 84,7,67, 0,8,122, 0,8,58, 0,9,212, - 82,7,19, 0,8,106, 0,8,42, 0,9,180, - 0,8,10, 0,8,138, 0,8,74, 0,9,244, - 80,7,5, 0,8,86, 0,8,22, 192,8,0, - 83,7,51, 0,8,118, 0,8,54, 0,9,204, - 81,7,15, 0,8,102, 0,8,38, 0,9,172, - 0,8,6, 0,8,134, 0,8,70, 0,9,236, - 80,7,9, 0,8,94, 0,8,30, 0,9,156, - 84,7,99, 0,8,126, 0,8,62, 0,9,220, - 82,7,27, 0,8,110, 0,8,46, 0,9,188, - 0,8,14, 0,8,142, 0,8,78, 0,9,252, - 96,7,256, 0,8,81, 0,8,17, 85,8,131, - 82,7,31, 0,8,113, 0,8,49, 0,9,194, - 80,7,10, 0,8,97, 0,8,33, 0,9,162, - 0,8,1, 0,8,129, 0,8,65, 0,9,226, - 80,7,6, 0,8,89, 0,8,25, 0,9,146, - 83,7,59, 0,8,121, 0,8,57, 0,9,210, - 81,7,17, 0,8,105, 0,8,41, 0,9,178, - 0,8,9, 0,8,137, 0,8,73, 0,9,242, - 80,7,4, 0,8,85, 0,8,21, 80,8,258, - 83,7,43, 0,8,117, 0,8,53, 0,9,202, - 81,7,13, 0,8,101, 0,8,37, 0,9,170, - 0,8,5, 0,8,133, 0,8,69, 0,9,234, - 80,7,8, 0,8,93, 0,8,29, 0,9,154, - 84,7,83, 0,8,125, 0,8,61, 0,9,218, - 82,7,23, 0,8,109, 0,8,45, 0,9,186, - 0,8,13, 0,8,141, 0,8,77, 0,9,250, - 80,7,3, 0,8,83, 0,8,19, 85,8,195, - 83,7,35, 0,8,115, 0,8,51, 0,9,198, - 81,7,11, 0,8,99, 0,8,35, 0,9,166, - 0,8,3, 0,8,131, 0,8,67, 0,9,230, - 80,7,7, 0,8,91, 0,8,27, 0,9,150, - 84,7,67, 0,8,123, 0,8,59, 0,9,214, - 82,7,19, 0,8,107, 0,8,43, 0,9,182, - 0,8,11, 0,8,139, 0,8,75, 0,9,246, - 80,7,5, 0,8,87, 0,8,23, 192,8,0, - 83,7,51, 0,8,119, 0,8,55, 0,9,206, - 81,7,15, 0,8,103, 0,8,39, 0,9,174, - 0,8,7, 0,8,135, 0,8,71, 0,9,238, - 80,7,9, 0,8,95, 0,8,31, 0,9,158, - 84,7,99, 0,8,127, 0,8,63, 0,9,222, - 82,7,27, 0,8,111, 0,8,47, 0,9,190, - 0,8,15, 0,8,143, 0,8,79, 0,9,254, - 96,7,256, 0,8,80, 0,8,16, 84,8,115, - 82,7,31, 0,8,112, 0,8,48, 0,9,193, - - 80,7,10, 0,8,96, 0,8,32, 0,9,161, - 0,8,0, 0,8,128, 0,8,64, 0,9,225, - 80,7,6, 0,8,88, 0,8,24, 0,9,145, - 83,7,59, 0,8,120, 0,8,56, 0,9,209, - 81,7,17, 0,8,104, 0,8,40, 0,9,177, - 0,8,8, 0,8,136, 0,8,72, 0,9,241, - 80,7,4, 0,8,84, 0,8,20, 85,8,227, - 83,7,43, 0,8,116, 0,8,52, 0,9,201, - 81,7,13, 0,8,100, 0,8,36, 0,9,169, - 0,8,4, 0,8,132, 0,8,68, 0,9,233, - 80,7,8, 0,8,92, 0,8,28, 0,9,153, - 84,7,83, 0,8,124, 0,8,60, 0,9,217, - 82,7,23, 0,8,108, 0,8,44, 0,9,185, - 0,8,12, 0,8,140, 0,8,76, 0,9,249, - 80,7,3, 0,8,82, 0,8,18, 85,8,163, - 83,7,35, 0,8,114, 0,8,50, 0,9,197, - 81,7,11, 0,8,98, 0,8,34, 0,9,165, - 0,8,2, 0,8,130, 0,8,66, 0,9,229, - 80,7,7, 0,8,90, 0,8,26, 0,9,149, - 84,7,67, 0,8,122, 0,8,58, 0,9,213, - 82,7,19, 0,8,106, 0,8,42, 0,9,181, - 0,8,10, 0,8,138, 0,8,74, 0,9,245, - 80,7,5, 0,8,86, 0,8,22, 192,8,0, - 83,7,51, 0,8,118, 0,8,54, 0,9,205, - 81,7,15, 0,8,102, 0,8,38, 0,9,173, - 0,8,6, 0,8,134, 0,8,70, 0,9,237, - 80,7,9, 0,8,94, 0,8,30, 0,9,157, - 84,7,99, 0,8,126, 0,8,62, 0,9,221, - 82,7,27, 0,8,110, 0,8,46, 0,9,189, - 0,8,14, 0,8,142, 0,8,78, 0,9,253, - 96,7,256, 0,8,81, 0,8,17, 85,8,131, - 82,7,31, 0,8,113, 0,8,49, 0,9,195, - 80,7,10, 0,8,97, 0,8,33, 0,9,163, - 0,8,1, 0,8,129, 0,8,65, 0,9,227, - 80,7,6, 0,8,89, 0,8,25, 0,9,147, - 83,7,59, 0,8,121, 0,8,57, 0,9,211, - 81,7,17, 0,8,105, 0,8,41, 0,9,179, - 0,8,9, 0,8,137, 0,8,73, 0,9,243, - 80,7,4, 0,8,85, 0,8,21, 80,8,258, - 83,7,43, 0,8,117, 0,8,53, 0,9,203, - 81,7,13, 0,8,101, 0,8,37, 0,9,171, - 0,8,5, 0,8,133, 0,8,69, 0,9,235, - 80,7,8, 0,8,93, 0,8,29, 0,9,155, - 84,7,83, 0,8,125, 0,8,61, 0,9,219, - 82,7,23, 0,8,109, 0,8,45, 0,9,187, - 0,8,13, 0,8,141, 0,8,77, 0,9,251, - 80,7,3, 0,8,83, 0,8,19, 85,8,195, - 83,7,35, 0,8,115, 0,8,51, 0,9,199, - 81,7,11, 0,8,99, 0,8,35, 0,9,167, - 0,8,3, 0,8,131, 0,8,67, 0,9,231, - 80,7,7, 0,8,91, 0,8,27, 0,9,151, - 84,7,67, 0,8,123, 0,8,59, 0,9,215, - 82,7,19, 0,8,107, 0,8,43, 0,9,183, - 0,8,11, 0,8,139, 0,8,75, 0,9,247, - 80,7,5, 0,8,87, 0,8,23, 192,8,0, - 83,7,51, 0,8,119, 0,8,55, 0,9,207, - 81,7,15, 0,8,103, 0,8,39, 0,9,175, - 0,8,7, 0,8,135, 0,8,71, 0,9,239, - 80,7,9, 0,8,95, 0,8,31, 0,9,159, - 84,7,99, 0,8,127, 0,8,63, 0,9,223, - 82,7,27, 0,8,111, 0,8,47, 0,9,191, - 0,8,15, 0,8,143, 0,8,79, 0,9,255 - }; - static final int[] fixed_td = { - 80,5,1, 87,5,257, 83,5,17, 91,5,4097, - 81,5,5, 89,5,1025, 85,5,65, 93,5,16385, - 80,5,3, 88,5,513, 84,5,33, 92,5,8193, - 82,5,9, 90,5,2049, 86,5,129, 192,5,24577, - 80,5,2, 87,5,385, 83,5,25, 91,5,6145, - 81,5,7, 89,5,1537, 85,5,97, 93,5,24577, - 80,5,4, 88,5,769, 84,5,49, 92,5,12289, - 82,5,13, 90,5,3073, 86,5,193, 192,5,24577 - }; - - // Tables for deflate from PKZIP's appnote.txt. - static final int[] cplens = { // Copy lengths for literal codes 257..285 - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 - }; - - // see note #13 above about 258 - static final int[] cplext = { // Extra bits for literal codes 257..285 - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid - }; - - static final int[] cpdist = { // Copy offsets for distance codes 0..29 - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577 - }; - - static final int[] cpdext = { // Extra bits for distance codes - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13}; - - // If BMAX needs to be larger than 16, then h and x[] should be uLong. - static final int BMAX=15; // maximum bit length of any code - - int[] hn = null; // hufts used in space - int[] v = null; // work area for huft_build - int[] c = null; // bit length count table - int[] r = null; // table entry for structure assignment - int[] u = null; // table stack - int[] x = null; // bit offsets, then code stack - - private int huft_build(int[] b, // code lengths in bits (all assumed <= BMAX) - int bindex, - int n, // number of codes (assumed <= 288) - int s, // number of simple-valued codes (0..s-1) - int[] d, // list of base values for non-simple codes - int[] e, // list of extra bits for non-simple codes - int[] t, // result: starting table - int[] m, // maximum lookup bits, returns actual - int[] hp,// space for trees - int[] hn,// hufts used in space - int[] v // working area: values in order of bit length - ){ - // Given a list of code lengths and a maximum table size, make a set of - // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - // if the given code set is incomplete (the tables are still built in this - // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of - // lengths), or Z_MEM_ERROR if not enough memory. - - int a; // counter for codes of length k - int f; // i repeats in table every f entries - int g; // maximum code length - int h; // table level - int i; // counter, current code - int j; // counter - int k; // number of bits in current code - int l; // bits per table (returned in m) - int mask; // (1 << w) - 1, to avoid cc -O bug on HP - int p; // pointer into c[], b[], or v[] - int q; // points to current table - int w; // bits before this table == (l * h) - int xp; // pointer into x - int y; // number of dummy codes added - int z; // number of entries in current table - - // Generate counts for each bit length - - p = 0; i = n; - do { - c[b[bindex+p]]++; p++; i--; // assume all entries <= BMAX - }while(i!=0); - - if(c[0] == n){ // null input--all zero length codes - t[0] = -1; - m[0] = 0; - return Z_OK; - } - - // Find minimum and maximum length, bound *m by those - l = m[0]; - for (j = 1; j <= BMAX; j++) - if(c[j]!=0) break; - k = j; // minimum code length - if(l < j){ - l = j; - } - for (i = BMAX; i!=0; i--){ - if(c[i]!=0) break; - } - g = i; // maximum code length - if(l > i){ - l = i; - } - m[0] = l; - - // Adjust last length count to fill out codes, if needed - for (y = 1 << j; j < i; j++, y <<= 1){ - if ((y -= c[j]) < 0){ - return Z_DATA_ERROR; - } - } - if ((y -= c[i]) < 0){ - return Z_DATA_ERROR; - } - c[i] += y; - - // Generate starting offsets into the value table for each length - x[1] = j = 0; - p = 1; xp = 2; - while (--i!=0) { // note that i == g from above - x[xp] = (j += c[p]); - xp++; - p++; - } - - // Make a table of values in order of bit lengths - i = 0; p = 0; - do { - if ((j = b[bindex+p]) != 0){ - v[x[j]++] = i; - } - p++; - } - while (++i < n); - n = x[g]; // set n to length of v - - // Generate the Huffman codes and for each, make the table entries - x[0] = i = 0; // first Huffman code is zero - p = 0; // grab values in bit order - h = -1; // no tables yet--level -1 - w = -l; // bits decoded == (l * h) - u[0] = 0; // just to keep compilers happy - q = 0; // ditto - z = 0; // ditto - - // go through the bit lengths (k already is bits in shortest code) - for (; k <= g; k++){ - a = c[k]; - while (a--!=0){ - // here i is the Huffman code of length k bits for value *p - // make tables up to required level - while (k > w + l){ - h++; - w += l; // previous table always l bits - // compute minimum size table less than or equal to l bits - z = g - w; - z = (z > l) ? l : z; // table size upper limit - if((f=1<<(j=k-w))>a+1){ // try a k-w bit table - // too few codes for k-w bit table - f -= a + 1; // deduct codes from patterns left - xp = k; - if(j < z){ - while (++j < z){ // try smaller tables up to z bits - if((f <<= 1) <= c[++xp]) - break; // enough codes to use up j bits - f -= c[xp]; // else deduct codes from patterns - } - } - } - z = 1 << j; // table entries for j-bit table - - // allocate new table - if (hn[0] + z > MANY){ // (note: doesn't matter for fixed) - return Z_DATA_ERROR; // overflow of MANY - } - u[h] = q = /*hp+*/ hn[0]; // DEBUG - hn[0] += z; - - // connect to last table, if there is one - if(h!=0){ - x[h]=i; // save pattern for backing up - r[0]=(byte)j; // bits in this table - r[1]=(byte)l; // bits to dump before this table - j=i>>>(w - l); - r[2] = (int)(q - u[h-1] - j); // offset to this table - System.arraycopy(r, 0, hp, (u[h-1]+j)*3, 3); // connect to last table - } - else{ - t[0] = q; // first table is returned result - } - } - - // set up table entry in r - r[1] = (byte)(k - w); - if (p >= n){ - r[0] = 128 + 64; // out of values--invalid code - } - else if (v[p] < s){ - r[0] = (byte)(v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block - r[2] = v[p++]; // simple code is just the value - } - else{ - r[0]=(byte)(e[v[p]-s]+16+64); // non-simple--look up in lists - r[2]=d[v[p++] - s]; - } - - // fill code-like entries with r - f=1<<(k-w); - for (j=i>>>w;j>>= 1){ - i ^= j; - } - i ^= j; - - // backup over finished tables - mask = (1 << w) - 1; // needed on HP, cc -O bug - while ((i & mask) != x[h]){ - h--; // don't need to update q - w -= l; - mask = (1 << w) - 1; - } - } - } - // Return Z_BUF_ERROR if we were given an incomplete table - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; - } - - int inflate_trees_bits(int[] c, // 19 code lengths - int[] bb, // bits tree desired/actual depth - int[] tb, // bits tree result - int[] hp, // space for trees - ZStream z // for messages - ){ - int result; - initWorkArea(19); - hn[0]=0; - result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); - - if(result == Z_DATA_ERROR){ - z.msg = "oversubscribed dynamic bit lengths tree"; - } - else if(result == Z_BUF_ERROR || bb[0] == 0){ - z.msg = "incomplete dynamic bit lengths tree"; - result = Z_DATA_ERROR; - } - return result; - } - - int inflate_trees_dynamic(int nl, // number of literal/length codes - int nd, // number of distance codes - int[] c, // that many (total) code lengths - int[] bl, // literal desired/actual bit depth - int[] bd, // distance desired/actual bit depth - int[] tl, // literal/length tree result - int[] td, // distance tree result - int[] hp, // space for trees - ZStream z // for messages - ){ - int result; - - // build literal/length tree - initWorkArea(288); - hn[0]=0; - result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); - if (result != Z_OK || bl[0] == 0){ - if(result == Z_DATA_ERROR){ - z.msg = "oversubscribed literal/length tree"; - } - else if (result != Z_MEM_ERROR){ - z.msg = "incomplete literal/length tree"; - result = Z_DATA_ERROR; - } - return result; - } - - // build distance tree - initWorkArea(288); - result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); - - if (result != Z_OK || (bd[0] == 0 && nl > 257)){ - if (result == Z_DATA_ERROR){ - z.msg = "oversubscribed distance tree"; - } - else if (result == Z_BUF_ERROR) { - z.msg = "incomplete distance tree"; - result = Z_DATA_ERROR; - } - else if (result != Z_MEM_ERROR){ - z.msg = "empty distance tree with lengths"; - result = Z_DATA_ERROR; - } - return result; - } - - return Z_OK; - } - - static int inflate_trees_fixed(int[] bl, //literal desired/actual bit depth - int[] bd, //distance desired/actual bit depth - int[][] tl,//literal/length tree result - int[][] td,//distance tree result - ZStream z //for memory allocation - ){ - bl[0]=fixed_bl; - bd[0]=fixed_bd; - tl[0]=fixed_tl; - td[0]=fixed_td; - return Z_OK; - } - - private void initWorkArea(int vsize){ - if(hn==null){ - hn=new int[1]; - v=new int[vsize]; - c=new int[BMAX+1]; - r=new int[3]; - u=new int[BMAX]; - x=new int[BMAX+1]; - } - if(v.length> 4) + 1; - if(w < 48) - w &= 15; - } - - if(w<8 ||w>15){ - inflateEnd(); - return Z_STREAM_ERROR; - } - if(blocks != null && wbits != w){ - blocks.free(); - blocks=null; - } - - // set window size - wbits=w; - - this.blocks=new InfBlocks(z, 1<>8))&0xff; - - if(((wrap&1)==0 || // check if zlib header allowed - (((this.method << 8)+b) % 31)!=0) && - (this.method&0xf)!=Z_DEFLATED){ - if(wrap == 4){ - z.next_in_index -= 2; - z.avail_in += 2; - z.total_in -= 2; - wrap = 0; - this.mode = BLOCKS; - break; - } - this.mode = BAD; - z.msg = "incorrect header check"; - // since zlib 1.2, it is allowted to inflateSync for this case. - /* - this.marker = 5; // can't try inflateSync - */ - break; - } - - if((this.method&0xf)!=Z_DEFLATED){ - this.mode = BAD; - z.msg="unknown compression method"; - // since zlib 1.2, it is allowted to inflateSync for this case. - /* - this.marker = 5; // can't try inflateSync - */ - break; - } - - if(wrap == 4){ - wrap = 1; - } - - if((this.method>>4)+8>this.wbits){ - this.mode = BAD; - z.msg="invalid window size"; - // since zlib 1.2, it is allowted to inflateSync for this case. - /* - this.marker = 5; // can't try inflateSync - */ - break; - } - - z.adler=new Adler32(); - - if((b&PRESET_DICT)==0){ - this.mode = BLOCKS; - break; - } - this.mode = DICT4; - case DICT4: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; - this.mode=DICT3; - case DICT3: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; - this.mode=DICT2; - case DICT2: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; - this.mode=DICT1; - case DICT1: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need += (z.next_in[z.next_in_index++]&0xffL); - z.adler.reset(this.need); - this.mode = DICT0; - return Z_NEED_DICT; - case DICT0: - this.mode = BAD; - z.msg = "need dictionary"; - this.marker = 0; // can try inflateSync - return Z_STREAM_ERROR; - case BLOCKS: - r = this.blocks.proc(r); - if(r == Z_DATA_ERROR){ - this.mode = BAD; - this.marker = 0; // can try inflateSync - break; - } - if(r == Z_OK){ - r = f; - } - if(r != Z_STREAM_END){ - return r; - } - r = f; - this.was=z.adler.getValue(); - this.blocks.reset(); - if(this.wrap==0){ - this.mode=DONE; - break; - } - this.mode=CHECK4; - case CHECK4: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; - this.mode=CHECK3; - case CHECK3: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; - this.mode = CHECK2; - case CHECK2: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; - this.mode = CHECK1; - case CHECK1: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=(z.next_in[z.next_in_index++]&0xffL); - - if(flags!=0){ // gzip - this.need = ((this.need&0xff000000)>>24 | - (this.need&0x00ff0000)>>8 | - (this.need&0x0000ff00)<<8 | - (this.need&0x0000ffff)<<24)&0xffffffffL; - } - - if(((int)(this.was)) != ((int)(this.need))){ - z.msg = "incorrect data check"; - // chack is delayed - /* - this.mode = BAD; - this.marker = 5; // can't try inflateSync - break; - */ - } - else if(flags!=0 && gheader!=null){ - gheader.crc = this.need; - } - - this.mode = LENGTH; - case LENGTH: - if (wrap!=0 && flags!=0) { - - try { r=readBytes(4, r, f); } - catch(Return e){ return e.r; } - - if(z.msg!=null && z.msg.equals("incorrect data check")){ - this.mode = BAD; - this.marker = 5; // can't try inflateSync - break; - } - - if (this.need != (z.total_out & 0xffffffffL)) { - z.msg = "incorrect length check"; - this.mode = BAD; - break; - } - z.msg = null; - } - else { - if(z.msg!=null && z.msg.equals("incorrect data check")){ - this.mode = BAD; - this.marker = 5; // can't try inflateSync - break; - } - } - - this.mode = DONE; - case DONE: - return Z_STREAM_END; - case BAD: - return Z_DATA_ERROR; - - case FLAGS: - - try { r=readBytes(2, r, f); } - catch(Return e){ return e.r; } - - flags = ((int)this.need)&0xffff; - - if ((flags & 0xff) != Z_DEFLATED) { - z.msg = "unknown compression method"; - this.mode = BAD; - break; - } - if ((flags & 0xe000)!=0) { - z.msg = "unknown header flags set"; - this.mode = BAD; - break; - } - - if ((flags & 0x0200)!=0){ - checksum(2, this.need); - } - - this.mode = TIME; - - case TIME: - try { r=readBytes(4, r, f); } - catch(Return e){ return e.r; } - if(gheader!=null) - gheader.time = this.need; - if ((flags & 0x0200)!=0){ - checksum(4, this.need); - } - this.mode = OS; - case OS: - try { r=readBytes(2, r, f); } - catch(Return e){ return e.r; } - if(gheader!=null){ - gheader.xflags = ((int)this.need)&0xff; - gheader.os = (((int)this.need)>>8)&0xff; - } - if ((flags & 0x0200)!=0){ - checksum(2, this.need); - } - this.mode = EXLEN; - case EXLEN: - if ((flags & 0x0400)!=0) { - try { r=readBytes(2, r, f); } - catch(Return e){ return e.r; } - if(gheader!=null){ - gheader.extra = new byte[((int)this.need)&0xffff]; - } - if ((flags & 0x0200)!=0){ - checksum(2, this.need); - } - } - else if(gheader!=null){ - gheader.extra=null; - } - this.mode = EXTRA; - - case EXTRA: - if ((flags & 0x0400)!=0) { - try { - r=readBytes(r, f); - if(gheader!=null){ - byte[] foo = tmp_string.toByteArray(); - tmp_string=null; - if(foo.length == gheader.extra.length){ - System.arraycopy(foo, 0, gheader.extra, 0, foo.length); - } - else{ - z.msg = "bad extra field length"; - this.mode = BAD; - break; - } - } - } - catch(Return e){ return e.r; } - } - else if(gheader!=null){ - gheader.extra=null; - } - this.mode = NAME; - case NAME: - if ((flags & 0x0800)!=0) { - try { - r=readString(r, f); - if(gheader!=null){ - gheader.name=tmp_string.toByteArray(); - } - tmp_string=null; - } - catch(Return e){ return e.r; } - } - else if(gheader!=null){ - gheader.name=null; - } - this.mode = COMMENT; - case COMMENT: - if ((flags & 0x1000)!=0) { - try { - r=readString(r, f); - if(gheader!=null){ - gheader.comment=tmp_string.toByteArray(); - } - tmp_string=null; - } - catch(Return e){ return e.r; } - } - else if(gheader!=null){ - gheader.comment=null; - } - this.mode = HCRC; - case HCRC: - if ((flags & 0x0200)!=0) { - try { r=readBytes(2, r, f); } - catch(Return e){ return e.r; } - if(gheader!=null){ - gheader.hcrc=(int)(this.need&0xffff); - } - if(this.need != (z.adler.getValue()&0xffffL)){ - this.mode = BAD; - z.msg = "header crc mismatch"; - this.marker = 5; // can't try inflateSync - break; - } - } - z.adler = new CRC32(); - - this.mode = BLOCKS; - break; - default: - return Z_STREAM_ERROR; - } - } - } - - int inflateSetDictionary(byte[] dictionary, int dictLength){ - if(z==null || (this.mode != DICT0 && this.wrap != 0)){ - return Z_STREAM_ERROR; - } - - int index=0; - int length = dictLength; - - if(this.mode==DICT0){ - long adler_need=z.adler.getValue(); - z.adler.reset(); - z.adler.update(dictionary, 0, dictLength); - if(z.adler.getValue()!=adler_need){ - return Z_DATA_ERROR; - } - } - - z.adler.reset(); - - if(length >= (1<0){ - if(z.avail_in==0){ throw new Return(r); }; r=f; - z.avail_in--; z.total_in++; - this.need = this.need | - ((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8)); - need_bytes--; - } - if(n==2){ - this.need&=0xffffL; - } - else if(n==4) { - this.need&=0xffffffffL; - } - need_bytes=-1; - return r; - } - class Return extends Exception{ - int r; - Return(int r){this.r=r; } - } - - private java.io.ByteArrayOutputStream tmp_string = null; - private int readString(int r, int f) throws Return{ - if(tmp_string == null){ - tmp_string=new java.io.ByteArrayOutputStream(); - } - int b=0; - do { - if(z.avail_in==0){ throw new Return(r); }; r=f; - z.avail_in--; z.total_in++; - b = z.next_in[z.next_in_index]; - if(b!=0) tmp_string.write(z.next_in, z.next_in_index, 1); - z.adler.update(z.next_in, z.next_in_index, 1); - z.next_in_index++; - }while(b!=0); - return r; - } - - private int readBytes(int r, int f) throws Return{ - if(tmp_string == null){ - tmp_string=new java.io.ByteArrayOutputStream(); - } - int b=0; - while(this.need>0){ - if(z.avail_in==0){ throw new Return(r); }; r=f; - z.avail_in--; z.total_in++; - b = z.next_in[z.next_in_index]; - tmp_string.write(z.next_in, z.next_in_index, 1); - z.adler.update(z.next_in, z.next_in_index, 1); - z.next_in_index++; - this.need--; - } - return r; - } - - private void checksum(int n, long v){ - for(int i=0; i>=8; - } - z.adler.update(crcbuf, 0, n); - } - - public GZIPHeader getGZIPHeader(){ - return gheader; - } - - boolean inParsingHeader(){ - switch(mode){ - case HEAD: - case DICT4: - case DICT3: - case DICT2: - case DICT1: - case FLAGS: - case TIME: - case OS: - case EXLEN: - case EXTRA: - case NAME: - case COMMENT: - case HCRC: - return true; - default: - return false; - } - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Inflater.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Inflater.java deleted file mode 100644 index 0fb0b098..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Inflater.java +++ /dev/null @@ -1,168 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jzlib; - -final public class Inflater extends ZStream{ - - static final private int MAX_WBITS=15; // 32K LZ77 window - static final private int DEF_WBITS=MAX_WBITS; - - static final private int Z_NO_FLUSH=0; - static final private int Z_PARTIAL_FLUSH=1; - static final private int Z_SYNC_FLUSH=2; - static final private int Z_FULL_FLUSH=3; - static final private int Z_FINISH=4; - - static final private int MAX_MEM_LEVEL=9; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - public Inflater() { - super(); - init(); - } - - public Inflater(JZlib.WrapperType wrapperType) throws GZIPException { - this(DEF_WBITS, wrapperType); - } - - public Inflater(int w, JZlib.WrapperType wrapperType) throws GZIPException { - super(); - int ret = init(w, wrapperType); - if(ret!=Z_OK) - throw new GZIPException(ret+": "+msg); - } - - public Inflater(int w) throws GZIPException { - this(w, false); - } - - public Inflater(boolean nowrap) throws GZIPException { - this(DEF_WBITS, nowrap); - } - - public Inflater(int w, boolean nowrap) throws GZIPException { - super(); - int ret = init(w, nowrap); - if(ret!=Z_OK) - throw new GZIPException(ret+": "+msg); - } - - private boolean finished = false; - - public int init(){ - return init(DEF_WBITS); - } - - public int init(JZlib.WrapperType wrapperType){ - return init(DEF_WBITS, wrapperType); - } - - public int init(int w, JZlib.WrapperType wrapperType) { - boolean nowrap = false; - if(wrapperType == JZlib.W_NONE){ - nowrap = true; - } - else if(wrapperType == JZlib.W_GZIP) { - w += 16; - } - else if(wrapperType == JZlib.W_ANY) { - w |= Inflate.INFLATE_ANY; - } - else if(wrapperType == JZlib.W_ZLIB) { - } - return init(w, nowrap); - } - - public int init(boolean nowrap){ - return init(DEF_WBITS, nowrap); - } - - public int init(int w){ - return init(w, false); - } - - public int init(int w, boolean nowrap){ - finished = false; - istate=new Inflate(this); - return istate.inflateInit(nowrap?-w:w); - } - - public int inflate(int f){ - if(istate==null) return Z_STREAM_ERROR; - int ret = istate.inflate(f); - if(ret == Z_STREAM_END) - finished = true; - return ret; - } - - public int end(){ - finished = true; - if(istate==null) return Z_STREAM_ERROR; - int ret=istate.inflateEnd(); -// istate = null; - return ret; - } - - public int sync(){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSync(); - } - - public int syncPoint(){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSyncPoint(); - } - - public int setDictionary(byte[] dictionary, int dictLength){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSetDictionary(dictionary, dictLength); - } - - public boolean finished(){ - return istate.mode==12 /*DONE*/; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/InflaterInputStream.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/InflaterInputStream.java deleted file mode 100644 index 0420582a..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/InflaterInputStream.java +++ /dev/null @@ -1,247 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.jcraft.jzlib; -import java.io.*; - -public class InflaterInputStream extends FilterInputStream { - protected final Inflater inflater; - protected byte[] buf; - - private boolean closed = false; - - private boolean eof = false; - - private boolean close_in = true; - - protected static final int DEFAULT_BUFSIZE = 512; - - public InflaterInputStream(InputStream in) throws IOException { - this(in, false); - } - - public InflaterInputStream(InputStream in, boolean nowrap) throws IOException { - this(in, new Inflater(nowrap)); - myinflater = true; - } - - public InflaterInputStream(InputStream in, Inflater inflater) throws IOException { - this(in, inflater, DEFAULT_BUFSIZE); - } - - public InflaterInputStream(InputStream in, - Inflater inflater, int size) throws IOException { - this(in, inflater, size, true); - } - - public InflaterInputStream(InputStream in, - Inflater inflater, - int size, boolean close_in) throws IOException { - super(in); - if (in == null || inflater == null) { - throw new NullPointerException(); - } - else if (size <= 0) { - throw new IllegalArgumentException("buffer size must be greater than 0"); - } - this.inflater = inflater; - buf = new byte[size]; - this.close_in = close_in; - } - - protected boolean myinflater = false; - - private byte[] byte1 = new byte[1]; - - public int read() throws IOException { - if (closed) { throw new IOException("Stream closed"); } - return read(byte1, 0, 1) == -1 ? -1 : byte1[0] & 0xff; - } - - public int read(byte[] b, int off, int len) throws IOException { - if (closed) { throw new IOException("Stream closed"); } - if (b == null) { - throw new NullPointerException(); - } - else if (off < 0 || len < 0 || len > b.length - off) { - throw new IndexOutOfBoundsException(); - } - else if (len == 0) { - return 0; - } - else if (eof) { - return -1; - } - - int n = 0; - inflater.setOutput(b, off, len); - while(!eof) { - if(inflater.avail_in==0) - fill(); - int err = inflater.inflate(JZlib.Z_NO_FLUSH); - n += inflater.next_out_index - off; - off = inflater.next_out_index; - switch(err) { - case JZlib.Z_DATA_ERROR: - throw new IOException(inflater.msg); - case JZlib.Z_STREAM_END: - case JZlib.Z_NEED_DICT: - eof = true; - if(err == JZlib.Z_NEED_DICT) - return -1; - break; - default: - } - if(inflater.avail_out==0) - break; - } - return n; - } - - public int available() throws IOException { - if (closed) { throw new IOException("Stream closed"); } - if (eof) { - return 0; - } - else { - return 1; - } - } - - private byte[] b = new byte[512]; - - public long skip(long n) throws IOException { - if (n < 0) { - throw new IllegalArgumentException("negative skip length"); - } - - if (closed) { throw new IOException("Stream closed"); } - - int max = (int)Math.min(n, Integer.MAX_VALUE); - int total = 0; - while (total < max) { - int len = max - total; - if (len > b.length) { - len = b.length; - } - len = read(b, 0, len); - if (len == -1) { - eof = true; - break; - } - total += len; - } - return total; - } - - public void close() throws IOException { - if (!closed) { - if (myinflater) - inflater.end(); - if(close_in) - in.close(); - closed = true; - } - } - - protected void fill() throws IOException { - if (closed) { throw new IOException("Stream closed"); } - int len = in.read(buf, 0, buf.length); - if (len == -1) { - if(inflater.istate.wrap == 0 && - !inflater.finished()){ - buf[0]=0; - len=1; - } - else if(inflater.istate.was != -1){ // in reading trailer - throw new IOException("footer is not found"); - } - else{ - throw new EOFException("Unexpected end of ZLIB input stream"); - } - } - inflater.setInput(buf, 0, len, true); - } - - public boolean markSupported() { - return false; - } - - public synchronized void mark(int readlimit) { - } - - public synchronized void reset() throws IOException { - throw new IOException("mark/reset not supported"); - } - - public long getTotalIn() { - return inflater.getTotalIn(); - } - - public long getTotalOut() { - return inflater.getTotalOut(); - } - - public byte[] getAvailIn() { - if(inflater.avail_in<=0) - return null; - byte[] tmp = new byte[inflater.avail_in]; - System.arraycopy(inflater.next_in, inflater.next_in_index, - tmp, 0, inflater.avail_in); - return tmp; - } - - public void readHeader() throws IOException { - - byte[] empty = "".getBytes(); - inflater.setInput(empty, 0, 0, false); - inflater.setOutput(empty, 0, 0); - - int err = inflater.inflate(JZlib.Z_NO_FLUSH); - if(!inflater.istate.inParsingHeader()){ - return; - } - - byte[] b1 = new byte[1]; - do{ - int i = in.read(b1); - if(i<=0) - throw new IOException("no input"); - inflater.setInput(b1); - err = inflater.inflate(JZlib.Z_NO_FLUSH); - if(err!=0/*Z_OK*/) - throw new IOException(inflater.msg); - } - while(inflater.istate.inParsingHeader()); - } - - public Inflater getInflater(){ - return inflater; - } -} \ No newline at end of file diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/JZlib.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/JZlib.java deleted file mode 100644 index a4bb3410..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/JZlib.java +++ /dev/null @@ -1,92 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jzlib; - -final public class JZlib{ - private static final String version="1.1.0"; - public static String version(){return version;} - - static final public int MAX_WBITS=15; // 32K LZ77 window - static final public int DEF_WBITS=MAX_WBITS; - - public enum WrapperType { - NONE, ZLIB, GZIP, ANY - } - - public static final WrapperType W_NONE = WrapperType.NONE; - public static final WrapperType W_ZLIB = WrapperType.ZLIB; - public static final WrapperType W_GZIP = WrapperType.GZIP; - public static final WrapperType W_ANY = WrapperType.ANY; - - // compression levels - static final public int Z_NO_COMPRESSION=0; - static final public int Z_BEST_SPEED=1; - static final public int Z_BEST_COMPRESSION=9; - static final public int Z_DEFAULT_COMPRESSION=(-1); - - // compression strategy - static final public int Z_FILTERED=1; - static final public int Z_HUFFMAN_ONLY=2; - static final public int Z_DEFAULT_STRATEGY=0; - - static final public int Z_NO_FLUSH=0; - static final public int Z_PARTIAL_FLUSH=1; - static final public int Z_SYNC_FLUSH=2; - static final public int Z_FULL_FLUSH=3; - static final public int Z_FINISH=4; - - static final public int Z_OK=0; - static final public int Z_STREAM_END=1; - static final public int Z_NEED_DICT=2; - static final public int Z_ERRNO=-1; - static final public int Z_STREAM_ERROR=-2; - static final public int Z_DATA_ERROR=-3; - static final public int Z_MEM_ERROR=-4; - static final public int Z_BUF_ERROR=-5; - static final public int Z_VERSION_ERROR=-6; - - // The three kinds of block type - static final public byte Z_BINARY = 0; - static final public byte Z_ASCII = 1; - static final public byte Z_UNKNOWN = 2; - - public static long adler32_combine(long adler1, long adler2, long len2){ - return Adler32.combine(adler1, adler2, len2); - } - - public static long crc32_combine(long crc1, long crc2, long len2){ - return CRC32.combine(crc1, crc2, len2); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/StaticTree.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/StaticTree.java deleted file mode 100644 index e35931c3..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/StaticTree.java +++ /dev/null @@ -1,148 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jzlib; - -final class StaticTree{ - static final private int MAX_BITS=15; - - static final private int BL_CODES=19; - static final private int D_CODES=30; - static final private int LITERALS=256; - static final private int LENGTH_CODES=29; - static final private int L_CODES=(LITERALS+1+LENGTH_CODES); - - // Bit length codes must not exceed MAX_BL_BITS bits - static final int MAX_BL_BITS=7; - - static final short[] static_ltree = { - 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, - 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, - 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, - 252, 8, 2, 8, 130, 8, 66, 8, 194, 8, - 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, - 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, - 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, - 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, - 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, - 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, - 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, - 230, 8, 22, 8, 150, 8, 86, 8, 214, 8, - 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, - 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, - 110, 8, 238, 8, 30, 8, 158, 8, 94, 8, - 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, - 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, - 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, - 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, - 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, - 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, - 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, - 121, 8, 249, 8, 5, 8, 133, 8, 69, 8, - 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, - 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, - 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, - 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, - 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, - 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, - 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, - 211, 9, 467, 9, 51, 9, 307, 9, 179, 9, - 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, - 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, - 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, - 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, - 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, - 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, - 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, - 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, - 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, - 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, - 359, 9, 231, 9, 487, 9, 23, 9, 279, 9, - 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, - 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, - 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, - 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, - 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, - 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, - 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, - 351, 9, 223, 9, 479, 9, 63, 9, 319, 9, - 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, - 511, 9, 0, 7, 64, 7, 32, 7, 96, 7, - 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, - 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, - 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, - 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, - 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, - 163, 8, 99, 8, 227, 8 - }; - - static final short[] static_dtree = { - 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, - 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, - 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, - 30, 5, 1, 5, 17, 5, 9, 5, 25, 5, - 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, - 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 - }; - - static StaticTree static_l_desc = - new StaticTree(static_ltree, Tree.extra_lbits, - LITERALS+1, L_CODES, MAX_BITS); - - static StaticTree static_d_desc = - new StaticTree(static_dtree, Tree.extra_dbits, - 0, D_CODES, MAX_BITS); - - static StaticTree static_bl_desc = - new StaticTree(null, Tree.extra_blbits, - 0, BL_CODES, MAX_BL_BITS); - - short[] static_tree; // static tree or null - int[] extra_bits; // extra bits for each code or null - int extra_base; // base index for extra_bits - int elems; // max number of elements in the tree - int max_length; // max bit length for the codes - - private StaticTree(short[] static_tree, - int[] extra_bits, - int extra_base, - int elems, - int max_length){ - this.static_tree=static_tree; - this.extra_bits=extra_bits; - this.extra_base=extra_base; - this.elems=elems; - this.max_length=max_length; - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Tree.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Tree.java deleted file mode 100644 index 38cb40f2..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/Tree.java +++ /dev/null @@ -1,367 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jzlib; - -final class Tree{ - static final private int MAX_BITS=15; - static final private int BL_CODES=19; - static final private int D_CODES=30; - static final private int LITERALS=256; - static final private int LENGTH_CODES=29; - static final private int L_CODES=(LITERALS+1+LENGTH_CODES); - static final private int HEAP_SIZE=(2*L_CODES+1); - - // Bit length codes must not exceed MAX_BL_BITS bits - static final int MAX_BL_BITS=7; - - // end of block literal code - static final int END_BLOCK=256; - - // repeat previous bit length 3-6 times (2 bits of repeat count) - static final int REP_3_6=16; - - // repeat a zero length 3-10 times (3 bits of repeat count) - static final int REPZ_3_10=17; - - // repeat a zero length 11-138 times (7 bits of repeat count) - static final int REPZ_11_138=18; - - // extra bits for each length code - static final int[] extra_lbits={ - 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0 - }; - - // extra bits for each distance code - static final int[] extra_dbits={ - 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 - }; - - // extra bits for each bit length code - static final int[] extra_blbits={ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7 - }; - - static final byte[] bl_order={ - 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; - - - // The lengths of the bit length codes are sent in order of decreasing - // probability, to avoid transmitting the lengths for unused bit - // length codes. - - static final int Buf_size=8*2; - - // see definition of array dist_code below - static final int DIST_CODE_LEN=512; - - static final byte[] _dist_code = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, - 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, - 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 - }; - - static final byte[] _length_code={ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, - 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, - 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, - 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 - }; - - static final int[] base_length = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, - 64, 80, 96, 112, 128, 160, 192, 224, 0 - }; - - static final int[] base_dist = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 - }; - - // Mapping from a distance to a distance code. dist is the distance - 1 and - // must not have side effects. _dist_code[256] and _dist_code[257] are never - // used. - static int d_code(int dist){ - return ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>>7)]); - } - - short[] dyn_tree; // the dynamic tree - int max_code; // largest code with non zero frequency - StaticTree stat_desc; // the corresponding static tree - - // Compute the optimal bit lengths for a tree and update the total bit length - // for the current block. - // IN assertion: the fields freq and dad are set, heap[heap_max] and - // above are the tree nodes sorted by increasing frequency. - // OUT assertions: the field len is set to the optimal bit length, the - // array bl_count contains the frequencies for each bit length. - // The length opt_len is updated; static_len is also updated if stree is - // not null. - void gen_bitlen(Deflate s){ - short[] tree = dyn_tree; - short[] stree = stat_desc.static_tree; - int[] extra = stat_desc.extra_bits; - int base = stat_desc.extra_base; - int max_length = stat_desc.max_length; - int h; // heap index - int n, m; // iterate over the tree elements - int bits; // bit length - int xbits; // extra bits - short f; // frequency - int overflow = 0; // number of elements with bit length too large - - for (bits = 0; bits <= MAX_BITS; bits++) s.bl_count[bits] = 0; - - // In a first pass, compute the optimal bit lengths (which may - // overflow in the case of the bit length tree). - tree[s.heap[s.heap_max]*2+1] = 0; // root of the heap - - for(h=s.heap_max+1; h max_length){ bits = max_length; overflow++; } - tree[n*2+1] = (short)bits; - // We overwrite tree[n*2+1] which is no longer needed - - if (n > max_code) continue; // not a leaf node - - s.bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n*2]; - s.opt_len += f * (bits + xbits); - if (stree!=null) s.static_len += f * (stree[n*2+1] + xbits); - } - if (overflow == 0) return; - - // This happens for example on obj2 and pic of the Calgary corpus - // Find the first bit length which could increase: - do { - bits = max_length-1; - while(s.bl_count[bits]==0) bits--; - s.bl_count[bits]--; // move one leaf down the tree - s.bl_count[bits+1]+=2; // move one overflow item as its brother - s.bl_count[max_length]--; - // The brother of the overflow item also moves one step up, - // but this does not affect bl_count[max_length] - overflow -= 2; - } - while (overflow > 0); - - for (bits = max_length; bits != 0; bits--) { - n = s.bl_count[bits]; - while (n != 0) { - m = s.heap[--h]; - if (m > max_code) continue; - if (tree[m*2+1] != bits) { - s.opt_len += ((long)bits - (long)tree[m*2+1])*(long)tree[m*2]; - tree[m*2+1] = (short)bits; - } - n--; - } - } - } - - // Construct one Huffman tree and assigns the code bit strings and lengths. - // Update the total bit length for the current block. - // IN assertion: the field freq is set for all tree elements. - // OUT assertions: the fields len and code are set to the optimal bit length - // and corresponding code. The length opt_len is updated; static_len is - // also updated if stree is not null. The field max_code is set. - void build_tree(Deflate s){ - short[] tree=dyn_tree; - short[] stree=stat_desc.static_tree; - int elems=stat_desc.elems; - int n, m; // iterate over heap elements - int max_code=-1; // largest code with non zero frequency - int node; // new node being created - - // Construct the initial heap, with least frequent element in - // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - // heap[0] is not used. - s.heap_len = 0; - s.heap_max = HEAP_SIZE; - - for(n=0; n=1; n--) - s.pqdownheap(tree, n); - - // Construct the Huffman tree by repeatedly combining the least two - // frequent nodes. - - node=elems; // next internal node of the tree - do{ - // n = node of least frequency - n=s.heap[1]; - s.heap[1]=s.heap[s.heap_len--]; - s.pqdownheap(tree, 1); - m=s.heap[1]; // m = node of next least frequency - - s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency - s.heap[--s.heap_max] = m; - - // Create a new node father of n and m - tree[node*2] = (short)(tree[n*2] + tree[m*2]); - s.depth[node] = (byte)(Math.max(s.depth[n],s.depth[m])+1); - tree[n*2+1] = tree[m*2+1] = (short)node; - - // and insert the new node in the heap - s.heap[1] = node++; - s.pqdownheap(tree, 1); - } - while(s.heap_len>=2); - - s.heap[--s.heap_max] = s.heap[1]; - - // At this point, the fields freq and dad are set. We can now - // generate the bit lengths. - - gen_bitlen(s); - - // The field len is now set, we can generate the bit codes - gen_codes(tree, max_code, s.bl_count, s.next_code); - } - - // Generate the codes for a given tree and bit counts (which need not be - // optimal). - // IN assertion: the array bl_count contains the bit length statistics for - // the given tree and the field len is set for all tree elements. - // OUT assertion: the field code is set for all tree elements of non - // zero code length. - private final static void gen_codes( - short[] tree, // the tree to decorate - int max_code, // largest code with non zero frequency - short[] bl_count, // number of codes at each bit length - short[] next_code){ - short code = 0; // running code value - int bits; // bit index - int n; // code index - - // The distribution counts are first used to generate the code values - // without bit reversal. - next_code[0]=0; - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (short)((code + bl_count[bits-1]) << 1); - } - - // Check that the bit counts in bl_count are consistent. The last code - // must be all ones. - //Assert (code + bl_count[MAX_BITS]-1 == (1<>>=1; - res<<=1; - } - while(--len>0); - return res>>>1; - } -} - diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/ZInputStream.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/ZInputStream.java deleted file mode 100644 index cbd38e15..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/ZInputStream.java +++ /dev/null @@ -1,126 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.jcraft.jzlib; -import java.io.*; - -/** - * ZInputStream - * - * @deprecated use DeflaterOutputStream or InflaterInputStream - */ -@Deprecated -public class ZInputStream extends FilterInputStream { - - protected int flush=JZlib.Z_NO_FLUSH; - protected boolean compress; - protected InputStream in=null; - - protected Deflater deflater; - protected InflaterInputStream iis; - - public ZInputStream(InputStream in) throws IOException { - this(in, false); - } - public ZInputStream(InputStream in, boolean nowrap) throws IOException { - super(in); - iis = new InflaterInputStream(in, nowrap); - compress=false; - } - - public ZInputStream(InputStream in, int level) throws IOException { - super(in); - this.in=in; - deflater = new Deflater(); - deflater.init(level); - compress=true; - } - - private byte[] buf1 = new byte[1]; - public int read() throws IOException { - if(read(buf1, 0, 1)==-1) return -1; - return(buf1[0]&0xFF); - } - - private byte[] buf = new byte[512]; - - public int read(byte[] b, int off, int len) throws IOException { - if(compress){ - deflater.setOutput(b, off, len); - while(true){ - int datalen = in.read(buf, 0, buf.length); - if(datalen == -1) return -1; - deflater.setInput(buf, 0, datalen, true); - int err = deflater.deflate(flush); - if(deflater.next_out_index>0) - return deflater.next_out_index; - if(err == JZlib.Z_STREAM_END) - return 0; - if(err == JZlib.Z_STREAM_ERROR || - err == JZlib.Z_DATA_ERROR){ - throw new ZStreamException("deflating: "+deflater.msg); - } - } - } - else{ - return iis.read(b, off, len); - } - } - - public long skip(long n) throws IOException { - int len=512; - if(n0){ - inflater.setOutput(buf, 0, buf.length); - err = inflater.inflate(flush); - if(inflater.next_out_index>0) - out.write(buf, 0, inflater.next_out_index); - if(err != JZlib.Z_OK) - break; - } - if(err != JZlib.Z_OK) - throw new ZStreamException("inflating: "+inflater.msg); - return; - } - } - - public int getFlushMode() { - return flush; - } - - public void setFlushMode(int flush) { - this.flush=flush; - } - - public void finish() throws IOException { - int err; - if(compress){ - int tmp = flush; - int flush = JZlib.Z_FINISH; - try{ - write("".getBytes(), 0, 0); - } - finally { flush = tmp; } - } - else{ - dos.finish(); - } - flush(); - } - public synchronized void end() { - if(end) return; - if(compress){ - try { dos.finish(); } catch(Exception e){} - } - else{ - inflater.end(); - } - end=true; - } - public void close() throws IOException { - try{ - try{finish();} - catch (IOException ignored) {} - } - finally{ - end(); - out.close(); - out=null; - } - } - - public long getTotalIn() { - if(compress) return dos.getTotalIn(); - else return inflater.total_in; - } - - public long getTotalOut() { - if(compress) return dos.getTotalOut(); - else return inflater.total_out; - } - - public void flush() throws IOException { - out.flush(); - } - -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/ZStream.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/ZStream.java deleted file mode 100644 index 0afa4fd0..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/ZStream.java +++ /dev/null @@ -1,377 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jzlib; - -/** - * ZStream - * - * @deprecated Not for public use in the future. - */ -@Deprecated -public class ZStream{ - - static final private int MAX_WBITS=15; // 32K LZ77 window - static final private int DEF_WBITS=MAX_WBITS; - - static final private int Z_NO_FLUSH=0; - static final private int Z_PARTIAL_FLUSH=1; - static final private int Z_SYNC_FLUSH=2; - static final private int Z_FULL_FLUSH=3; - static final private int Z_FINISH=4; - - static final private int MAX_MEM_LEVEL=9; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - public byte[] next_in; // next input byte - public int next_in_index; - public int avail_in; // number of bytes available at next_in - public long total_in; // total nb of input bytes read so far - - public byte[] next_out; // next output byte should be put there - public int next_out_index; - public int avail_out; // remaining free space at next_out - public long total_out; // total nb of bytes output so far - - public String msg; - - Deflate dstate; - Inflate istate; - - int data_type; // best guess about the data type: ascii or binary - - Checksum adler; - - public ZStream(){ - this(new Adler32()); - } - - public ZStream(Checksum adler){ - this.adler=adler; - } - - public int inflateInit(){ - return inflateInit(DEF_WBITS); - } - public int inflateInit(boolean nowrap){ - return inflateInit(DEF_WBITS, nowrap); - } - public int inflateInit(int w){ - return inflateInit(w, false); - } - public int inflateInit(JZlib.WrapperType wrapperType) { - return inflateInit(DEF_WBITS, wrapperType); - } - public int inflateInit(int w, JZlib.WrapperType wrapperType) { - boolean nowrap = false; - if(wrapperType == JZlib.W_NONE){ - nowrap = true; - } - else if(wrapperType == JZlib.W_GZIP) { - w += 16; - } - else if(wrapperType == JZlib.W_ANY) { - w |= Inflate.INFLATE_ANY; - } - else if(wrapperType == JZlib.W_ZLIB) { - } - return inflateInit(w, nowrap); - } - public int inflateInit(int w, boolean nowrap){ - istate=new Inflate(this); - return istate.inflateInit(nowrap?-w:w); - } - - public int inflate(int f){ - if(istate==null) return Z_STREAM_ERROR; - return istate.inflate(f); - } - public int inflateEnd(){ - if(istate==null) return Z_STREAM_ERROR; - int ret=istate.inflateEnd(); -// istate = null; - return ret; - } - public int inflateSync(){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSync(); - } - public int inflateSyncPoint(){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSyncPoint(); - } - public int inflateSetDictionary(byte[] dictionary, int dictLength){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSetDictionary(dictionary, dictLength); - } - public boolean inflateFinished(){ - return istate.mode==12 /*DONE*/; - } - - public int deflateInit(int level){ - return deflateInit(level, MAX_WBITS); - } - public int deflateInit(int level, boolean nowrap){ - return deflateInit(level, MAX_WBITS, nowrap); - } - public int deflateInit(int level, int bits){ - return deflateInit(level, bits, false); - } - public int deflateInit(int level, int bits, int memlevel, JZlib.WrapperType wrapperType){ - if(bits < 9 || bits > 15){ - return Z_STREAM_ERROR; - } - if(wrapperType == JZlib.W_NONE) { - bits *= -1; - } - else if(wrapperType == JZlib.W_GZIP) { - bits += 16; - } - else if(wrapperType == JZlib.W_ANY) { - return Z_STREAM_ERROR; - } - else if(wrapperType == JZlib.W_ZLIB) { - } - return this.deflateInit(level, bits, memlevel); - } - public int deflateInit(int level, int bits, int memlevel){ - dstate=new Deflate(this); - return dstate.deflateInit(level, bits, memlevel); - } - public int deflateInit(int level, int bits, boolean nowrap){ - dstate=new Deflate(this); - return dstate.deflateInit(level, nowrap?-bits:bits); - } - public int deflate(int flush){ - if(dstate==null){ - return Z_STREAM_ERROR; - } - return dstate.deflate(flush); - } - public int deflateEnd(){ - if(dstate==null) return Z_STREAM_ERROR; - int ret=dstate.deflateEnd(); - dstate=null; - return ret; - } - public int deflateParams(int level, int strategy){ - if(dstate==null) return Z_STREAM_ERROR; - return dstate.deflateParams(level, strategy); - } - public int deflateSetDictionary (byte[] dictionary, int dictLength){ - if(dstate == null) - return Z_STREAM_ERROR; - return dstate.deflateSetDictionary(dictionary, dictLength); - } - - // Flush as much pending output as possible. All deflate() output goes - // through this function so some applications may wish to modify it - // to avoid allocating a large strm->next_out buffer and copying into it. - // (See also read_buf()). - void flush_pending(){ - int len=dstate.pending; - - if(len>avail_out) len=avail_out; - if(len==0) return; - - if(dstate.pending_buf.length<=dstate.pending_out || - next_out.length<=next_out_index || - dstate.pending_buf.length<(dstate.pending_out+len) || - next_out.length<(next_out_index+len)){ - //System.out.println(dstate.pending_buf.length+", "+dstate.pending_out+ - // ", "+next_out.length+", "+next_out_index+", "+len); - //System.out.println("avail_out="+avail_out); - } - - System.arraycopy(dstate.pending_buf, dstate.pending_out, - next_out, next_out_index, len); - - next_out_index+=len; - dstate.pending_out+=len; - total_out+=len; - avail_out-=len; - dstate.pending-=len; - if(dstate.pending==0){ - dstate.pending_out=0; - } - } - - // Read a new buffer from the current input stream, update the adler32 - // and total number of bytes read. All deflate() input goes through - // this function so some applications may wish to modify it to avoid - // allocating a large strm->next_in buffer and copying from it. - // (See also flush_pending()). - int read_buf(byte[] buf, int start, int size) { - int len=avail_in; - - if(len>size) len=size; - if(len==0) return 0; - - avail_in-=len; - - if(dstate.wrap!=0) { - adler.update(next_in, next_in_index, len); - } - System.arraycopy(next_in, next_in_index, buf, start, len); - next_in_index += len; - total_in += len; - return len; - } - - public long getAdler(){ - return adler.getValue(); - } - - public void free(){ - next_in=null; - next_out=null; - msg=null; - } - - public void setOutput(byte[] buf){ - setOutput(buf, 0, buf.length); - } - - public void setOutput(byte[] buf, int off, int len){ - next_out = buf; - next_out_index = off; - avail_out = len; - } - - public void setInput(byte[] buf){ - setInput(buf, 0, buf.length, false); - } - - public void setInput(byte[] buf, boolean append){ - setInput(buf, 0, buf.length, append); - } - - public void setInput(byte[] buf, int off, int len, boolean append){ - if(len<=0 && append && next_in!=null) return; - - if(avail_in>0 && append){ - byte[] tmp = new byte[avail_in+len]; - System.arraycopy(next_in, next_in_index, tmp, 0, avail_in); - System.arraycopy(buf, off, tmp, avail_in, len); - next_in=tmp; - next_in_index=0; - avail_in+=len; - } - else{ - next_in=buf; - next_in_index=off; - avail_in=len; - } - } - - public byte[] getNextIn(){ - return next_in; - } - - public void setNextIn(byte[] next_in){ - this.next_in = next_in; - } - - public int getNextInIndex(){ - return next_in_index; - } - - public void setNextInIndex(int next_in_index){ - this.next_in_index = next_in_index; - } - - public int getAvailIn(){ - return avail_in; - } - - public void setAvailIn(int avail_in){ - this.avail_in = avail_in; - } - - public byte[] getNextOut(){ - return next_out; - } - - public void setNextOut(byte[] next_out){ - this.next_out = next_out; - } - - public int getNextOutIndex(){ - return next_out_index; - } - - public void setNextOutIndex(int next_out_index){ - this.next_out_index = next_out_index; - } - - public int getAvailOut(){ - return avail_out; - - } - - public void setAvailOut(int avail_out){ - this.avail_out = avail_out; - } - - public long getTotalOut(){ - return total_out; - } - - public long getTotalIn(){ - return total_in; - } - - public String getMessage(){ - return msg; - } - - /** - * Those methods are expected to be override by Inflater and Deflater. - * In the future, they will become abstract methods. - */ - public int end(){ return Z_OK; } - public boolean finished(){ return false; } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/ZStreamException.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/ZStreamException.java deleted file mode 100644 index 308bb8a1..00000000 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jzlib/ZStreamException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package com.jcraft.jzlib; - -public class ZStreamException extends java.io.IOException { - public ZStreamException() { - super(); - } - public ZStreamException(String s) { - super(s); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/keepass2android/javafilestorage/SftpStorage.java b/src/java/JavaFileStorage/app/src/main/java/keepass2android/javafilestorage/SftpStorage.java index 55b77959..4454d7d1 100644 --- a/src/java/JavaFileStorage/app/src/main/java/keepass2android/javafilestorage/SftpStorage.java +++ b/src/java/JavaFileStorage/app/src/main/java/keepass2android/javafilestorage/SftpStorage.java @@ -505,7 +505,7 @@ public class SftpStorage extends JavaFileStorageBase { } @SuppressWarnings("unused") // Exposed by JavaFileStorageBindings - public String createKeyPair() throws IOException, JSchException { + public String createKeyPair() throws Exception { return _keyUtils.createKeyPair(jsch); } diff --git a/src/java/JavaFileStorage/build.gradle b/src/java/JavaFileStorage/build.gradle index 2318eb57..6195c915 100644 --- a/src/java/JavaFileStorage/build.gradle +++ b/src/java/JavaFileStorage/build.gradle @@ -6,7 +6,7 @@ buildscript { jcenter() } dependencies { - classpath "com.android.tools.build:gradle:8.4.0" + classpath "com.android.tools.build:gradle:8.9.0" } } diff --git a/src/java/JavaFileStorage/gradle/wrapper/gradle-wrapper.properties b/src/java/JavaFileStorage/gradle/wrapper/gradle-wrapper.properties index d8bbf7cb..e05ea54f 100644 --- a/src/java/JavaFileStorage/gradle/wrapper/gradle-wrapper.properties +++ b/src/java/JavaFileStorage/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip diff --git a/src/java/JavaFileStorageTest-AS/build.gradle b/src/java/JavaFileStorageTest-AS/build.gradle index dd9299af..881630c4 100644 --- a/src/java/JavaFileStorageTest-AS/build.gradle +++ b/src/java/JavaFileStorageTest-AS/build.gradle @@ -1,13 +1,16 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + ext { + agp_version = '8.9.0' + } repositories { google() mavenCentral() jcenter() } dependencies { - classpath "com.android.tools.build:gradle:8.4.0" + classpath "com.android.tools.build:gradle:$agp_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/src/java/JavaFileStorageTest-AS/gradle.properties b/src/java/JavaFileStorageTest-AS/gradle.properties index 76e5562c..2c7f1caa 100644 --- a/src/java/JavaFileStorageTest-AS/gradle.properties +++ b/src/java/JavaFileStorageTest-AS/gradle.properties @@ -20,3 +20,6 @@ android.enableJetifier=true android.useAndroidX=true org.gradle.jvmargs=-Xmx1536m +# jsch comes as a multi-release JAR containing Java24 classes. +# This doesn't work with jetifier. As jsch doesn't use Android support libraries, we can exclude it. +android.jetifier.ignorelist = jsch-2.27.2.jar \ No newline at end of file diff --git a/src/java/JavaFileStorageTest-AS/gradle/wrapper/gradle-wrapper.properties b/src/java/JavaFileStorageTest-AS/gradle/wrapper/gradle-wrapper.properties index ff3d166e..7f52bd8c 100644 --- a/src/java/JavaFileStorageTest-AS/gradle/wrapper/gradle-wrapper.properties +++ b/src/java/JavaFileStorageTest-AS/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip