aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorKenny Root <kenny@the-b.org>2015-07-23 22:38:46 -0700
committerKenny Root <kenny@the-b.org>2015-07-24 15:35:39 -0700
commit147dae0102979a0217ac8a9eea82a4969a1ecf63 (patch)
tree40718fac7fc6a3afce07c910ffc243dd5d69d403 /app
parent739337624a5e69221a998cf10b1fd34fcc5ecd2d (diff)
downloadconnectbot-147dae0102979a0217ac8a9eea82a4969a1ecf63.tar.gz
connectbot-147dae0102979a0217ac8a9eea82a4969a1ecf63.tar.bz2
connectbot-147dae0102979a0217ac8a9eea82a4969a1ecf63.zip
Move to library-based build
Diffstat (limited to 'app')
-rw-r--r--app/app.iml5
-rw-r--r--app/build.gradle8
-rw-r--r--app/src/main/java/com/jcraft/jzlib/Adler32.java94
-rw-r--r--app/src/main/java/com/jcraft/jzlib/Deflate.java1623
-rw-r--r--app/src/main/java/com/jcraft/jzlib/InfBlocks.java614
-rw-r--r--app/src/main/java/com/jcraft/jzlib/InfCodes.java605
-rw-r--r--app/src/main/java/com/jcraft/jzlib/InfTree.java520
-rw-r--r--app/src/main/java/com/jcraft/jzlib/Inflate.java374
-rw-r--r--app/src/main/java/com/jcraft/jzlib/JZlib.java67
-rw-r--r--app/src/main/java/com/jcraft/jzlib/StaticTree.java149
-rw-r--r--app/src/main/java/com/jcraft/jzlib/Tree.java365
-rw-r--r--app/src/main/java/com/jcraft/jzlib/ZInputStream.java149
-rw-r--r--app/src/main/java/com/jcraft/jzlib/ZOutputStream.java156
-rw-r--r--app/src/main/java/com/jcraft/jzlib/ZStream.java211
-rw-r--r--app/src/main/java/com/jcraft/jzlib/ZStreamException.java44
-rw-r--r--app/src/main/java/com/trilead/ssh2/AuthAgentCallback.java64
-rw-r--r--app/src/main/java/com/trilead/ssh2/ChannelCondition.java61
-rw-r--r--app/src/main/java/com/trilead/ssh2/Connection.java1628
-rw-r--r--app/src/main/java/com/trilead/ssh2/ConnectionInfo.java53
-rw-r--r--app/src/main/java/com/trilead/ssh2/ConnectionMonitor.java34
-rw-r--r--app/src/main/java/com/trilead/ssh2/DHGexParameters.java121
-rw-r--r--app/src/main/java/com/trilead/ssh2/DebugLogger.java23
-rw-r--r--app/src/main/java/com/trilead/ssh2/DynamicPortForwarder.java67
-rw-r--r--app/src/main/java/com/trilead/ssh2/HTTPProxyData.java83
-rw-r--r--app/src/main/java/com/trilead/ssh2/HTTPProxyException.java29
-rw-r--r--app/src/main/java/com/trilead/ssh2/InteractiveCallback.java55
-rw-r--r--app/src/main/java/com/trilead/ssh2/KnownHosts.java844
-rw-r--r--app/src/main/java/com/trilead/ssh2/LocalPortForwarder.java63
-rw-r--r--app/src/main/java/com/trilead/ssh2/LocalStreamForwarder.java78
-rw-r--r--app/src/main/java/com/trilead/ssh2/ProxyData.java15
-rw-r--r--app/src/main/java/com/trilead/ssh2/SCPClient.java729
-rw-r--r--app/src/main/java/com/trilead/ssh2/SFTPException.java91
-rw-r--r--app/src/main/java/com/trilead/ssh2/SFTPv3Client.java1388
-rw-r--r--app/src/main/java/com/trilead/ssh2/SFTPv3DirectoryEntry.java38
-rw-r--r--app/src/main/java/com/trilead/ssh2/SFTPv3FileAttributes.java145
-rw-r--r--app/src/main/java/com/trilead/ssh2/SFTPv3FileHandle.java45
-rw-r--r--app/src/main/java/com/trilead/ssh2/ServerHostKeyVerifier.java31
-rw-r--r--app/src/main/java/com/trilead/ssh2/Session.java530
-rw-r--r--app/src/main/java/com/trilead/ssh2/StreamGobbler.java229
-rw-r--r--app/src/main/java/com/trilead/ssh2/auth/AuthenticationManager.java466
-rw-r--r--app/src/main/java/com/trilead/ssh2/channel/AuthAgentForwardThread.java579
-rw-r--r--app/src/main/java/com/trilead/ssh2/channel/Channel.java207
-rw-r--r--app/src/main/java/com/trilead/ssh2/channel/ChannelInputStream.java86
-rw-r--r--app/src/main/java/com/trilead/ssh2/channel/ChannelManager.java1756
-rw-r--r--app/src/main/java/com/trilead/ssh2/channel/ChannelOutputStream.java71
-rw-r--r--app/src/main/java/com/trilead/ssh2/channel/DynamicAcceptThread.java284
-rw-r--r--app/src/main/java/com/trilead/ssh2/channel/IChannelWorkerThread.java13
-rw-r--r--app/src/main/java/com/trilead/ssh2/channel/LocalAcceptThread.java135
-rw-r--r--app/src/main/java/com/trilead/ssh2/channel/RemoteAcceptThread.java103
-rw-r--r--app/src/main/java/com/trilead/ssh2/channel/RemoteForwardingData.java17
-rw-r--r--app/src/main/java/com/trilead/ssh2/channel/RemoteX11AcceptThread.java240
-rw-r--r--app/src/main/java/com/trilead/ssh2/channel/StreamForwarder.java113
-rw-r--r--app/src/main/java/com/trilead/ssh2/channel/X11ServerData.java16
-rw-r--r--app/src/main/java/com/trilead/ssh2/compression/CompressionFactory.java96
-rw-r--r--app/src/main/java/com/trilead/ssh2/compression/ICompressor.java32
-rw-r--r--app/src/main/java/com/trilead/ssh2/compression/Zlib.java130
-rw-r--r--app/src/main/java/com/trilead/ssh2/compression/ZlibOpenSSH.java35
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/Base64.java148
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/CryptoWishList.java26
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/KeyMaterial.java91
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/PEMDecoder.java494
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/PEMStructure.java17
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/SimpleDERReader.java229
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/cipher/AES.java698
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/cipher/BlockCipher.java16
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/cipher/BlockCipherFactory.java115
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/cipher/BlowFish.java403
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/cipher/CBCMode.java78
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/cipher/CTRMode.java62
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/cipher/CipherInputStream.java144
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/cipher/CipherOutputStream.java142
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/cipher/DES.java373
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/cipher/DESede.java105
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/cipher/NullCipher.java35
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/dh/DhExchange.java132
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/dh/DhGroupExchange.java113
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/dh/EcDhExchange.java106
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/dh/GenericDhExchange.java93
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/digest/HashForSSH2Types.java91
-rw-r--r--app/src/main/java/com/trilead/ssh2/crypto/digest/MAC.java157
-rw-r--r--app/src/main/java/com/trilead/ssh2/log/Logger.java54
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketChannelAuthAgentReq.java33
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketChannelOpenConfirmation.java66
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketChannelOpenFailure.java66
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketChannelTrileadPing.java35
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketChannelWindowAdjust.java57
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketDisconnect.java57
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketGlobalCancelForwardRequest.java42
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketGlobalForwardRequest.java41
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketGlobalTrileadPing.java32
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketIgnore.java59
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketKexDHInit.java31
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketKexDHReply.java53
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexGroup.java50
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexInit.java33
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexReply.java56
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexRequest.java39
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexRequestOld.java34
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketKexInit.java165
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketNewKeys.java46
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketOpenDirectTCPIPChannel.java56
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketOpenSessionChannel.java62
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketServiceAccept.java61
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketServiceRequest.java52
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketSessionExecCommand.java39
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketSessionPtyRequest.java57
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketSessionPtyResize.java40
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketSessionStartShell.java36
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketSessionSubsystemRequest.java40
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketSessionX11Request.java53
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketUserauthBanner.java60
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketUserauthFailure.java53
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketUserauthInfoRequest.java84
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketUserauthInfoResponse.java35
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketUserauthRequestInteractive.java42
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketUserauthRequestNone.java61
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketUserauthRequestPassword.java67
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/PacketUserauthRequestPublicKey.java65
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/Packets.java149
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/TypesReader.java177
-rw-r--r--app/src/main/java/com/trilead/ssh2/packets/TypesWriter.java169
-rw-r--r--app/src/main/java/com/trilead/ssh2/sftp/AttrTextHints.java38
-rw-r--r--app/src/main/java/com/trilead/ssh2/sftp/AttribBits.java129
-rw-r--r--app/src/main/java/com/trilead/ssh2/sftp/AttribFlags.java112
-rw-r--r--app/src/main/java/com/trilead/ssh2/sftp/AttribPermissions.java32
-rw-r--r--app/src/main/java/com/trilead/ssh2/sftp/AttribTypes.java28
-rw-r--r--app/src/main/java/com/trilead/ssh2/sftp/ErrorCodes.java104
-rw-r--r--app/src/main/java/com/trilead/ssh2/sftp/OpenFlags.java223
-rw-r--r--app/src/main/java/com/trilead/ssh2/sftp/Packet.java43
-rw-r--r--app/src/main/java/com/trilead/ssh2/signature/DSASHA1Verify.java255
-rw-r--r--app/src/main/java/com/trilead/ssh2/signature/ECDSASHA2Verify.java487
-rw-r--r--app/src/main/java/com/trilead/ssh2/signature/RSASHA1Verify.java180
-rw-r--r--app/src/main/java/com/trilead/ssh2/transport/ClientServerHello.java125
-rw-r--r--app/src/main/java/com/trilead/ssh2/transport/KexManager.java690
-rw-r--r--app/src/main/java/com/trilead/ssh2/transport/KexParameters.java24
-rw-r--r--app/src/main/java/com/trilead/ssh2/transport/KexState.java33
-rw-r--r--app/src/main/java/com/trilead/ssh2/transport/MessageHandler.java14
-rw-r--r--app/src/main/java/com/trilead/ssh2/transport/NegotiateException.java12
-rw-r--r--app/src/main/java/com/trilead/ssh2/transport/NegotiatedParameters.java22
-rw-r--r--app/src/main/java/com/trilead/ssh2/transport/TransportConnection.java343
-rw-r--r--app/src/main/java/com/trilead/ssh2/transport/TransportManager.java750
-rw-r--r--app/src/main/java/com/trilead/ssh2/util/TimeoutService.java149
-rw-r--r--app/src/main/java/com/trilead/ssh2/util/Tokenizer.java51
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/Authentication.java34
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/AuthenticationNone.java17
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/Proxy.java404
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/ProxyMessage.java109
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/ProxyServer.java591
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/Socks4Message.java171
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/Socks4Proxy.java107
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/Socks5DatagramSocket.java460
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/Socks5Message.java292
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/Socks5Proxy.java231
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/SocksException.java80
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/SocksServerSocket.java164
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/SocksSocket.java291
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/UDPEncapsulation.java29
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/UDPRelayServer.java212
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/server/ServerAuthenticator.java120
-rw-r--r--app/src/main/java/net/sourceforge/jsocks/server/ServerAuthenticatorNone.java169
160 files changed, 12 insertions, 29495 deletions
diff --git a/app/app.iml b/app/app.iml
index bde98ae..de9c0ba 100644
--- a/app/app.iml
+++ b/app/app.iml
@@ -87,7 +87,10 @@
</content>
<orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" exported="" name="jzlib-1.1.3" level="project" />
+ <orderEntry type="library" exported="" name="sshlib-2.2.0" level="project" />
+ <orderEntry type="library" exported="" name="jsocks-1.0.0" level="project" />
<orderEntry type="library" exported="" name="support-v4-22.2.1" level="project" />
<orderEntry type="library" exported="" name="support-annotations-22.2.1" level="project" />
</component>
-</module> \ No newline at end of file
+</module>
diff --git a/app/build.gradle b/app/build.gradle
index 3df0ece..1a643e6 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -108,7 +108,15 @@ tasks.create(name: "jacocoTestDebugReport", type: JacocoReport, dependsOn: "test
coveralls.jacocoReportPath = "${project.buildDir}/reports/jacoco/jacocoTestDebugReport/jacocoTestDebugReport.xml"
+repositories {
+ maven {
+ url 'https://dl.bintray.com/connectbot/maven'
+ }
+}
+
dependencies {
+ compile 'org.connectbot:sshlib:2.2.0'
+
testCompile 'junit:junit:4.12'
testCompile('org.robolectric:robolectric:3.0') {
exclude group: 'commons-logging', module: 'commons-logging'
diff --git a/app/src/main/java/com/jcraft/jzlib/Adler32.java b/app/src/main/java/com/jcraft/jzlib/Adler32.java
deleted file mode 100644
index d8b6ef8..0000000
--- a/app/src/main/java/com/jcraft/jzlib/Adler32.java
+++ /dev/null
@@ -1,94 +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 Adler32{
-
- // 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;
-
- long adler32(long adler, byte[] buf, int index, int len){
- if(buf == null){ return 1L; }
-
- long s1=adler&0xffff;
- long s2=(adler>>16)&0xffff;
- int k;
-
- while(len > 0) {
- k=len<NMAX?len:NMAX;
- len-=k;
- while(k>=16){
- s1+=buf[index++]&0xff; s2+=s1;
- s1+=buf[index++]&0xff; s2+=s1;
- s1+=buf[index++]&0xff; s2+=s1;
- s1+=buf[index++]&0xff; s2+=s1;
- s1+=buf[index++]&0xff; s2+=s1;
- s1+=buf[index++]&0xff; s2+=s1;
- s1+=buf[index++]&0xff; s2+=s1;
- s1+=buf[index++]&0xff; s2+=s1;
- s1+=buf[index++]&0xff; s2+=s1;
- s1+=buf[index++]&0xff; s2+=s1;
- s1+=buf[index++]&0xff; s2+=s1;
- s1+=buf[index++]&0xff; s2+=s1;
- s1+=buf[index++]&0xff; s2+=s1;
- s1+=buf[index++]&0xff; s2+=s1;
- s1+=buf[index++]&0xff; s2+=s1;
- s1+=buf[index++]&0xff; s2+=s1;
- k-=16;
- }
- if(k!=0){
- do{
- s1+=buf[index++]&0xff; s2+=s1;
- }
- while(--k!=0);
- }
- s1%=BASE;
- s2%=BASE;
- }
- return (s2<<16)|s1;
- }
-
- /*
- private java.util.zip.Adler32 adler=new java.util.zip.Adler32();
- long adler32(long value, byte[] buf, int index, int len){
- if(value==1) {adler.reset();}
- if(buf==null) {adler.reset();}
- else{adler.update(buf, index, len);}
- return adler.getValue();
- }
- */
-}
diff --git a/app/src/main/java/com/jcraft/jzlib/Deflate.java b/app/src/main/java/com/jcraft/jzlib/Deflate.java
deleted file mode 100644
index 9978802..0000000
--- a/app/src/main/java/com/jcraft/jzlib/Deflate.java
+++ /dev/null
@@ -1,1623 +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
-final class Deflate{
-
- 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 noheader; // suppress zlib header and adler32
- 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];
-
- // 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;
-
- Deflate(){
- 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<hash_size-1; i++){
- head[i]=0;
- }
-
- // Set the default configuration parameters:
- max_lazy_match = Deflate.config_table[level].max_lazy;
- good_match = Deflate.config_table[level].good_length;
- nice_match = Deflate.config_table[level].nice_length;
- max_chain_length = Deflate.config_table[level].max_chain;
-
- strstart = 0;
- block_start = 0;
- lookahead = 0;
- match_length = prev_length = MIN_MATCH-1;
- match_available = 0;
- ins_h = 0;
- }
-
- // Initialize the tree data structures for a new zlib stream.
- void tr_init(){
-
- l_desc.dyn_tree = dyn_ltree;
- l_desc.stat_desc = StaticTree.static_l_desc;
-
- d_desc.dyn_tree = dyn_dtree;
- d_desc.stat_desc = StaticTree.static_d_desc;
-
- bl_desc.dyn_tree = bl_tree;
- bl_desc.stat_desc = StaticTree.static_bl_desc;
-
- bi_buf = 0;
- bi_valid = 0;
- last_eob_len = 8; // enough lookahead for inflate
-
- // Initialize the first block of the first file:
- init_block();
- }
-
- void init_block(){
- // Initialize the trees.
- for(int i = 0; i < L_CODES; i++) dyn_ltree[i*2] = 0;
- for(int i= 0; i < D_CODES; i++) dyn_dtree[i*2] = 0;
- for(int i= 0; i < BL_CODES; i++) bl_tree[i*2] = 0;
-
- dyn_ltree[END_BLOCK*2] = 1;
- opt_len = static_len = 0;
- last_lit = matches = 0;
- }
-
- // Restore the heap property by moving down the tree starting at node k,
- // exchanging a node with the smallest of its two sons if necessary, stopping
- // when the heap property is re-established (each father smaller than its
- // two sons).
- void pqdownheap(short[] tree, // the tree to restore
- int k // node to move down
- ){
- int v = heap[k];
- int j = k << 1; // left son of k
- while (j <= heap_len) {
- // Set j to the smallest of the two sons:
- if (j < heap_len &&
- smaller(tree, heap[j+1], heap[j], depth)){
- j++;
- }
- // Exit if v is smaller than both sons
- if(smaller(tree, v, heap[j], depth)) break;
-
- // Exchange v with the smallest son
- heap[k]=heap[j]; k = j;
- // And continue down the tree, setting j to the left son of k
- j <<= 1;
- }
- heap[k] = v;
- }
-
- static boolean smaller(short[] tree, int n, int m, byte[] depth){
- short tn2=tree[n*2];
- short tm2=tree[m*2];
- return (tn2<tm2 ||
- (tn2==tm2 && depth[n] <= depth[m]));
- }
-
- // Scan a literal or distance tree to determine the frequencies of the codes
- // in the bit length tree.
- void scan_tree (short[] tree,// the tree to be scanned
- 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; }
- tree[(max_code+1)*2+1] = (short)0xffff; // guard
-
- 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) {
- bl_tree[curlen*2] += count;
- }
- else if(curlen != 0) {
- if(curlen != prevlen) bl_tree[curlen*2]++;
- bl_tree[REP_3_6*2]++;
- }
- else if(count <= 10) {
- bl_tree[REPZ_3_10*2]++;
- }
- else{
- bl_tree[REPZ_11_138*2]++;
- }
- 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;
- }
- }
- }
-
- // Construct the Huffman tree for the bit lengths and return the index in
- // bl_order of the last bit length code to send.
- int build_bl_tree(){
- int max_blindex; // index of last bit length code of non zero freq
-
- // Determine the bit length frequencies for literal and distance trees
- scan_tree(dyn_ltree, l_desc.max_code);
- scan_tree(dyn_dtree, d_desc.max_code);
-
- // Build the bit length tree:
- bl_desc.build_tree(this);
- // opt_len now includes the length of the tree representations, except
- // the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
-
- // Determine the number of bit length codes to send. The pkzip format
- // requires that at least 4 bit length codes be sent. (appnote.txt says
- // 3 but the actual value used is 4.)
- for (max_blindex = BL_CODES-1; max_blindex >= 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<LITERALS){ bin_freq += dyn_ltree[n*2]; n++;}
- data_type=(byte)(bin_freq > (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)<<hash_shift)^(window[strstart+1]&0xff))&hash_mask;
- }
- // If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
- // but this is not important since only literal bytes will be emitted.
- }
- while (lookahead < MIN_LOOKAHEAD && strm.avail_in != 0);
- }
-
- // Compress as much as possible from the input stream, return the current
- // block state.
- // This function does not perform lazy evaluation of matches and inserts
- // new strings in the dictionary only for unmatched strings or for short
- // matches. It is used only for the fast compression options.
- int deflate_fast(int flush){
-// short hash_head = 0; // head of the hash chain
- int hash_head = 0; // head of the hash chain
- boolean bflush; // set if current block must be flushed
-
- while(true){
- // Make sure that we always have enough lookahead, except
- // at the end of the input file. We need MAX_MATCH bytes
- // for the next match, plus MIN_MATCH bytes to insert the
- // string following the next match.
- if(lookahead < MIN_LOOKAHEAD){
- fill_window();
- if(lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH){
- return NeedMore;
- }
- if(lookahead == 0) break; // flush the current block
- }
-
- // Insert the string window[strstart .. strstart+2] in the
- // dictionary, and set hash_head to the head of the hash chain:
- if(lookahead >= MIN_MATCH){
- ins_h=(((ins_h)<<hash_shift)^(window[(strstart)+(MIN_MATCH-1)]&0xff))&hash_mask;
-
-// prev[strstart&w_mask]=hash_head=head[ins_h];
- hash_head=(head[ins_h]&0xffff);
- prev[strstart&w_mask]=head[ins_h];
- head[ins_h]=(short)strstart;
- }
-
- // Find the longest match, discarding those <= prev_length.
- // At this point we have always match_length < MIN_MATCH
-
- if(hash_head!=0L &&
- ((strstart-hash_head)&0xffff) <= w_size-MIN_LOOKAHEAD
- ){
- // To simplify the code, we prevent matches with the string
- // of window index 0 (in particular we have to avoid a match
- // of the string with itself at the start of the input file).
- if(strategy != Z_HUFFMAN_ONLY){
- match_length=longest_match (hash_head);
- }
- // longest_match() sets match_start
- }
- if(match_length>=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<<hash_shift)^(window[(strstart)+(MIN_MATCH-1)]&0xff))&hash_mask;
-// prev[strstart&w_mask]=hash_head=head[ins_h];
- hash_head=(head[ins_h]&0xffff);
- prev[strstart&w_mask]=head[ins_h];
- head[ins_h]=(short)strstart;
-
- // strstart never exceeds WSIZE-MAX_MATCH, so there are
- // always MIN_MATCH bytes ahead.
- }
- while (--match_length != 0);
- strstart++;
- }
- else{
- strstart += match_length;
- match_length = 0;
- ins_h = window[strstart]&0xff;
-
- ins_h=(((ins_h)<<hash_shift)^(window[strstart+1]&0xff))&hash_mask;
- // If lookahead < MIN_MATCH, ins_h is garbage, but it does not
- // matter since it will be recomputed at next deflate call.
- }
- }
- else {
- // No match, output a literal byte
-
- bflush=_tr_tally(0, window[strstart]&0xff);
- lookahead--;
- strstart++;
- }
- if (bflush){
-
- flush_block_only(false);
- if(strm.avail_out==0) return NeedMore;
- }
- }
-
- flush_block_only(flush == Z_FINISH);
- if(strm.avail_out==0){
- if(flush == Z_FINISH) return FinishStarted;
- else return NeedMore;
- }
- return flush==Z_FINISH ? FinishDone : BlockDone;
- }
-
- // Same as above, but achieves better compression. We use a lazy
- // evaluation for matches: a match is finally adopted only if there is
- // no better match at the next window position.
- int deflate_slow(int flush){
-// short hash_head = 0; // head of hash chain
- int hash_head = 0; // head of hash chain
- boolean bflush; // set if current block must be flushed
-
- // Process the input block.
- while(true){
- // Make sure that we always have enough lookahead, except
- // at the end of the input file. We need MAX_MATCH bytes
- // for the next match, plus MIN_MATCH bytes to insert the
- // string following the next match.
-
- if (lookahead < MIN_LOOKAHEAD) {
- fill_window();
- if(lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return NeedMore;
- }
- if(lookahead == 0) break; // flush the current block
- }
-
- // Insert the string window[strstart .. strstart+2] in the
- // dictionary, and set hash_head to the head of the hash chain:
-
- if(lookahead >= MIN_MATCH) {
- ins_h=(((ins_h)<<hash_shift)^(window[(strstart)+(MIN_MATCH-1)]&0xff)) & hash_mask;
-// prev[strstart&w_mask]=hash_head=head[ins_h];
- hash_head=(head[ins_h]&0xffff);
- prev[strstart&w_mask]=head[ins_h];
- head[ins_h]=(short)strstart;
- }
-
- // Find the longest match, discarding those <= prev_length.
- prev_length = match_length; prev_match = match_start;
- match_length = MIN_MATCH-1;
-
- if (hash_head != 0 && prev_length < max_lazy_match &&
- ((strstart-hash_head)&0xffff) <= w_size-MIN_LOOKAHEAD
- ){
- // To simplify the code, we prevent matches with the string
- // of window index 0 (in particular we have to avoid a match
- // of the string with itself at the start of the input file).
-
- if(strategy != Z_HUFFMAN_ONLY) {
- match_length = longest_match(hash_head);
- }
- // longest_match() sets match_start
-
- if (match_length <= 5 && (strategy == Z_FILTERED ||
- (match_length == MIN_MATCH &&
- strstart - match_start > 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)<<hash_shift)^(window[(strstart)+(MIN_MATCH-1)]&0xff))&hash_mask;
- //prev[strstart&w_mask]=hash_head=head[ins_h];
- hash_head=(head[ins_h]&0xffff);
- prev[strstart&w_mask]=head[ins_h];
- head[ins_h]=(short)strstart;
- }
- }
- while(--prev_length != 0);
- match_available = 0;
- match_length = MIN_MATCH-1;
- strstart++;
-
- if (bflush){
- flush_block_only(false);
- if(strm.avail_out==0) return NeedMore;
- }
- } else if (match_available!=0) {
-
- // If there was no match at the previous position, output a
- // single literal. If there was a match but the current match
- // is longer, truncate the previous match to a single literal.
-
- bflush=_tr_tally(0, window[strstart-1]&0xff);
-
- if (bflush) {
- flush_block_only(false);
- }
- strstart++;
- lookahead--;
- if(strm.avail_out == 0) return NeedMore;
- } else {
- // There is no previous match to compare with, wait for
- // the next step to decide.
-
- match_available = 1;
- strstart++;
- lookahead--;
- }
- }
-
- if(match_available!=0) {
- bflush=_tr_tally(0, window[strstart-1]&0xff);
- match_available = 0;
- }
- flush_block_only(flush == Z_FINISH);
-
- if(strm.avail_out==0){
- if(flush == Z_FINISH) return FinishStarted;
- else return NeedMore;
- }
-
- return flush == Z_FINISH ? FinishDone : BlockDone;
- }
-
- int longest_match(int cur_match){
- int chain_length = max_chain_length; // max hash chain length
- int scan = strstart; // current string
- int match; // matched string
- int len; // length of current match
- int best_len = prev_length; // best match length so far
- int limit = strstart>(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(ZStream strm, int level, int bits){
- return deflateInit2(strm, level, Z_DEFLATED, bits, DEF_MEM_LEVEL,
- Z_DEFAULT_STRATEGY);
- }
- int deflateInit(ZStream strm, int level){
- return deflateInit(strm, level, MAX_WBITS);
- }
- int deflateInit2(ZStream strm, int level, int method, int windowBits,
- int memLevel, int strategy){
- int noheader = 0;
- // 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
- noheader = 1;
- windowBits = -windowBits;
- }
-
- 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.noheader = noheader;
- 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;
-
-//System.out.println("level="+level);
-
- this.strategy = strategy;
- this.method = (byte)method;
-
- return deflateReset(strm);
- }
-
- int deflateReset(ZStream strm){
- strm.total_in = strm.total_out = 0;
- strm.msg = null; //
- strm.data_type = Z_UNKNOWN;
-
- pending = 0;
- pending_out = 0;
-
- if(noheader < 0) {
- noheader = 0; // was set to -1 by deflate(..., Z_FINISH);
- }
- status = (noheader!=0) ? BUSY_STATE : INIT_STATE;
- strm.adler=strm._adler.adler32(0, null, 0, 0);
-
- 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(ZStream strm, 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 (ZStream strm, byte[] dictionary, int dictLength){
- int length = dictLength;
- int index=0;
-
- if(dictionary == null || status != INIT_STATE)
- return Z_STREAM_ERROR;
-
- strm.adler=strm._adler.adler32(strm.adler, 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)<<hash_shift)^(window[1]&0xff))&hash_mask;
-
- for(int n=0; n<=length-MIN_MATCH; n++){
- ins_h=(((ins_h)<<hash_shift)^(window[(n)+(MIN_MATCH-1)]&0xff))&hash_mask;
- prev[n&w_mask]=head[ins_h];
- head[ins_h]=(short)n;
- }
- return Z_OK;
- }
-
- int deflate(ZStream strm, int flush){
- int old_flush;
-
- if(flush>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;
- }
-
- this.strm = strm; // just in case
- old_flush = last_flush;
- last_flush = flush;
-
- // Write the zlib header
- if(status == INIT_STATE) {
- 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){
- putShortMSB((int)(strm.adler>>>16));
- putShortMSB((int)(strm.adler&0xffff));
- }
- strm.adler=strm._adler.adler32(0, null, 0, 0);
- }
-
- // Flush as much pending output as possible
- if(pending != 0) {
- strm.flush_pending();
- if(strm.avail_out == 0) {
- //System.out.println(" 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<hash_size/*-1*/; i++) // forget history
- head[i]=0;
- }
- }
- strm.flush_pending();
- if(strm.avail_out == 0) {
- last_flush = -1; // avoid BUF_ERROR at next call, see above
- return Z_OK;
- }
- }
- }
-
- if(flush!=Z_FINISH) return Z_OK;
- if(noheader!=0) return Z_STREAM_END;
-
- // Write the zlib trailer (adler32)
- putShortMSB((int)(strm.adler>>>16));
- putShortMSB((int)(strm.adler&0xffff));
- strm.flush_pending();
-
- // If avail_out is zero, the application will call deflate again
- // to flush the rest.
- noheader = -1; // write the trailer only once!
- return pending != 0 ? Z_OK : Z_STREAM_END;
- }
-}
diff --git a/app/src/main/java/com/jcraft/jzlib/InfBlocks.java b/app/src/main/java/com/jcraft/jzlib/InfBlocks.java
deleted file mode 100644
index f6997fc..0000000
--- a/app/src/main/java/com/jcraft/jzlib/InfBlocks.java
+++ /dev/null
@@ -1,614 +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 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
-
- InfCodes codes=new InfCodes(); // 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
- Object checkfn; // check function
- long check; // check on output
-
- InfTree inftree=new InfTree();
-
- InfBlocks(ZStream z, Object checkfn, int w){
- hufts=new int[MANY*3];
- window=new byte[w];
- end=w;
- this.checkfn = checkfn;
- mode = TYPE;
- reset(z, null);
- }
-
- void reset(ZStream z, long[] c){
- if(c!=null) c[0]=check;
- if(mode==BTREE || mode==DTREE){
- }
- if(mode==CODES){
- codes.free(z);
- }
- mode=TYPE;
- bitk=0;
- bitb=0;
- read=write=0;
-
- if(checkfn != null)
- z.adler=check=z._adler.adler32(0L, null, 0, 0);
- }
-
- int proc(ZStream z, 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=(int)(q<read?read-q-1:end-q);}
-
- // process input based on current state
- while(true){
- switch (mode){
- case TYPE:
-
- 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(z,r);
- };
- n--;
- b|=(z.next_in[p++]&0xff)<<k;
- k+=8;
- }
- t = (int)(b & 7);
- last = t & 1;
-
- switch (t >>> 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
- {
- int[] bl=new int[1];
- int[] bd=new int[1];
- int[][] tl=new int[1][];
- int[][] td=new int[1][];
-
- InfTree.inflate_trees_fixed(bl, bd, tl, td, z);
- codes.init(bl[0], bd[0], tl[0], 0, td[0], 0, z);
- }
-
- {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(z,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(z,r);
- };
- n--;
- b|=(z.next_in[p++]&0xff)<<k;
- k+=8;
- }
-
- if ((((~b) >>> 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(z,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(z,r);
- }
-
- if(m==0){
- if(q==end&&read!=0){
- q=0; m=(int)(q<read?read-q-1:end-q);
- }
- if(m==0){
- write=q;
- r=inflate_flush(z,r);
- q=write;m=(int)(q<read?read-q-1:end-q);
- if(q==end&&read!=0){
- q=0; m=(int)(q<read?read-q-1:end-q);
- }
- if(m==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(z,r);
- }
- }
- }
- r=Z_OK;
-
- t = left;
- if(t>n) 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(z,r);
- };
- n--;
- b|=(z.next_in[p++]&0xff)<<k;
- k+=8;
- }
-
- table = t = (b & 0x3fff);
- if ((t & 0x1f) > 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(z,r);
- }
- t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
- if(blens==null || blens.length<t){
- blens=new int[t];
- }
- else{
- for(int i=0; i<t; i++){blens[i]=0;}
- }
-
- {b>>>=(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(z,r);
- };
- n--;
- b|=(z.next_in[p++]&0xff)<<k;
- k+=8;
- }
-
- blens[border[index++]] = b&7;
-
- {b>>>=(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(z,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(z,r);
- };
- n--;
- b|=(z.next_in[p++]&0xff)<<k;
- k+=8;
- }
-
- if(tb[0]==-1){
- //System.err.println("null...");
- }
-
- t=hufts[(tb[0]+(b&inflate_mask[t]))*3+1];
- c=hufts[(tb[0]+(b&inflate_mask[t]))*3+2];
-
- if (c < 16){
- b>>>=(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(z,r);
- };
- n--;
- b|=(z.next_in[p++]&0xff)<<k;
- k+=8;
- }
-
- b>>>=(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(z,r);
- }
-
- c = c == 16 ? blens[i-1] : 0;
- do{
- blens[i++] = c;
- }
- while (--j!=0);
- index = i;
- }
- }
-
- tb[0]=-1;
- {
- int[] bl=new int[1];
- int[] bd=new int[1];
- int[] tl=new int[1];
- int[] td=new int[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, tl, td, 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(z,r);
- }
- codes.init(bl[0], bd[0], hufts, tl[0], hufts, td[0], z);
- }
- 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(this, z, r)) != Z_STREAM_END){
- return inflate_flush(z, 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<read?read-q-1:end-q);
-
- if (last==0){
- mode = TYPE;
- break;
- }
- mode = DRY;
- case DRY:
- write=q;
- r=inflate_flush(z, r);
- q=write; m=(int)(q<read?read-q-1:end-q);
- if (read != write){
- 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(z, r);
- }
- mode = DONE;
- case DONE:
- r = Z_STREAM_END;
-
- 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(z, r);
- case BAD:
- 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(z, r);
-
- default:
- r = Z_STREAM_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(z, r);
- }
- }
- }
-
- void free(ZStream z){
- reset(z, null);
- window=null;
- hufts=null;
- //ZFREE(z, s);
- }
-
- void set_dictionary(byte[] d, int start, int n){
- System.arraycopy(d, start, window, 0, n);
- read = write = n;
- }
-
- // Returns true if inflate is currently at the end of a block generated
- // by Z_SYNC_FLUSH or Z_FULL_FLUSH.
- int sync_point(){
- return mode == LENS ? 1 : 0;
- }
-
- // copy as much as possible from the sliding window to the output area
- int inflate_flush(ZStream z, int r){
- int n;
- int p;
- int q;
-
- // local copies of source and destination pointers
- p = z.next_out_index;
- q = read;
-
- // compute number of bytes to copy as far as end of window
- n = (int)((q <= write ? write : end) - 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(checkfn != null)
- z.adler=check=z._adler.adler32(check, 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(checkfn != null)
- z.adler=check=z._adler.adler32(check, 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/app/src/main/java/com/jcraft/jzlib/InfCodes.java b/app/src/main/java/com/jcraft/jzlib/InfCodes.java
deleted file mode 100644
index c768fb1..0000000
--- a/app/src/main/java/com/jcraft/jzlib/InfCodes.java
+++ /dev/null
@@ -1,605 +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
-
- InfCodes(){
- }
- void init(int bl, int bd,
- int[] tl, int tl_index,
- int[] td, int td_index, ZStream z){
- mode=START;
- lbits=(byte)bl;
- dbits=(byte)bd;
- ltree=tl;
- ltree_index=tl_index;
- dtree = td;
- dtree_index=td_index;
- tree=null;
- }
-
- int proc(InfBlocks s, ZStream z, 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<s.read?s.read-q-1:s.end-q;
-
- // process input and output based on current state
- while (true){
- switch (mode){
- // waiting for "i:"=input, "o:"=output, "x:"=nothing
- case START: // x: set up for LEN
- if (m >= 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<s.read?s.read-q-1:s.end-q;
-
- if (r != Z_OK){
- mode = r == Z_STREAM_END ? WASH : BADCODE;
- break;
- }
- }
- need = lbits;
- tree = ltree;
- tree_index=ltree_index;
-
- mode = LEN;
- case LEN: // i: get length/literal/eob 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(z,r);
- }
- n--;
- b|=(z.next_in[p++]&0xff)<<k;
- k+=8;
- }
-
- tindex=(tree_index+(b&inflate_mask[j]))*3;
-
- b>>>=(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(z,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(z,r);
- }
- n--; b|=(z.next_in[p++]&0xff)<<k;
- k+=8;
- }
-
- len += (b & inflate_mask[j]);
-
- b>>=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(z,r);
- }
- n--; b|=(z.next_in[p++]&0xff)<<k;
- k+=8;
- }
-
- tindex=(tree_index+(b & inflate_mask[j]))*3;
-
- b>>=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(z,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(z,r);
- }
- n--; b|=(z.next_in[p++]&0xff)<<k;
- k+=8;
- }
-
- dist += (b & inflate_mask[j]);
-
- b>>=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<s.read?s.read-q-1:s.end-q;}
- if(m==0){
- s.write=q; r=s.inflate_flush(z,r);
- q=s.write;m=q<s.read?s.read-q-1:s.end-q;
-
- if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;}
-
- if(m==0){
- 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(z,r);
- }
- }
- }
-
- s.window[q++]=s.window[f++]; m--;
-
- if (f == s.end)
- f = 0;
- len--;
- }
- mode = START;
- break;
- case LIT: // o: got literal, waiting for output space
- if(m==0){
- if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;}
- if(m==0){
- s.write=q; r=s.inflate_flush(z,r);
- q=s.write;m=q<s.read?s.read-q-1:s.end-q;
-
- if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;}
- if(m==0){
- 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(z,r);
- }
- }
- }
- r=Z_OK;
-
- s.window[q++]=(byte)lit; m--;
-
- mode = START;
- break;
- case WASH: // o: got eob, possibly more output
- if (k > 7){ // return unused byte, if any
- k -= 8;
- n++;
- p--; // can always return one
- }
-
- s.write=q; r=s.inflate_flush(z,r);
- q=s.write;m=q<s.read?s.read-q-1:s.end-q;
-
- if (s.read != s.write){
- 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(z,r);
- }
- mode = END;
- case END:
- r = Z_STREAM_END;
- 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(z,r);
-
- case BADCODE: // x: got error
-
- 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(z,r);
-
- default:
- r = Z_STREAM_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(z,r);
- }
- }
- }
-
- void free(ZStream z){
- // ZFREE(z, c);
- }
-
- // Called with number of bytes left to write in window at least 258
- // (the maximum string length) and number of input bytes available
- // at least ten. The ten bytes are six bytes for the longest length/
- // distance pair plus four bytes for overloading the bit buffer.
-
- int inflate_fast(int bl, int bd,
- int[] tl, int tl_index,
- int[] td, int td_index,
- InfBlocks s, ZStream z){
- int t; // temporary pointer
- int[] tp; // temporary pointer
- int tp_index; // temporary pointer
- int e; // extra bits or operation
- 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
- int ml; // mask for literal/length tree
- int md; // mask for distance tree
- int c; // bytes to copy
- int d; // distance back to copy from
- int r; // copy source pointer
-
- int tp_index_t_3; // (tp_index+t)*3
-
- // load input, output, bit values
- p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk;
- q=s.write;m=q<s.read?s.read-q-1:s.end-q;
-
- // initialize masks
- ml = inflate_mask[bl];
- md = inflate_mask[bd];
-
- // do until not enough input or output space for fast loop
- do { // assume called with m >= 258 && n >= 10
- // get literal/length code
- while(k<(20)){ // max bits for literal/length code
- n--;
- b|=(z.next_in[p++]&0xff)<<k;k+=8;
- }
-
- t= b&ml;
- tp=tl;
- tp_index=tl_index;
- 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--;
- 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)<<k;k+=8;
- }
-
- t= b&md;
- tp=td;
- tp_index=td_index;
- tp_index_t_3=(tp_index+t)*3;
- e = tp[tp_index_t_3];
-
- do {
-
- b>>=(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)<<k;k+=8;
- }
-
- d = tp[tp_index_t_3+2] + (b&inflate_mask[e]);
-
- b>>=(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)<c?k>>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)<c?k>>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)<c?k>>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)<c?k>>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/app/src/main/java/com/jcraft/jzlib/InfTree.java b/app/src/main/java/com/jcraft/jzlib/InfTree.java
deleted file mode 100644
index cbca436..0000000
--- a/app/src/main/java/com/jcraft/jzlib/InfTree.java
+++ /dev/null
@@ -1,520 +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<z;j+=f){
- System.arraycopy(r, 0, hp, (q+j)*3, 3);
- }
-
- // backwards increment the k-bit code i
- for (j = 1 << (k - 1); (i & j)!=0; 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<vsize){ v=new int[vsize]; }
- for(int i=0; i<vsize; i++){v[i]=0;}
- for(int i=0; i<BMAX+1; i++){c[i]=0;}
- for(int i=0; i<3; i++){r[i]=0;}
-// for(int i=0; i<BMAX; i++){u[i]=0;}
- System.arraycopy(c, 0, u, 0, BMAX);
-// for(int i=0; i<BMAX+1; i++){x[i]=0;}
- System.arraycopy(c, 0, x, 0, BMAX+1);
- }
-}
diff --git a/app/src/main/java/com/jcraft/jzlib/Inflate.java b/app/src/main/java/com/jcraft/jzlib/Inflate.java
deleted file mode 100644
index 30310f6..0000000
--- a/app/src/main/java/com/jcraft/jzlib/Inflate.java
+++ /dev/null
@@ -1,374 +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 Inflate{
-
- static final private int MAX_WBITS=15; // 32K LZ77 window
-
- // preset dictionary flag in zlib header
- static final private int PRESET_DICT=0x20;
-
- 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 private int Z_DEFLATED=8;
-
- 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 METHOD=0; // waiting for method byte
- static final private int FLAG=1; // waiting for flag byte
- static final private int DICT4=2; // four dictionary check bytes to go
- static final private int DICT3=3; // three dictionary check bytes to go
- static final private int DICT2=4; // two dictionary check bytes to go
- static final private int DICT1=5; // one dictionary check byte to go
- static final private int DICT0=6; // waiting for inflateSetDictionary
- static final private int BLOCKS=7; // decompressing blocks
- static final private int CHECK4=8; // four check bytes to go
- static final private int CHECK3=9; // three check bytes to go
- static final private int CHECK2=10; // two check bytes to go
- static final private int CHECK1=11; // one check byte to go
- static final private int DONE=12; // finished check, done
- static final private int BAD=13; // got an error--stay here
-
- int mode; // current inflate mode
-
- // mode dependent information
- int method; // if FLAGS, method byte
-
- // if CHECK, check values to compare
- long[] was=new long[1] ; // computed check value
- long need; // stream check value
-
- // if BAD, inflateSync's marker bytes count
- int marker;
-
- // mode independent information
- int nowrap; // flag for no wrapper
- int wbits; // log2(window size) (8..15, defaults to 15)
-
- InfBlocks blocks; // current inflate_blocks state
-
- int inflateReset(ZStream z){
- if(z == null || z.istate == null) return Z_STREAM_ERROR;
-
- z.total_in = z.total_out = 0;
- z.msg = null;
- z.istate.mode = z.istate.nowrap!=0 ? BLOCKS : METHOD;
- z.istate.blocks.reset(z, null);
- return Z_OK;
- }
-
- int inflateEnd(ZStream z){
- if(blocks != null)
- blocks.free(z);
- blocks=null;
- // ZFREE(z, z->state);
- return Z_OK;
- }
-
- int inflateInit(ZStream z, int w){
- z.msg = null;
- blocks = null;
-
- // handle undocumented nowrap option (no zlib header or check)
- nowrap = 0;
- if(w < 0){
- w = - w;
- nowrap = 1;
- }
-
- // set window size
- if(w<8 ||w>15){
- inflateEnd(z);
- return Z_STREAM_ERROR;
- }
- wbits=w;
-
- z.istate.blocks=new InfBlocks(z,
- z.istate.nowrap!=0 ? null : this,
- 1<<w);
-
- // reset state
- inflateReset(z);
- return Z_OK;
- }
-
- int inflate(ZStream z, int f){
- int r;
- int b;
-
- if(z == null || z.istate == null || z.next_in == null)
- return Z_STREAM_ERROR;
- f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
- r = Z_BUF_ERROR;
- while (true){
-//System.out.println("mode: "+z.istate.mode);
- switch (z.istate.mode){
- case METHOD:
-
- if(z.avail_in==0)return r;r=f;
-
- z.avail_in--; z.total_in++;
- if(((z.istate.method = z.next_in[z.next_in_index++])&0xf)!=Z_DEFLATED){
- z.istate.mode = BAD;
- z.msg="unknown compression method";
- z.istate.marker = 5; // can't try inflateSync
- break;
- }
- if((z.istate.method>>4)+8>z.istate.wbits){
- z.istate.mode = BAD;
- z.msg="invalid window size";
- z.istate.marker = 5; // can't try inflateSync
- break;
- }
- z.istate.mode=FLAG;
- case FLAG:
-
- if(z.avail_in==0)return r;r=f;
-
- z.avail_in--; z.total_in++;
- b = (z.next_in[z.next_in_index++])&0xff;
-
- if((((z.istate.method << 8)+b) % 31)!=0){
- z.istate.mode = BAD;
- z.msg = "incorrect header check";
- z.istate.marker = 5; // can't try inflateSync
- break;
- }
-
- if((b&PRESET_DICT)==0){
- z.istate.mode = BLOCKS;
- break;
- }
- z.istate.mode = DICT4;
- case DICT4:
-
- if(z.avail_in==0)return r;r=f;
-
- z.avail_in--; z.total_in++;
- z.istate.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L;
- z.istate.mode=DICT3;
- case DICT3:
-
- if(z.avail_in==0)return r;r=f;
-
- z.avail_in--; z.total_in++;
- z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L;
- z.istate.mode=DICT2;
- case DICT2:
-
- if(z.avail_in==0)return r;r=f;
-
- z.avail_in--; z.total_in++;
- z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L;
- z.istate.mode=DICT1;
- case DICT1:
-
- if(z.avail_in==0)return r;r=f;
-
- z.avail_in--; z.total_in++;
- z.istate.need += (z.next_in[z.next_in_index++]&0xffL);
- z.adler = z.istate.need;
- z.istate.mode = DICT0;
- return Z_NEED_DICT;
- case DICT0:
- z.istate.mode = BAD;
- z.msg = "need dictionary";
- z.istate.marker = 0; // can try inflateSync
- return Z_STREAM_ERROR;
- case BLOCKS:
-
- r = z.istate.blocks.proc(z, r);
- if(r == Z_DATA_ERROR){
- z.istate.mode = BAD;
- z.istate.marker = 0; // can try inflateSync
- break;
- }
- if(r == Z_OK){
- r = f;
- }
- if(r != Z_STREAM_END){
- return r;
- }
- r = f;
- z.istate.blocks.reset(z, z.istate.was);
- if(z.istate.nowrap!=0){
- z.istate.mode=DONE;
- break;
- }
- z.istate.mode=CHECK4;
- case CHECK4:
-
- if(z.avail_in==0)return r;r=f;
-
- z.avail_in--; z.total_in++;
- z.istate.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L;
- z.istate.mode=CHECK3;
- case CHECK3:
-
- if(z.avail_in==0)return r;r=f;
-
- z.avail_in--; z.total_in++;
- z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L;
- z.istate.mode = CHECK2;
- case CHECK2:
-
- if(z.avail_in==0)return r;r=f;
-
- z.avail_in--; z.total_in++;
- z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L;
- z.istate.mode = CHECK1;
- case CHECK1:
-
- if(z.avail_in==0)return r;r=f;
-
- z.avail_in--; z.total_in++;
- z.istate.need+=(z.next_in[z.next_in_index++]&0xffL);
-
- if(((int)(z.istate.was[0])) != ((int)(z.istate.need))){
- z.istate.mode = BAD;
- z.msg = "incorrect data check";
- z.istate.marker = 5; // can't try inflateSync
- break;
- }
-
- z.istate.mode = DONE;
- case DONE:
- return Z_STREAM_END;
- case BAD:
- return Z_DATA_ERROR;
- default:
- return Z_STREAM_ERROR;
- }
- }
- }
-
-
- int inflateSetDictionary(ZStream z, byte[] dictionary, int dictLength){
- int index=0;
- int length = dictLength;
- if(z==null || z.istate == null|| z.istate.mode != DICT0)
- return Z_STREAM_ERROR;
-
- if(z._adler.adler32(1L, dictionary, 0, dictLength)!=z.adler){
- return Z_DATA_ERROR;
- }
-
- z.adler = z._adler.adler32(0, null, 0, 0);
-
- if(length >= (1<<z.istate.wbits)){
- length = (1<<z.istate.wbits)-1;
- index=dictLength - length;
- }
- z.istate.blocks.set_dictionary(dictionary, index, length);
- z.istate.mode = BLOCKS;
- return Z_OK;
- }
-
- static private byte[] mark = {(byte)0, (byte)0, (byte)0xff, (byte)0xff};
-
- int inflateSync(ZStream z){
- int n; // number of bytes to look at
- int p; // pointer to bytes
- int m; // number of marker bytes found in a row
- long r, w; // temporaries to save total_in and total_out
-
- // set up
- if(z == null || z.istate == null)
- return Z_STREAM_ERROR;
- if(z.istate.mode != BAD){
- z.istate.mode = BAD;
- z.istate.marker = 0;
- }
- if((n=z.avail_in)==0)
- return Z_BUF_ERROR;
- p=z.next_in_index;
- m=z.istate.marker;
-
- // search
- while (n!=0 && m < 4){
- if(z.next_in[p] == mark[m]){
- m++;
- }
- else if(z.next_in[p]!=0){
- m = 0;
- }
- else{
- m = 4 - m;
- }
- p++; n--;
- }
-
- // restore
- z.total_in += p-z.next_in_index;
- z.next_in_index = p;
- z.avail_in = n;
- z.istate.marker = m;
-
- // return no joy or set up to restart on a new block
- if(m != 4){
- return Z_DATA_ERROR;
- }
- r=z.total_in; w=z.total_out;
- inflateReset(z);
- z.total_in=r; z.total_out = w;
- z.istate.mode = BLOCKS;
- return Z_OK;
- }
-
- // Returns true if inflate is currently at the end of a block generated
- // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
- // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
- // but removes the length bytes of the resulting empty stored block. When
- // decompressing, PPP checks that at the end of input packet, inflate is
- // waiting for these length bytes.
- int inflateSyncPoint(ZStream z){
- if(z == null || z.istate == null || z.istate.blocks == null)
- return Z_STREAM_ERROR;
- return z.istate.blocks.sync_point();
- }
-}
diff --git a/app/src/main/java/com/jcraft/jzlib/JZlib.java b/app/src/main/java/com/jcraft/jzlib/JZlib.java
deleted file mode 100644
index b84d7a1..0000000
--- a/app/src/main/java/com/jcraft/jzlib/JZlib.java
+++ /dev/null
@@ -1,67 +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 public class JZlib{
- private static final String version="1.0.2";
- public static String version(){return version;}
-
- // 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;
-}
diff --git a/app/src/main/java/com/jcraft/jzlib/StaticTree.java b/app/src/main/java/com/jcraft/jzlib/StaticTree.java
deleted file mode 100644
index 0f7f577..0000000
--- a/app/src/main/java/com/jcraft/jzlib/StaticTree.java
+++ /dev/null
@@ -1,149 +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
-
- 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/app/src/main/java/com/jcraft/jzlib/Tree.java b/app/src/main/java/com/jcraft/jzlib/Tree.java
deleted file mode 100644
index 8103897..0000000
--- a/app/src/main/java/com/jcraft/jzlib/Tree.java
+++ /dev/null
@@ -1,365 +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<HEAP_SIZE; h++){
- n = s.heap[h];
- bits = tree[tree[n*2+1]*2+1] + 1;
- if (bits > 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<elems; n++) {
- if(tree[n*2] != 0) {
- s.heap[++s.heap_len] = max_code = n;
- s.depth[n] = 0;
- }
- else{
- tree[n*2+1] = 0;
- }
- }
-
- // The pkzip format requires that at least one distance code exists,
- // and that at least one bit should be sent even if there is only one
- // possible code. So to avoid special checks later on we force at least
- // two codes of non zero frequency.
- while (s.heap_len < 2) {
- node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0);
- tree[node*2] = 1;
- s.depth[node] = 0;
- s.opt_len--; if (stree!=null) s.static_len -= stree[node*2+1];
- // node is 0 or 1 so it does not have extra bits
- }
- this.max_code = max_code;
-
- // The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
- // establish sub-heaps of increasing lengths:
-
- for(n=s.heap_len/2;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);
- }
-
- // 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.
- 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=new short[MAX_BITS+1]; // next code value for each bit length
- 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.
- 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<<MAX_BITS)-1,
- // "inconsistent bit counts");
- //Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
- for (n = 0; n <= max_code; n++) {
- int len = tree[n*2+1];
- if (len == 0) continue;
- // Now reverse the bits
- tree[n*2] = (short)(bi_reverse(next_code[len]++, len));
- }
- }
-
- // Reverse the first len bits of a code, using straightforward code (a faster
- // method would use a table)
- // IN assertion: 1 <= len <= 15
- static int bi_reverse(int code, // the value to invert
- int len // its bit length
- ){
- int res = 0;
- do{
- res|=code&1;
- code>>>=1;
- res<<=1;
- }
- while(--len>0);
- return res>>>1;
- }
-}
-
diff --git a/app/src/main/java/com/jcraft/jzlib/ZInputStream.java b/app/src/main/java/com/jcraft/jzlib/ZInputStream.java
deleted file mode 100644
index 3f97c44..0000000
--- a/app/src/main/java/com/jcraft/jzlib/ZInputStream.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
-/*
-Copyright (c) 2001 Lapo Luchini.
-
-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 THE AUTHORS
-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.*;
-
-public class ZInputStream extends FilterInputStream {
-
- protected ZStream z=new ZStream();
- protected int bufsize=512;
- protected int flush=JZlib.Z_NO_FLUSH;
- protected byte[] buf=new byte[bufsize],
- buf1=new byte[1];
- protected boolean compress;
-
- protected InputStream in=null;
-
- public ZInputStream(InputStream in) {
- this(in, false);
- }
- public ZInputStream(InputStream in, boolean nowrap) {
- super(in);
- this.in=in;
- z.inflateInit(nowrap);
- compress=false;
- z.next_in=buf;
- z.next_in_index=0;
- z.avail_in=0;
- }
-
- public ZInputStream(InputStream in, int level) {
- super(in);
- this.in=in;
- z.deflateInit(level);
- compress=true;
- z.next_in=buf;
- z.next_in_index=0;
- z.avail_in=0;
- }
-
- /*public int available() throws IOException {
- return inf.finished() ? 0 : 1;
- }*/
-
- public int read() throws IOException {
- if(read(buf1, 0, 1)==-1)
- return(-1);
- return(buf1[0]&0xFF);
- }
-
- private boolean nomoreinput=false;
-
- public int read(byte[] b, int off, int len) throws IOException {
- if(len==0)
- return(0);
- int err;
- z.next_out=b;
- z.next_out_index=off;
- z.avail_out=len;
- do {
- if((z.avail_in==0)&&(!nomoreinput)) { // if buffer is empty and more input is avaiable, refill it
- z.next_in_index=0;
- z.avail_in=in.read(buf, 0, bufsize);//(bufsize<z.avail_out ? bufsize : z.avail_out));
- if(z.avail_in==-1) {
- z.avail_in=0;
- nomoreinput=true;
- }
- }
- if(compress)
- err=z.deflate(flush);
- else
- err=z.inflate(flush);
- if(nomoreinput&&(err==JZlib.Z_BUF_ERROR))
- return(-1);
- if(err!=JZlib.Z_OK && err!=JZlib.Z_STREAM_END)
- throw new ZStreamException((compress ? "de" : "in")+"flating: "+z.msg);
- if((nomoreinput||err==JZlib.Z_STREAM_END)&&(z.avail_out==len))
- return(-1);
- }
- while(z.avail_out==len&&err==JZlib.Z_OK);
- //System.err.print("("+(len-z.avail_out)+")");
- return(len-z.avail_out);
- }
-
- public long skip(long n) throws IOException {
- int len=512;
- if(n<len)
- len=(int)n;
- byte[] tmp=new byte[len];
- return((long)read(tmp));
- }
-
- public int getFlushMode() {
- return(flush);
- }
-
- public void setFlushMode(int flush) {
- this.flush=flush;
- }
-
- /**
- * Returns the total number of bytes input so far.
- */
- public long getTotalIn() {
- return z.total_in;
- }
-
- /**
- * Returns the total number of bytes output so far.
- */
- public long getTotalOut() {
- return z.total_out;
- }
-
- public void close() throws IOException{
- in.close();
- }
-}
diff --git a/app/src/main/java/com/jcraft/jzlib/ZOutputStream.java b/app/src/main/java/com/jcraft/jzlib/ZOutputStream.java
deleted file mode 100644
index afee65b..0000000
--- a/app/src/main/java/com/jcraft/jzlib/ZOutputStream.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
-/*
-Copyright (c) 2001 Lapo Luchini.
-
-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 THE AUTHORS
-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.*;
-
-public class ZOutputStream extends OutputStream {
-
- protected ZStream z=new ZStream();
- protected int bufsize=512;
- protected int flush=JZlib.Z_NO_FLUSH;
- protected byte[] buf=new byte[bufsize],
- buf1=new byte[1];
- protected boolean compress;
-
- protected OutputStream out;
-
- public ZOutputStream(OutputStream out) {
- super();
- this.out=out;
- z.inflateInit();
- compress=false;
- }
-
- public ZOutputStream(OutputStream out, int level) {
- this(out, level, false);
- }
- public ZOutputStream(OutputStream out, int level, boolean nowrap) {
- super();
- this.out=out;
- z.deflateInit(level, nowrap);
- compress=true;
- }
-
- public void write(int b) throws IOException {
- buf1[0]=(byte)b;
- write(buf1, 0, 1);
- }
-
- public void write(byte b[], int off, int len) throws IOException {
- if(len==0)
- return;
- int err;
- z.next_in=b;
- z.next_in_index=off;
- z.avail_in=len;
- do{
- z.next_out=buf;
- z.next_out_index=0;
- z.avail_out=bufsize;
- if(compress)
- err=z.deflate(flush);
- else
- err=z.inflate(flush);
- if(err!=JZlib.Z_OK)
- throw new ZStreamException((compress?"de":"in")+"flating: "+z.msg);
- out.write(buf, 0, bufsize-z.avail_out);
- }
- while(z.avail_in>0 || z.avail_out==0);
- }
-
- public int getFlushMode() {
- return(flush);
- }
-
- public void setFlushMode(int flush) {
- this.flush=flush;
- }
-
- public void finish() throws IOException {
- int err;
- do{
- z.next_out=buf;
- z.next_out_index=0;
- z.avail_out=bufsize;
- if(compress){ err=z.deflate(JZlib.Z_FINISH); }
- else{ err=z.inflate(JZlib.Z_FINISH); }
- if(err!=JZlib.Z_STREAM_END && err != JZlib.Z_OK)
- throw new ZStreamException((compress?"de":"in")+"flating: "+z.msg);
- if(bufsize-z.avail_out>0){
- out.write(buf, 0, bufsize-z.avail_out);
- }
- }
- while(z.avail_in>0 || z.avail_out==0);
- flush();
- }
- public void end() {
- if(z==null)
- return;
- if(compress){ z.deflateEnd(); }
- else{ z.inflateEnd(); }
- z.free();
- z=null;
- }
- public void close() throws IOException {
- try{
- try{finish();}
- catch (IOException ignored) {}
- }
- finally{
- end();
- out.close();
- out=null;
- }
- }
-
- /**
- * Returns the total number of bytes input so far.
- */
- public long getTotalIn() {
- return z.total_in;
- }
-
- /**
- * Returns the total number of bytes output so far.
- */
- public long getTotalOut() {
- return z.total_out;
- }
-
- public void flush() throws IOException {
- out.flush();
- }
-
-}
diff --git a/app/src/main/java/com/jcraft/jzlib/ZStream.java b/app/src/main/java/com/jcraft/jzlib/ZStream.java
deleted file mode 100644
index 334475e..0000000
--- a/app/src/main/java/com/jcraft/jzlib/ZStream.java
+++ /dev/null
@@ -1,211 +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 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
-
- public long adler;
- Adler32 _adler=new Adler32();
-
- 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(int w, boolean nowrap){
- istate=new Inflate();
- return istate.inflateInit(this, nowrap?-w:w);
- }
-
- public int inflate(int f){
- if(istate==null) return Z_STREAM_ERROR;
- return istate.inflate(this, f);
- }
- public int inflateEnd(){
- if(istate==null) return Z_STREAM_ERROR;
- int ret=istate.inflateEnd(this);
- istate = null;
- return ret;
- }
- public int inflateSync(){
- if(istate == null)
- return Z_STREAM_ERROR;
- return istate.inflateSync(this);
- }
- public int inflateSetDictionary(byte[] dictionary, int dictLength){
- if(istate == null)
- return Z_STREAM_ERROR;
- return istate.inflateSetDictionary(this, dictionary, dictLength);
- }
-
- 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, boolean nowrap){
- dstate=new Deflate();
- return dstate.deflateInit(this, level, nowrap?-bits:bits);
- }
- public int deflate(int flush){
- if(dstate==null){
- return Z_STREAM_ERROR;
- }
- return dstate.deflate(this, 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(this, level, strategy);
- }
- public int deflateSetDictionary (byte[] dictionary, int dictLength){
- if(dstate == null)
- return Z_STREAM_ERROR;
- return dstate.deflateSetDictionary(this, 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.noheader==0) {
- adler=_adler.adler32(adler, 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 void free(){
- next_in=null;
- next_out=null;
- msg=null;
- _adler=null;
- }
-}
diff --git a/app/src/main/java/com/jcraft/jzlib/ZStreamException.java b/app/src/main/java/com/jcraft/jzlib/ZStreamException.java
deleted file mode 100644
index 308bb8a..0000000
--- a/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/app/src/main/java/com/trilead/ssh2/AuthAgentCallback.java b/app/src/main/java/com/trilead/ssh2/AuthAgentCallback.java
deleted file mode 100644
index 7fe270b..0000000
--- a/app/src/main/java/com/trilead/ssh2/AuthAgentCallback.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.trilead.ssh2;
-
-import java.security.KeyPair;
-import java.util.Map;
-
-/**
- * AuthAgentCallback.
- *
- * @author Kenny Root
- * @version $Id$
- */
-public interface AuthAgentCallback {
-
- /**
- * @return array of blobs containing the OpenSSH-format encoded public keys
- */
- Map<String,byte[]> retrieveIdentities();
-
- /**
- * @param key A <code>RSAPrivateKey</code> or <code>DSAPrivateKey</code>
- * containing a DSA or RSA private key of
- * the user in Trilead object format.
- * @param comment comment associated with this key
- * @param confirmUse whether to prompt before using this key
- * @param lifetime lifetime in seconds for key to be remembered
- * @return success or failure
- */
- boolean addIdentity(KeyPair pair, String comment, boolean confirmUse, int lifetime);
-
- /**
- * @param publicKey byte blob containing the OpenSSH-format encoded public key
- * @return success or failure
- */
- boolean removeIdentity(byte[] publicKey);
-
- /**
- * @return success or failure
- */
- boolean removeAllIdentities();
-
- /**
- * @param publicKey byte blob containing the OpenSSH-format encoded public key
- * @return A <code>RSAPrivateKey</code> or <code>DSAPrivateKey</code>
- * containing a DSA or RSA private key of
- * the user in Trilead object format.
- */
- KeyPair getKeyPair(byte[] publicKey);
-
- /**
- * @return
- */
- boolean isAgentLocked();
-
- /**
- * @param lockPassphrase
- */
- boolean setAgentLock(String lockPassphrase);
-
- /**
- * @param unlockPassphrase
- * @return
- */
- boolean requestAgentUnlock(String unlockPassphrase);
-}
diff --git a/app/src/main/java/com/trilead/ssh2/ChannelCondition.java b/app/src/main/java/com/trilead/ssh2/ChannelCondition.java
deleted file mode 100644
index df1ad50..0000000
--- a/app/src/main/java/com/trilead/ssh2/ChannelCondition.java
+++ /dev/null
@@ -1,61 +0,0 @@
-
-package com.trilead.ssh2;
-
-/**
- * Contains constants that can be used to specify what conditions to wait for on
- * a SSH-2 channel (e.g., represented by a {@link Session}).
- *
- * @see Session#waitForCondition(int, long)
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: ChannelCondition.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-
-public abstract interface ChannelCondition
-{
- /**
- * A timeout has occurred, none of your requested conditions is fulfilled.
- * However, other conditions may be true - therefore, NEVER use the "=="
- * operator to test for this (or any other) condition. Always use
- * something like <code>((cond & ChannelCondition.CLOSED) != 0)</code>.
- */
- public static final int TIMEOUT = 1;
-
- /**
- * The underlying SSH-2 channel, however not necessarily the whole connection,
- * has been closed. This implies <code>EOF</code>. Note that there may still
- * be unread stdout or stderr data in the local window, i.e, <code>STDOUT_DATA</code>
- * or/and <code>STDERR_DATA</code> may be set at the same time.
- */
- public static final int CLOSED = 2;
-
- /**
- * There is stdout data available that is ready to be consumed.
- */
- public static final int STDOUT_DATA = 4;
-
- /**
- * There is stderr data available that is ready to be consumed.
- */
- public static final int STDERR_DATA = 8;
-
- /**
- * EOF on has been reached, no more _new_ stdout or stderr data will arrive
- * from the remote server. However, there may be unread stdout or stderr
- * data, i.e, <code>STDOUT_DATA</code> or/and <code>STDERR_DATA</code>
- * may be set at the same time.
- */
- public static final int EOF = 16;
-
- /**
- * The exit status of the remote process is available.
- * Some servers never send the exist status, or occasionally "forget" to do so.
- */
- public static final int EXIT_STATUS = 32;
-
- /**
- * The exit signal of the remote process is available.
- */
- public static final int EXIT_SIGNAL = 64;
-
-}
diff --git a/app/src/main/java/com/trilead/ssh2/Connection.java b/app/src/main/java/com/trilead/ssh2/Connection.java
deleted file mode 100644
index 163fdb5..0000000
--- a/app/src/main/java/com/trilead/ssh2/Connection.java
+++ /dev/null
@@ -1,1628 +0,0 @@
-
-package com.trilead.ssh2;
-
-import java.io.CharArrayWriter;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketTimeoutException;
-import java.security.KeyPair;
-import java.security.SecureRandom;
-import java.security.Security;
-import java.util.Set;
-import java.util.Vector;
-
-import com.trilead.ssh2.auth.AuthenticationManager;
-import com.trilead.ssh2.channel.ChannelManager;
-import com.trilead.ssh2.crypto.CryptoWishList;
-import com.trilead.ssh2.crypto.cipher.BlockCipherFactory;
-import com.trilead.ssh2.crypto.digest.MAC;
-import com.trilead.ssh2.log.Logger;
-import com.trilead.ssh2.packets.PacketIgnore;
-import com.trilead.ssh2.transport.KexManager;
-import com.trilead.ssh2.transport.TransportManager;
-import com.trilead.ssh2.util.TimeoutService;
-import com.trilead.ssh2.util.TimeoutService.TimeoutToken;
-
-/**
- * A <code>Connection</code> is used to establish an encrypted TCP/IP
- * connection to a SSH-2 server.
- * <p>
- * Typically, one
- * <ol>
- * <li>creates a {@link #Connection(String) Connection} object.</li>
- * <li>calls the {@link #connect() connect()} method.</li>
- * <li>calls some of the authentication methods (e.g.,
- * {@link #authenticateWithPublicKey(String, File, String) authenticateWithPublicKey()}).</li>
- * <li>calls one or several times the {@link #openSession() openSession()}
- * method.</li>
- * <li>finally, one must close the connection and release resources with the
- * {@link #close() close()} method.</li>
- * </ol>
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: Connection.java,v 1.3 2008/04/01 12:38:09 cplattne Exp $
- */
-
-public class Connection
-{
- /**
- * The identifier presented to the SSH-2 server.
- */
- public final static String identification = "TrileadSSH2Java_213";
-
- /**
- * Will be used to generate all random data needed for the current
- * connection. Note: SecureRandom.nextBytes() is thread safe.
- */
- private SecureRandom generator;
-
- /**
- * Unless you know what you are doing, you will never need this.
- *
- * @return The list of supported cipher algorithms by this implementation.
- */
- public static synchronized String[] getAvailableCiphers()
- {
- return BlockCipherFactory.getDefaultCipherList();
- }
-
- /**
- * Unless you know what you are doing, you will never need this.
- *
- * @return The list of supported MAC algorthims by this implementation.
- */
- public static synchronized String[] getAvailableMACs()
- {
- return MAC.getMacList();
- }
-
- /**
- * Unless you know what you are doing, you will never need this.
- *
- * @return The list of supported server host key algorthims by this
- * implementation.
- */
- public static synchronized String[] getAvailableServerHostKeyAlgorithms()
- {
- return KexManager.getDefaultServerHostkeyAlgorithmList();
- }
-
- private AuthenticationManager am;
-
- private boolean authenticated = false;
- private boolean compression = false;
- private ChannelManager cm;
-
- private CryptoWishList cryptoWishList = new CryptoWishList();
-
- private DHGexParameters dhgexpara = new DHGexParameters();
-
- private final String hostname;
-
- private final int port;
-
- private TransportManager tm;
-
- private boolean tcpNoDelay = false;
-
- private ProxyData proxyData = null;
-
- private Vector<ConnectionMonitor> connectionMonitors = new Vector<ConnectionMonitor>();
-
- /**
- * Prepares a fresh <code>Connection</code> object which can then be used
- * to establish a connection to the specified SSH-2 server.
- * <p>
- * Same as {@link #Connection(String, int) Connection(hostname, 22)}.
- *
- * @param hostname
- * the hostname of the SSH-2 server.
- */
- public Connection(String hostname)
- {
- this(hostname, 22);
- }
-
- /**
- * Prepares a fresh <code>Connection</code> object which can then be used
- * to establish a connection to the specified SSH-2 server.
- *
- * @param hostname
- * the host where we later want to connect to.
- * @param port
- * port on the server, normally 22.
- */
- public Connection(String hostname, int port)
- {
- this.hostname = hostname;
- this.port = port;
- }
-
- /**
- * After a successful connect, one has to authenticate oneself. This method
- * is based on DSA (it uses DSA to sign a challenge sent by the server).
- * <p>
- * If the authentication phase is complete, <code>true</code> will be
- * returned. If the server does not accept the request (or if further
- * authentication steps are needed), <code>false</code> is returned and
- * one can retry either by using this or any other authentication method
- * (use the <code>getRemainingAuthMethods</code> method to get a list of
- * the remaining possible methods).
- *
- * @param user
- * A <code>String</code> holding the username.
- * @param pem
- * A <code>String</code> containing the DSA private key of the
- * user in OpenSSH key format (PEM, you can't miss the
- * "-----BEGIN DSA PRIVATE KEY-----" tag). The string may contain
- * linefeeds.
- * @param password
- * If the PEM string is 3DES encrypted ("DES-EDE3-CBC"), then you
- * must specify the password. Otherwise, this argument will be
- * ignored and can be set to <code>null</code>.
- *
- * @return whether the connection is now authenticated.
- * @throws IOException
- *
- * @deprecated You should use one of the
- * {@link #authenticateWithPublicKey(String, File, String) authenticateWithPublicKey()}
- * methods, this method is just a wrapper for it and will
- * disappear in future builds.
- *
- */
- public synchronized boolean authenticateWithDSA(String user, String pem, String password) throws IOException
- {
- if (tm == null)
- throw new IllegalStateException("Connection is not established!");
-
- if (authenticated)
- throw new IllegalStateException("Connection is already authenticated!");
-
- if (am == null)
- am = new AuthenticationManager(tm);
-
- if (cm == null)
- cm = new ChannelManager(tm);
-
- if (user == null)
- throw new IllegalArgumentException("user argument is null");
-
- if (pem == null)
- throw new IllegalArgumentException("pem argument is null");
-
- authenticated = am.authenticatePublicKey(user, pem.toCharArray(), password, getOrCreateSecureRND());
-
- return authenticated;
- }
-
- /**
- * A wrapper that calls
- * {@link #authenticateWithKeyboardInteractive(String, String[], InteractiveCallback)
- * authenticateWithKeyboardInteractivewith} a <code>null</code> submethod
- * list.
- *
- * @param user
- * A <code>String</code> holding the username.
- * @param cb
- * An <code>InteractiveCallback</code> which will be used to
- * determine the responses to the questions asked by the server.
- * @return whether the connection is now authenticated.
- * @throws IOException
- */
- public synchronized boolean authenticateWithKeyboardInteractive(String user, InteractiveCallback cb)
- throws IOException
- {
- return authenticateWithKeyboardInteractive(user, null, cb);
- }
-
- /**
- * After a successful connect, one has to authenticate oneself. This method
- * is based on "keyboard-interactive", specified in
- * draft-ietf-secsh-auth-kbdinteract-XX. Basically, you have to define a
- * callback object which will be feeded with challenges generated by the
- * server. Answers are then sent back to the server. It is possible that the
- * callback will be called several times during the invocation of this
- * method (e.g., if the server replies to the callback's answer(s) with
- * another challenge...)
- * <p>
- * If the authentication phase is complete, <code>true</code> will be
- * returned. If the server does not accept the request (or if further
- * authentication steps are needed), <code>false</code> is returned and
- * one can retry either by using this or any other authentication method
- * (use the <code>getRemainingAuthMethods</code> method to get a list of
- * the remaining possible methods).
- * <p>
- * Note: some SSH servers advertise "keyboard-interactive", however, any
- * interactive request will be denied (without having sent any challenge to
- * the client).
- *
- * @param user
- * A <code>String</code> holding the username.
- * @param submethods
- * An array of submethod names, see
- * draft-ietf-secsh-auth-kbdinteract-XX. May be <code>null</code>
- * to indicate an empty list.
- * @param cb
- * An <code>InteractiveCallback</code> which will be used to
- * determine the responses to the questions asked by the server.
- *
- * @return whether the connection is now authenticated.
- * @throws IOException
- */
- public synchronized boolean authenticateWithKeyboardInteractive(String user, String[] submethods,
- InteractiveCallback cb) throws IOException
- {
- if (cb == null)
- throw new IllegalArgumentException("Callback may not ne NULL!");
-
- if (tm == null)
- throw new IllegalStateException("Connection is not established!");
-
- if (authenticated)
- throw new IllegalStateException("Connection is already authenticated!");
-
- if (am == null)
- am = new AuthenticationManager(tm);
-
- if (cm == null)
- cm = new ChannelManager(tm);
-
- if (user == null)
- throw new IllegalArgumentException("user argument is null");
-
- authenticated = am.authenticateInteractive(user, submethods, cb);
-
- return authenticated;
- }
-
- /**
- * After a successful connect, one has to authenticate oneself. This method
- * sends username and password to the server.
- * <p>
- * If the authentication phase is complete, <code>true</code> will be
- * returned. If the server does not accept the request (or if further
- * authentication steps are needed), <code>false</code> is returned and
- * one can retry either by using this or any other authentication method
- * (use the <code>getRemainingAuthMethods</code> method to get a list of
- * the remaining possible methods).
- * <p>
- * Note: if this method fails, then please double-check that it is actually
- * offered by the server (use
- * {@link #getRemainingAuthMethods(String) getRemainingAuthMethods()}.
- * <p>
- * Often, password authentication is disabled, but users are not aware of
- * it. Many servers only offer "publickey" and "keyboard-interactive".
- * However, even though "keyboard-interactive" *feels* like password
- * authentication (e.g., when using the putty or openssh clients) it is
- * *not* the same mechanism.
- *
- * @param user
- * @param password
- * @return if the connection is now authenticated.
- * @throws IOException
- */
- public synchronized boolean authenticateWithPassword(String user, String password) throws IOException
- {
- if (tm == null)
- throw new IllegalStateException("Connection is not established!");
-
- if (authenticated)
- throw new IllegalStateException("Connection is already authenticated!");
-
- if (am == null)
- am = new AuthenticationManager(tm);
-
- if (cm == null)
- cm = new ChannelManager(tm);
-
- if (user == null)
- throw new IllegalArgumentException("user argument is null");
-
- if (password == null)
- throw new IllegalArgumentException("password argument is null");
-
- authenticated = am.authenticatePassword(user, password);
-
- return authenticated;
- }
-
- /**
- * After a successful connect, one has to authenticate oneself. This method
- * can be used to explicitly use the special "none" authentication method
- * (where only a username has to be specified).
- * <p>
- * Note 1: The "none" method may always be tried by clients, however as by
- * the specs, the server will not explicitly announce it. In other words,
- * the "none" token will never show up in the list returned by
- * {@link #getRemainingAuthMethods(String)}.
- * <p>
- * Note 2: no matter which one of the authenticateWithXXX() methods you
- * call, the library will always issue exactly one initial "none"
- * authentication request to retrieve the initially allowed list of
- * authentication methods by the server. Please read RFC 4252 for the
- * details.
- * <p>
- * If the authentication phase is complete, <code>true</code> will be
- * returned. If further authentication steps are needed, <code>false</code>
- * is returned and one can retry by any other authentication method (use the
- * <code>getRemainingAuthMethods</code> method to get a list of the
- * remaining possible methods).
- *
- * @param user
- * @return if the connection is now authenticated.
- * @throws IOException
- */
- public synchronized boolean authenticateWithNone(String user) throws IOException
- {
- if (tm == null)
- throw new IllegalStateException("Connection is not established!");
-
- if (authenticated)
- throw new IllegalStateException("Connection is already authenticated!");
-
- if (am == null)
- am = new AuthenticationManager(tm);
-
- if (cm == null)
- cm = new ChannelManager(tm);
-
- if (user == null)
- throw new IllegalArgumentException("user argument is null");
-
- /* Trigger the sending of the PacketUserauthRequestNone packet */
- /* (if not already done) */
-
- authenticated = am.authenticateNone(user);
-
- return authenticated;
- }
-
- /**
- * After a successful connect, one has to authenticate oneself. The
- * authentication method "publickey" works by signing a challenge sent by
- * the server. The signature is either DSA or RSA based - it just depends on
- * the type of private key you specify, either a DSA or RSA private key in
- * PEM format. And yes, this is may seem to be a little confusing, the
- * method is called "publickey" in the SSH-2 protocol specification, however
- * since we need to generate a signature, you actually have to supply a
- * private key =).
- * <p>
- * The private key contained in the PEM file may also be encrypted
- * ("Proc-Type: 4,ENCRYPTED"). The library supports DES-CBC and DES-EDE3-CBC
- * encryption, as well as the more exotic PEM encrpytions AES-128-CBC,
- * AES-192-CBC and AES-256-CBC.
- * <p>
- * If the authentication phase is complete, <code>true</code> will be
- * returned. If the server does not accept the request (or if further
- * authentication steps are needed), <code>false</code> is returned and
- * one can retry either by using this or any other authentication method
- * (use the <code>getRemainingAuthMethods</code> method to get a list of
- * the remaining possible methods).
- * <p>
- * NOTE PUTTY USERS: Event though your key file may start with
- * "-----BEGIN..." it is not in the expected format. You have to convert it
- * to the OpenSSH key format by using the "puttygen" tool (can be downloaded
- * from the Putty website). Simply load your key and then use the
- * "Conversions/Export OpenSSH key" functionality to get a proper PEM file.
- *
- * @param user
- * A <code>String</code> holding the username.
- * @param pemPrivateKey
- * A <code>char[]</code> containing a DSA or RSA private key of
- * the user in OpenSSH key format (PEM, you can't miss the
- * "-----BEGIN DSA PRIVATE KEY-----" or "-----BEGIN RSA PRIVATE
- * KEY-----" tag). The char array may contain
- * linebreaks/linefeeds.
- * @param password
- * If the PEM structure is encrypted ("Proc-Type: 4,ENCRYPTED")
- * then you must specify a password. Otherwise, this argument
- * will be ignored and can be set to <code>null</code>.
- *
- * @return whether the connection is now authenticated.
- * @throws IOException
- */
- public synchronized boolean authenticateWithPublicKey(String user, char[] pemPrivateKey, String password)
- throws IOException
- {
- if (tm == null)
- throw new IllegalStateException("Connection is not established!");
-
- if (authenticated)
- throw new IllegalStateException("Connection is already authenticated!");
-
- if (am == null)
- am = new AuthenticationManager(tm);
-
- if (cm == null)
- cm = new ChannelManager(tm);
-
- if (user == null)
- throw new IllegalArgumentException("user argument is null");
-
- if (pemPrivateKey == null)
- throw new IllegalArgumentException("pemPrivateKey argument is null");
-
- authenticated = am.authenticatePublicKey(user, pemPrivateKey, password, getOrCreateSecureRND());
-
- return authenticated;
- }
-
- /**
- * After a successful connect, one has to authenticate oneself. The
- * authentication method "publickey" works by signing a challenge sent by
- * the server. The signature is either DSA or RSA based - it just depends on
- * the type of private key you specify, either a DSA or RSA private key in
- * PEM format. And yes, this is may seem to be a little confusing, the
- * method is called "publickey" in the SSH-2 protocol specification, however
- * since we need to generate a signature, you actually have to supply a
- * private key =).
- * <p>
- * If the authentication phase is complete, <code>true</code> will be
- * returned. If the server does not accept the request (or if further
- * authentication steps are needed), <code>false</code> is returned and
- * one can retry either by using this or any other authentication method
- * (use the <code>getRemainingAuthMethods</code> method to get a list of
- * the remaining possible methods).
- *
- * @param user
- * A <code>String</code> holding the username.
- * @param key
- * A <code>RSAPrivateKey</code> or <code>DSAPrivateKey</code>
- * containing a DSA or RSA private key of
- * the user in Trilead object format.
- *
- * @return whether the connection is now authenticated.
- * @throws IOException
- */
- public synchronized boolean authenticateWithPublicKey(String user, KeyPair pair)
- throws IOException
- {
- if (tm == null)
- throw new IllegalStateException("Connection is not established!");
-
- if (authenticated)
- throw new IllegalStateException("Connection is already authenticated!");
-
- if (am == null)
- am = new AuthenticationManager(tm);
-
- if (cm == null)
- cm = new ChannelManager(tm);
-
- if (user == null)
- throw new IllegalArgumentException("user argument is null");
-
- if (pair == null)
- throw new IllegalArgumentException("Key pair argument is null");
-
- authenticated = am.authenticatePublicKey(user, pair, getOrCreateSecureRND());
-
- return authenticated;
- }
- /**
- * A convenience wrapper function which reads in a private key (PEM format,
- * either DSA or RSA) and then calls
- * <code>authenticateWithPublicKey(String, char[], String)</code>.
- * <p>
- * NOTE PUTTY USERS: Event though your key file may start with
- * "-----BEGIN..." it is not in the expected format. You have to convert it
- * to the OpenSSH key format by using the "puttygen" tool (can be downloaded
- * from the Putty website). Simply load your key and then use the
- * "Conversions/Export OpenSSH key" functionality to get a proper PEM file.
- *
- * @param user
- * A <code>String</code> holding the username.
- * @param pemFile
- * A <code>File</code> object pointing to a file containing a
- * DSA or RSA private key of the user in OpenSSH key format (PEM,
- * you can't miss the "-----BEGIN DSA PRIVATE KEY-----" or
- * "-----BEGIN RSA PRIVATE KEY-----" tag).
- * @param password
- * If the PEM file is encrypted then you must specify the
- * password. Otherwise, this argument will be ignored and can be
- * set to <code>null</code>.
- *
- * @return whether the connection is now authenticated.
- * @throws IOException
- */
- public synchronized boolean authenticateWithPublicKey(String user, File pemFile, String password)
- throws IOException
- {
- if (pemFile == null)
- throw new IllegalArgumentException("pemFile argument is null");
-
- char[] buff = new char[256];
-
- CharArrayWriter cw = new CharArrayWriter();
-
- FileReader fr = new FileReader(pemFile);
-
- while (true)
- {
- int len = fr.read(buff);
- if (len < 0)
- break;
- cw.write(buff, 0, len);
- }
-
- fr.close();
-
- return authenticateWithPublicKey(user, cw.toCharArray(), password);
- }
-
- /**
- * Add a {@link ConnectionMonitor} to this connection. Can be invoked at any
- * time, but it is best to add connection monitors before invoking
- * <code>connect()</code> to avoid glitches (e.g., you add a connection
- * monitor after a successful connect(), but the connection has died in the
- * mean time. Then, your connection monitor won't be notified.)
- * <p>
- * You can add as many monitors as you like.
- *
- * @see ConnectionMonitor
- *
- * @param cmon
- * An object implementing the <code>ConnectionMonitor</code>
- * interface.
- */
- public synchronized void addConnectionMonitor(ConnectionMonitor cmon)
- {
- if (cmon == null)
- throw new IllegalArgumentException("cmon argument is null");
-
- connectionMonitors.addElement(cmon);
-
- if (tm != null)
- tm.setConnectionMonitors(connectionMonitors);
- }
-
- /**
- * Controls whether compression is used on the link or not.
- * <p>
- * Note: This can only be called before connect()
- * @param enabled whether to enable compression
- * @throws IOException
- */
- public synchronized void setCompression(boolean enabled) throws IOException {
- if (tm != null)
- throw new IOException("Connection to " + hostname + " is already in connected state!");
-
- compression = enabled;
- }
-
- /**
- * Close the connection to the SSH-2 server. All assigned sessions will be
- * closed, too. Can be called at any time. Don't forget to call this once
- * you don't need a connection anymore - otherwise the receiver thread may
- * run forever.
- */
- public synchronized void close()
- {
- Throwable t = new Throwable("Closed due to user request.");
- close(t, false);
- }
-
- private void close(Throwable t, boolean hard)
- {
- if (cm != null)
- cm.closeAllChannels();
-
- if (tm != null)
- {
- tm.close(t, hard == false);
- tm = null;
- }
- am = null;
- cm = null;
- authenticated = false;
- }
-
- /**
- * Same as
- * {@link #connect(ServerHostKeyVerifier, int, int) connect(null, 0, 0)}.
- *
- * @return see comments for the
- * {@link #connect(ServerHostKeyVerifier, int, int) connect(ServerHostKeyVerifier, int, int)}
- * method.
- * @throws IOException
- */
- public synchronized ConnectionInfo connect() throws IOException
- {
- return connect(null, 0, 0);
- }
-
- /**
- * Same as
- * {@link #connect(ServerHostKeyVerifier, int, int) connect(verifier, 0, 0)}.
- *
- * @return see comments for the
- * {@link #connect(ServerHostKeyVerifier, int, int) connect(ServerHostKeyVerifier, int, int)}
- * method.
- * @throws IOException
- */
- public synchronized ConnectionInfo connect(ServerHostKeyVerifier verifier) throws IOException
- {
- return connect(verifier, 0, 0);
- }
-
- /**
- * Connect to the SSH-2 server and, as soon as the server has presented its
- * host key, use the
- * {@link ServerHostKeyVerifier#verifyServerHostKey(String, int, String,
- * byte[]) ServerHostKeyVerifier.verifyServerHostKey()} method of the
- * <code>verifier</code> to ask for permission to proceed. If
- * <code>verifier</code> is <code>null</code>, then any host key will
- * be accepted - this is NOT recommended, since it makes man-in-the-middle
- * attackes VERY easy (somebody could put a proxy SSH server between you and
- * the real server).
- * <p>
- * Note: The verifier will be called before doing any crypto calculations
- * (i.e., diffie-hellman). Therefore, if you don't like the presented host
- * key then no CPU cycles are wasted (and the evil server has less
- * information about us).
- * <p>
- * However, it is still possible that the server presented a fake host key:
- * the server cheated (typically a sign for a man-in-the-middle attack) and
- * is not able to generate a signature that matches its host key. Don't
- * worry, the library will detect such a scenario later when checking the
- * signature (the signature cannot be checked before having completed the
- * diffie-hellman exchange).
- * <p>
- * Note 2: The {@link ServerHostKeyVerifier#verifyServerHostKey(String, int,
- * String, byte[]) ServerHostKeyVerifier.verifyServerHostKey()} method will
- * *NOT* be called from the current thread, the call is being made from a
- * background thread (there is a background dispatcher thread for every
- * established connection).
- * <p>
- * Note 3: This method will block as long as the key exchange of the
- * underlying connection has not been completed (and you have not specified
- * any timeouts).
- * <p>
- * Note 4: If you want to re-use a connection object that was successfully
- * connected, then you must call the {@link #close()} method before invoking
- * <code>connect()</code> again.
- *
- * @param verifier
- * An object that implements the {@link ServerHostKeyVerifier}
- * interface. Pass <code>null</code> to accept any server host
- * key - NOT recommended.
- *
- * @param connectTimeout
- * Connect the underlying TCP socket to the server with the given
- * timeout value (non-negative, in milliseconds). Zero means no
- * timeout. If a proxy is being used (see
- * {@link #setProxyData(ProxyData)}), then this timeout is used
- * for the connection establishment to the proxy.
- *
- * @param kexTimeout
- * Timeout for complete connection establishment (non-negative,
- * in milliseconds). Zero means no timeout. The timeout counts
- * from the moment you invoke the connect() method and is
- * cancelled as soon as the first key-exchange round has
- * finished. It is possible that the timeout event will be fired
- * during the invocation of the <code>verifier</code> callback,
- * but it will only have an effect after the
- * <code>verifier</code> returns.
- *
- * @return A {@link ConnectionInfo} object containing the details of the
- * established connection.
- *
- * @throws IOException
- * If any problem occurs, e.g., the server's host key is not
- * accepted by the <code>verifier</code> or there is problem
- * during the initial crypto setup (e.g., the signature sent by
- * the server is wrong).
- * <p>
- * In case of a timeout (either connectTimeout or kexTimeout) a
- * SocketTimeoutException is thrown.
- * <p>
- * An exception may also be thrown if the connection was already
- * successfully connected (no matter if the connection broke in
- * the mean time) and you invoke <code>connect()</code> again
- * without having called {@link #close()} first.
- * <p>
- * If a HTTP proxy is being used and the proxy refuses the
- * connection, then a {@link HTTPProxyException} may be thrown,
- * which contains the details returned by the proxy. If the
- * proxy is buggy and does not return a proper HTTP response,
- * then a normal IOException is thrown instead.
- */
- public synchronized ConnectionInfo connect(ServerHostKeyVerifier verifier, int connectTimeout, int kexTimeout)
- throws IOException
- {
- final class TimeoutState
- {
- boolean isCancelled = false;
- boolean timeoutSocketClosed = false;
- }
-
- if (tm != null)
- throw new IOException("Connection to " + hostname + " is already in connected state!");
-
- if (connectTimeout < 0)
- throw new IllegalArgumentException("connectTimeout must be non-negative!");
-
- if (kexTimeout < 0)
- throw new IllegalArgumentException("kexTimeout must be non-negative!");
-
- final TimeoutState state = new TimeoutState();
-
- tm = new TransportManager(hostname, port);
-
- tm.setConnectionMonitors(connectionMonitors);
-
- // Don't offer compression if not requested
- if (!compression) {
- cryptoWishList.c2s_comp_algos = new String[] { "none" };
- cryptoWishList.s2c_comp_algos = new String[] { "none" };
- }
-
- /*
- * Make sure that the runnable below will observe the new value of "tm"
- * and "state" (the runnable will be executed in a different thread,
- * which may be already running, that is why we need a memory barrier
- * here). See also the comment in Channel.java if you are interested in
- * the details.
- *
- * OKOK, this is paranoid since adding the runnable to the todo list of
- * the TimeoutService will ensure that all writes have been flushed
- * before the Runnable reads anything (there is a synchronized block in
- * TimeoutService.addTimeoutHandler).
- */
-
- synchronized (tm)
- {
- /* We could actually synchronize on anything. */
- }
-
- try
- {
- TimeoutToken token = null;
-
- if (kexTimeout > 0)
- {
- final Runnable timeoutHandler = new Runnable()
- {
- public void run()
- {
- synchronized (state)
- {
- if (state.isCancelled)
- return;
- state.timeoutSocketClosed = true;
- tm.close(new SocketTimeoutException("The connect timeout expired"), false);
- }
- }
- };
-
- long timeoutHorizont = System.currentTimeMillis() + kexTimeout;
-
- token = TimeoutService.addTimeoutHandler(timeoutHorizont, timeoutHandler);
- }
-
- try
- {
- tm.initialize(cryptoWishList, verifier, dhgexpara, connectTimeout, getOrCreateSecureRND(), proxyData);
- }
- catch (SocketTimeoutException se)
- {
- throw (SocketTimeoutException) new SocketTimeoutException(
- "The connect() operation on the socket timed out.").initCause(se);
- }
-
- tm.setTcpNoDelay(tcpNoDelay);
-
- /* Wait until first KEX has finished */
-
- ConnectionInfo ci = tm.getConnectionInfo(1);
-
- /* Now try to cancel the timeout, if needed */
-
- if (token != null)
- {
- TimeoutService.cancelTimeoutHandler(token);
-
- /* Were we too late? */
-
- synchronized (state)
- {
- if (state.timeoutSocketClosed)
- throw new IOException("This exception will be replaced by the one below =)");
- /*
- * Just in case the "cancelTimeoutHandler" invocation came
- * just a little bit too late but the handler did not enter
- * the semaphore yet - we can still stop it.
- */
- state.isCancelled = true;
- }
- }
-
- return ci;
- }
- catch (SocketTimeoutException ste)
- {
- throw ste;
- }
- catch (IOException e1)
- {
- /* This will also invoke any registered connection monitors */
- close(new Throwable("There was a problem during connect."), false);
-
- synchronized (state)
- {
- /*
- * Show a clean exception, not something like "the socket is
- * closed!?!"
- */
- if (state.timeoutSocketClosed)
- throw new SocketTimeoutException("The kexTimeout (" + kexTimeout + " ms) expired.");
- }
-
- /* Do not wrap a HTTPProxyException */
- if (e1 instanceof HTTPProxyException)
- throw e1;
-
- throw (IOException) new IOException("There was a problem while connecting to " + hostname + ":" + port)
- .initCause(e1);
- }
- }
-
- /**
- * Creates a new {@link LocalPortForwarder}. A
- * <code>LocalPortForwarder</code> forwards TCP/IP connections that arrive
- * at a local port via the secure tunnel to another host (which may or may
- * not be identical to the remote SSH-2 server).
- * <p>
- * This method must only be called after one has passed successfully the
- * authentication step. There is no limit on the number of concurrent
- * forwardings.
- *
- * @param local_port
- * the local port the LocalPortForwarder shall bind to.
- * @param host_to_connect
- * target address (IP or hostname)
- * @param port_to_connect
- * target port
- * @return A {@link LocalPortForwarder} object.
- * @throws IOException
- */
- public synchronized LocalPortForwarder createLocalPortForwarder(int local_port, String host_to_connect,
- int port_to_connect) throws IOException
- {
- if (tm == null)
- throw new IllegalStateException("Cannot forward ports, you need to establish a connection first.");
-
- if (!authenticated)
- throw new IllegalStateException("Cannot forward ports, connection is not authenticated.");
-
- return new LocalPortForwarder(cm, local_port, host_to_connect, port_to_connect);
- }
-
- /**
- * Creates a new {@link LocalPortForwarder}. A
- * <code>LocalPortForwarder</code> forwards TCP/IP connections that arrive
- * at a local port via the secure tunnel to another host (which may or may
- * not be identical to the remote SSH-2 server).
- * <p>
- * This method must only be called after one has passed successfully the
- * authentication step. There is no limit on the number of concurrent
- * forwardings.
- *
- * @param addr
- * specifies the InetSocketAddress where the local socket shall
- * be bound to.
- * @param host_to_connect
- * target address (IP or hostname)
- * @param port_to_connect
- * target port
- * @return A {@link LocalPortForwarder} object.
- * @throws IOException
- */
- public synchronized LocalPortForwarder createLocalPortForwarder(InetSocketAddress addr, String host_to_connect,
- int port_to_connect) throws IOException
- {
- if (tm == null)
- throw new IllegalStateException("Cannot forward ports, you need to establish a connection first.");
-
- if (!authenticated)
- throw new IllegalStateException("Cannot forward ports, connection is not authenticated.");
-
- return new LocalPortForwarder(cm, addr, host_to_connect, port_to_connect);
- }
-
- /**
- * Creates a new {@link LocalStreamForwarder}. A
- * <code>LocalStreamForwarder</code> manages an Input/Outputstream pair
- * that is being forwarded via the secure tunnel into a TCP/IP connection to
- * another host (which may or may not be identical to the remote SSH-2
- * server).
- *
- * @param host_to_connect
- * @param port_to_connect
- * @return A {@link LocalStreamForwarder} object.
- * @throws IOException
- */
- public synchronized LocalStreamForwarder createLocalStreamForwarder(String host_to_connect, int port_to_connect)
- throws IOException
- {
- if (tm == null)
- throw new IllegalStateException("Cannot forward, you need to establish a connection first.");
-
- if (!authenticated)
- throw new IllegalStateException("Cannot forward, connection is not authenticated.");
-
- return new LocalStreamForwarder(cm, host_to_connect, port_to_connect);
- }
-
- /**
- * Creates a new {@link DynamicPortForwarder}. A
- * <code>DynamicPortForwarder</code> forwards TCP/IP connections that arrive
- * at a local port via the secure tunnel to another host that is chosen via
- * the SOCKS protocol.
- * <p>
- * This method must only be called after one has passed successfully the
- * authentication step. There is no limit on the number of concurrent
- * forwardings.
- *
- * @param local_port
- * @return A {@link DynamicPortForwarder} object.
- * @throws IOException
- */
- public synchronized DynamicPortForwarder createDynamicPortForwarder(int local_port) throws IOException
- {
- if (tm == null)
- throw new IllegalStateException("Cannot forward ports, you need to establish a connection first.");
-
- if (!authenticated)
- throw new IllegalStateException("Cannot forward ports, connection is not authenticated.");
-
- return new DynamicPortForwarder(cm, local_port);
- }
-
- /**
- * Creates a new {@link DynamicPortForwarder}. A
- * <code>DynamicPortForwarder</code> forwards TCP/IP connections that arrive
- * at a local port via the secure tunnel to another host that is chosen via
- * the SOCKS protocol.
- * <p>
- * This method must only be called after one has passed successfully the
- * authentication step. There is no limit on the number of concurrent
- * forwardings.
- *
- * @param addr
- * specifies the InetSocketAddress where the local socket shall
- * be bound to.
- * @return A {@link DynamicPortForwarder} object.
- * @throws IOException
- */
- public synchronized DynamicPortForwarder createDynamicPortForwarder(InetSocketAddress addr) throws IOException
- {
- if (tm == null)
- throw new IllegalStateException("Cannot forward ports, you need to establish a connection first.");
-
- if (!authenticated)
- throw new IllegalStateException("Cannot forward ports, connection is not authenticated.");
-
- return new DynamicPortForwarder(cm, addr);
- }
-
- /**
- * Create a very basic {@link SCPClient} that can be used to copy files
- * from/to the SSH-2 server.
- * <p>
- * Works only after one has passed successfully the authentication step.
- * There is no limit on the number of concurrent SCP clients.
- * <p>
- * Note: This factory method will probably disappear in the future.
- *
- * @return A {@link SCPClient} object.
- * @throws IOException
- */
- public synchronized SCPClient createSCPClient() throws IOException
- {
- if (tm == null)
- throw new IllegalStateException("Cannot create SCP client, you need to establish a connection first.");
-
- if (!authenticated)
- throw new IllegalStateException("Cannot create SCP client, connection is not authenticated.");
-
- return new SCPClient(this);
- }
-
- /**
- * Force an asynchronous key re-exchange (the call does not block). The
- * latest values set for MAC, Cipher and DH group exchange parameters will
- * be used. If a key exchange is currently in progress, then this method has
- * the only effect that the so far specified parameters will be used for the
- * next (server driven) key exchange.
- * <p>
- * Note: This implementation will never start a key exchange (other than the
- * initial one) unless you or the SSH-2 server ask for it.
- *
- * @throws IOException
- * In case of any failure behind the scenes.
- */
- public synchronized void forceKeyExchange() throws IOException
- {
- if (tm == null)
- throw new IllegalStateException("You need to establish a connection first.");
-
- tm.forceKeyExchange(cryptoWishList, dhgexpara);
- }
-
- /**
- * Returns the hostname that was passed to the constructor.
- *
- * @return the hostname
- */
- public synchronized String getHostname()
- {
- return hostname;
- }
-
- /**
- * Returns the port that was passed to the constructor.
- *
- * @return the TCP port
- */
- public synchronized int getPort()
- {
- return port;
- }
-
- /**
- * Returns a {@link ConnectionInfo} object containing the details of the
- * connection. Can be called as soon as the connection has been established
- * (successfully connected).
- *
- * @return A {@link ConnectionInfo} object.
- * @throws IOException
- * In case of any failure behind the scenes.
- */
- public synchronized ConnectionInfo getConnectionInfo() throws IOException
- {
- if (tm == null)
- throw new IllegalStateException(
- "Cannot get details of connection, you need to establish a connection first.");
- return tm.getConnectionInfo(1);
- }
-
- /**
- * After a successful connect, one has to authenticate oneself. This method
- * can be used to tell which authentication methods are supported by the
- * server at a certain stage of the authentication process (for the given
- * username).
- * <p>
- * Note 1: the username will only be used if no authentication step was done
- * so far (it will be used to ask the server for a list of possible
- * authentication methods by sending the initial "none" request). Otherwise,
- * this method ignores the user name and returns a cached method list (which
- * is based on the information contained in the last negative server
- * response).
- * <p>
- * Note 2: the server may return method names that are not supported by this
- * implementation.
- * <p>
- * After a successful authentication, this method must not be called
- * anymore.
- *
- * @param user
- * A <code>String</code> holding the username.
- *
- * @return a (possibly emtpy) array holding authentication method names.
- * @throws IOException
- */
- public synchronized String[] getRemainingAuthMethods(String user) throws IOException
- {
- if (user == null)
- throw new IllegalArgumentException("user argument may not be NULL!");
-
- if (tm == null)
- throw new IllegalStateException("Connection is not established!");
-
- if (authenticated)
- throw new IllegalStateException("Connection is already authenticated!");
-
- if (am == null)
- am = new AuthenticationManager(tm);
-
- if (cm == null)
- cm = new ChannelManager(tm);
-
- return am.getRemainingMethods(user);
- }
-
- /**
- * Determines if the authentication phase is complete. Can be called at any
- * time.
- *
- * @return <code>true</code> if no further authentication steps are
- * needed.
- */
- public synchronized boolean isAuthenticationComplete()
- {
- return authenticated;
- }
-
- /**
- * Returns true if there was at least one failed authentication request and
- * the last failed authentication request was marked with "partial success"
- * by the server. This is only needed in the rare case of SSH-2 server
- * setups that cannot be satisfied with a single successful authentication
- * request (i.e., multiple authentication steps are needed.)
- * <p>
- * If you are interested in the details, then have a look at RFC4252.
- *
- * @return if the there was a failed authentication step and the last one
- * was marked as a "partial success".
- */
- public synchronized boolean isAuthenticationPartialSuccess()
- {
- if (am == null)
- return false;
-
- return am.getPartialSuccess();
- }
-
- /**
- * Checks if a specified authentication method is available. This method is
- * actually just a wrapper for {@link #getRemainingAuthMethods(String)
- * getRemainingAuthMethods()}.
- *
- * @param user
- * A <code>String</code> holding the username.
- * @param method
- * An authentication method name (e.g., "publickey", "password",
- * "keyboard-interactive") as specified by the SSH-2 standard.
- * @return if the specified authentication method is currently available.
- * @throws IOException
- */
- public synchronized boolean isAuthMethodAvailable(String user, String method) throws IOException
- {
- if (method == null)
- throw new IllegalArgumentException("method argument may not be NULL!");
-
- String methods[] = getRemainingAuthMethods(user);
-
- for (int i = 0; i < methods.length; i++)
- {
- if (methods[i].compareTo(method) == 0)
- return true;
- }
-
- return false;
- }
-
- private final SecureRandom getOrCreateSecureRND()
- {
- if (generator == null)
- generator = new SecureRandom();
-
- return generator;
- }
-
- /**
- * Open a new {@link Session} on this connection. Works only after one has
- * passed successfully the authentication step. There is no limit on the
- * number of concurrent sessions.
- *
- * @return A {@link Session} object.
- * @throws IOException
- */
- public synchronized Session openSession() throws IOException
- {
- if (tm == null)
- throw new IllegalStateException("Cannot open session, you need to establish a connection first.");
-
- if (!authenticated)
- throw new IllegalStateException("Cannot open session, connection is not authenticated.");
-
- return new Session(cm, getOrCreateSecureRND());
- }
-
- /**
- * Send an SSH_MSG_IGNORE packet. This method will generate a random data
- * attribute (length between 0 (invlusive) and 16 (exclusive) bytes,
- * contents are random bytes).
- * <p>
- * This method must only be called once the connection is established.
- *
- * @throws IOException
- */
- public synchronized void sendIgnorePacket() throws IOException
- {
- SecureRandom rnd = getOrCreateSecureRND();
-
- byte[] data = new byte[rnd.nextInt(16)];
- rnd.nextBytes(data);
-
- sendIgnorePacket(data);
- }
-
- /**
- * Send an SSH_MSG_IGNORE packet with the given data attribute.
- * <p>
- * This method must only be called once the connection is established.
- *
- * @throws IOException
- */
- public synchronized void sendIgnorePacket(byte[] data) throws IOException
- {
- if (data == null)
- throw new IllegalArgumentException("data argument must not be null.");
-
- if (tm == null)
- throw new IllegalStateException(
- "Cannot send SSH_MSG_IGNORE packet, you need to establish a connection first.");
-
- PacketIgnore pi = new PacketIgnore();
- pi.setData(data);
-
- tm.sendMessage(pi.getPayload());
- }
-
- /**
- * Removes duplicates from a String array, keeps only first occurence of
- * each element. Does not destroy order of elements; can handle nulls. Uses
- * a very efficient O(N^2) algorithm =)
- *
- * @param list
- * a String array.
- * @return a cleaned String array.
- */
- private String[] removeDuplicates(String[] list)
- {
- if ((list == null) || (list.length < 2))
- return list;
-
- String[] list2 = new String[list.length];
-
- int count = 0;
-
- for (int i = 0; i < list.length; i++)
- {
- boolean duplicate = false;
-
- String element = list[i];
-
- for (int j = 0; j < count; j++)
- {
- if (((element == null) && (list2[j] == null)) || ((element != null) && (element.equals(list2[j]))))
- {
- duplicate = true;
- break;
- }
- }
-
- if (duplicate)
- continue;
-
- list2[count++] = list[i];
- }
-
- if (count == list2.length)
- return list2;
-
- String[] tmp = new String[count];
- System.arraycopy(list2, 0, tmp, 0, count);
-
- return tmp;
- }
-
- /**
- * Unless you know what you are doing, you will never need this.
- *
- * @param ciphers
- */
- public synchronized void setClient2ServerCiphers(String[] ciphers)
- {
- if ((ciphers == null) || (ciphers.length == 0))
- throw new IllegalArgumentException();
- ciphers = removeDuplicates(ciphers);
- BlockCipherFactory.checkCipherList(ciphers);
- cryptoWishList.c2s_enc_algos = ciphers;
- }
-
- /**
- * Unless you know what you are doing, you will never need this.
- *
- * @param macs
- */
- public synchronized void setClient2ServerMACs(String[] macs)
- {
- if ((macs == null) || (macs.length == 0))
- throw new IllegalArgumentException();
- macs = removeDuplicates(macs);
- MAC.checkMacList(macs);
- cryptoWishList.c2s_mac_algos = macs;
- }
-
- /**
- * Sets the parameters for the diffie-hellman group exchange. Unless you
- * know what you are doing, you will never need this. Default values are
- * defined in the {@link DHGexParameters} class.
- *
- * @param dgp
- * {@link DHGexParameters}, non null.
- *
- */
- public synchronized void setDHGexParameters(DHGexParameters dgp)
- {
- if (dgp == null)
- throw new IllegalArgumentException();
-
- dhgexpara = dgp;
- }
-
- /**
- * Unless you know what you are doing, you will never need this.
- *
- * @param ciphers
- */
- public synchronized void setServer2ClientCiphers(String[] ciphers)
- {
- if ((ciphers == null) || (ciphers.length == 0))
- throw new IllegalArgumentException();
- ciphers = removeDuplicates(ciphers);
- BlockCipherFactory.checkCipherList(ciphers);
- cryptoWishList.s2c_enc_algos = ciphers;
- }
-
- /**
- * Unless you know what you are doing, you will never need this.
- *
- * @param macs
- */
- public synchronized void setServer2ClientMACs(String[] macs)
- {
- if ((macs == null) || (macs.length == 0))
- throw new IllegalArgumentException();
-
- macs = removeDuplicates(macs);
- MAC.checkMacList(macs);
- cryptoWishList.s2c_mac_algos = macs;
- }
-
- /**
- * Define the set of allowed server host key algorithms to be used for the
- * following key exchange operations.
- * <p>
- * Unless you know what you are doing, you will never need this.
- *
- * @param algos
- * An array of allowed server host key algorithms. SSH-2 defines
- * <code>ssh-dss</code> and <code>ssh-rsa</code>. The
- * entries of the array must be ordered after preference, i.e.,
- * the entry at index 0 is the most preferred one. You must
- * specify at least one entry.
- */
- public synchronized void setServerHostKeyAlgorithms(String[] algos)
- {
- if ((algos == null) || (algos.length == 0))
- throw new IllegalArgumentException();
-
- algos = removeDuplicates(algos);
- KexManager.checkServerHostkeyAlgorithmsList(algos);
- cryptoWishList.serverHostKeyAlgorithms = algos;
- }
-
- /**
- * Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm) on the
- * underlying socket.
- * <p>
- * Can be called at any time. If the connection has not yet been established
- * then the passed value will be stored and set after the socket has been
- * set up. The default value that will be used is <code>false</code>.
- *
- * @param enable
- * the argument passed to the <code>Socket.setTCPNoDelay()</code>
- * method.
- * @throws IOException
- */
- public synchronized void setTCPNoDelay(boolean enable) throws IOException
- {
- tcpNoDelay = enable;
-
- if (tm != null)
- tm.setTcpNoDelay(enable);
- }
-
- /**
- * Used to tell the library that the connection shall be established through
- * a proxy server. It only makes sense to call this method before calling
- * the {@link #connect() connect()} method.
- * <p>
- * At the moment, only HTTP proxies are supported.
- * <p>
- * Note: This method can be called any number of times. The
- * {@link #connect() connect()} method will use the value set in the last
- * preceding invocation of this method.
- *
- * @see HTTPProxyData
- *
- * @param proxyData
- * Connection information about the proxy. If <code>null</code>,
- * then no proxy will be used (non surprisingly, this is also the
- * default).
- */
- public synchronized void setProxyData(ProxyData proxyData)
- {
- this.proxyData = proxyData;
- }
-
- /**
- * Request a remote port forwarding. If successful, then forwarded
- * connections will be redirected to the given target address. You can
- * cancle a requested remote port forwarding by calling
- * {@link #cancelRemotePortForwarding(int) cancelRemotePortForwarding()}.
- * <p>
- * A call of this method will block until the peer either agreed or
- * disagreed to your request-
- * <p>
- * Note 1: this method typically fails if you
- * <ul>
- * <li>pass a port number for which the used remote user has not enough
- * permissions (i.e., port &lt; 1024)</li>
- * <li>or pass a port number that is already in use on the remote server</li>
- * <li>or if remote port forwarding is disabled on the server.</li>
- * </ul>
- * <p>
- * Note 2: (from the openssh man page): By default, the listening socket on
- * the server will be bound to the loopback interface only. This may be
- * overriden by specifying a bind address. Specifying a remote bind address
- * will only succeed if the server's <b>GatewayPorts</b> option is enabled
- * (see sshd_config(5)).
- *
- * @param bindAddress
- * address to bind to on the server:
- * <ul>
- * <li>"" means that connections are to be accepted on all
- * protocol families supported by the SSH implementation</li>
- * <li>"0.0.0.0" means to listen on all IPv4 addresses</li>
- * <li>"::" means to listen on all IPv6 addresses</li>
- * <li>"localhost" means to listen on all protocol families
- * supported by the SSH implementation on loopback addresses
- * only, [RFC3330] and RFC3513]</li>
- * <li>"127.0.0.1" and "::1" indicate listening on the loopback
- * interfaces for IPv4 and IPv6 respectively</li>
- * </ul>
- * @param bindPort
- * port number to bind on the server (must be &gt; 0)
- * @param targetAddress
- * the target address (IP or hostname)
- * @param targetPort
- * the target port
- * @throws IOException
- */
- public synchronized void requestRemotePortForwarding(String bindAddress, int bindPort, String targetAddress,
- int targetPort) throws IOException
- {
- if (tm == null)
- throw new IllegalStateException("You need to establish a connection first.");
-
- if (!authenticated)
- throw new IllegalStateException("The connection is not authenticated.");
-
- if ((bindAddress == null) || (targetAddress == null) || (bindPort <= 0) || (targetPort <= 0))
- throw new IllegalArgumentException();
-
- cm.requestGlobalForward(bindAddress, bindPort, targetAddress, targetPort);
- }
-
- /**
- * Cancel an earlier requested remote port forwarding. Currently active
- * forwardings will not be affected (e.g., disrupted). Note that further
- * connection forwarding requests may be received until this method has
- * returned.
- *
- * @param bindPort
- * the allocated port number on the server
- * @throws IOException
- * if the remote side refuses the cancel request or another low
- * level error occurs (e.g., the underlying connection is
- * closed)
- */
- public synchronized void cancelRemotePortForwarding(int bindPort) throws IOException
- {
- if (tm == null)
- throw new IllegalStateException("You need to establish a connection first.");
-
- if (!authenticated)
- throw new IllegalStateException("The connection is not authenticated.");
-
- cm.requestCancelGlobalForward(bindPort);
- }
-
- /**
- * Provide your own instance of SecureRandom. Can be used, e.g., if you want
- * to seed the used SecureRandom generator manually.
- * <p>
- * The SecureRandom instance is used during key exchanges, public key
- * authentication, x11 cookie generation and the like.
- *
- * @param rnd
- * a SecureRandom instance
- */
- public synchronized void setSecureRandom(SecureRandom rnd)
- {
- if (rnd == null)
- throw new IllegalArgumentException();
-
- this.generator = rnd;
- }
-
- /**
- * Enable/disable debug logging. <b>Only do this when requested by Trilead
- * support.</b>
- * <p>
- * For speed reasons, some static variables used to check whether debugging
- * is enabled are not protected with locks. In other words, if you
- * dynamicaly enable/disable debug logging, then some threads may still use
- * the old setting. To be on the safe side, enable debugging before doing
- * the <code>connect()</code> call.
- *
- * @param enable
- * on/off
- * @param logger
- * a {@link DebugLogger DebugLogger} instance, <code>null</code>
- * means logging using the simple logger which logs all messages
- * to to stderr. Ignored if enabled is <code>false</code>
- */
- public synchronized void enableDebugging(boolean enable, DebugLogger logger)
- {
- Logger.enabled = enable;
-
- if (enable == false)
- {
- Logger.logger = null;
- }
- else
- {
- if (logger == null)
- {
- logger = new DebugLogger()
- {
-
- public void log(int level, String className, String message)
- {
- long now = System.currentTimeMillis();
- System.err.println(now + " : " + className + ": " + message);
- }
- };
- }
-
- Logger.logger = logger;
- }
- }
-
- /**
- * This method can be used to perform end-to-end connection testing. It
- * sends a 'ping' message to the server and waits for the 'pong' from the
- * server.
- * <p>
- * When this method throws an exception, then you can assume that the
- * connection should be abandoned.
- * <p>
- * Note: Works only after one has passed successfully the authentication
- * step.
- * <p>
- * Implementation details: this method sends a SSH_MSG_GLOBAL_REQUEST
- * request ('trilead-ping') to the server and waits for the
- * SSH_MSG_REQUEST_FAILURE reply packet from the server.
- *
- * @throws IOException
- * in case of any problem
- */
- public synchronized void ping() throws IOException
- {
- if (tm == null)
- throw new IllegalStateException("You need to establish a connection first.");
-
- if (!authenticated)
- throw new IllegalStateException("The connection is not authenticated.");
-
- cm.requestGlobalTrileadPing();
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/ConnectionInfo.java b/app/src/main/java/com/trilead/ssh2/ConnectionInfo.java
deleted file mode 100644
index b0ddbcf..0000000
--- a/app/src/main/java/com/trilead/ssh2/ConnectionInfo.java
+++ /dev/null
@@ -1,53 +0,0 @@
-
-package com.trilead.ssh2;
-
-/**
- * In most cases you probably do not need the information contained in here.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: ConnectionInfo.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public class ConnectionInfo
-{
- /**
- * The used key exchange (KEX) algorithm in the latest key exchange.
- */
- public String keyExchangeAlgorithm;
-
- /**
- * The currently used crypto algorithm for packets from to the client to the
- * server.
- */
- public String clientToServerCryptoAlgorithm;
- /**
- * The currently used crypto algorithm for packets from to the server to the
- * client.
- */
- public String serverToClientCryptoAlgorithm;
-
- /**
- * The currently used MAC algorithm for packets from to the client to the
- * server.
- */
- public String clientToServerMACAlgorithm;
- /**
- * The currently used MAC algorithm for packets from to the server to the
- * client.
- */
- public String serverToClientMACAlgorithm;
-
- /**
- * The type of the server host key (currently either "ssh-dss" or
- * "ssh-rsa").
- */
- public String serverHostKeyAlgorithm;
- /**
- * The server host key that was sent during the latest key exchange.
- */
- public byte[] serverHostKey;
-
- /**
- * Number of kex exchanges performed on this connection so far.
- */
- public int keyExchangeCounter = 0;
-}
diff --git a/app/src/main/java/com/trilead/ssh2/ConnectionMonitor.java b/app/src/main/java/com/trilead/ssh2/ConnectionMonitor.java
deleted file mode 100644
index 2f96d25..0000000
--- a/app/src/main/java/com/trilead/ssh2/ConnectionMonitor.java
+++ /dev/null
@@ -1,34 +0,0 @@
-
-package com.trilead.ssh2;
-
-/**
- * A <code>ConnectionMonitor</code> is used to get notified when the
- * underlying socket of a connection is closed.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: ConnectionMonitor.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-
-public interface ConnectionMonitor
-{
- /**
- * This method is called after the connection's underlying
- * socket has been closed. E.g., due to the {@link Connection#close()} request of the
- * user, if the peer closed the connection, due to a fatal error during connect()
- * (also if the socket cannot be established) or if a fatal error occured on
- * an established connection.
- * <p>
- * This is an experimental feature.
- * <p>
- * You MUST NOT make any assumption about the thread that invokes this method.
- * <p>
- * <b>Please note: if the connection is not connected (e.g., there was no successful
- * connect() call), then the invocation of {@link Connection#close()} will NOT trigger
- * this method.</b>
- *
- * @see Connection#addConnectionMonitor(ConnectionMonitor)
- *
- * @param reason Includes an indication why the socket was closed.
- */
- public void connectionLost(Throwable reason);
-} \ No newline at end of file
diff --git a/app/src/main/java/com/trilead/ssh2/DHGexParameters.java b/app/src/main/java/com/trilead/ssh2/DHGexParameters.java
deleted file mode 100644
index a2945ee..0000000
--- a/app/src/main/java/com/trilead/ssh2/DHGexParameters.java
+++ /dev/null
@@ -1,121 +0,0 @@
-
-package com.trilead.ssh2;
-
-/**
- * A <code>DHGexParameters</code> object can be used to specify parameters for
- * the diffie-hellman group exchange.
- * <p>
- * Depending on which constructor is used, either the use of a
- * <code>SSH_MSG_KEX_DH_GEX_REQUEST</code> or <code>SSH_MSG_KEX_DH_GEX_REQUEST_OLD</code>
- * can be forced.
- *
- * @see Connection#setDHGexParameters(DHGexParameters)
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: DHGexParameters.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-
-public class DHGexParameters
-{
- private final int min_group_len;
- private final int pref_group_len;
- private final int max_group_len;
-
- private static final int MIN_ALLOWED = 1024;
- private static final int MAX_ALLOWED = 8192;
-
- /**
- * Same as calling {@link #DHGexParameters(int, int, int) DHGexParameters(1024, 1024, 4096)}.
- * This is also the default used by the Connection class.
- *
- */
- public DHGexParameters()
- {
- this(1024, 1024, 4096);
- }
-
- /**
- * This constructor can be used to force the sending of a
- * <code>SSH_MSG_KEX_DH_GEX_REQUEST_OLD</code> request.
- * Internally, the minimum and maximum group lengths will
- * be set to zero.
- *
- * @param pref_group_len has to be &gt= 1024 and &lt;= 8192
- */
- public DHGexParameters(int pref_group_len)
- {
- if ((pref_group_len < MIN_ALLOWED) || (pref_group_len > MAX_ALLOWED))
- throw new IllegalArgumentException("pref_group_len out of range!");
-
- this.pref_group_len = pref_group_len;
- this.min_group_len = 0;
- this.max_group_len = 0;
- }
-
- /**
- * This constructor can be used to force the sending of a
- * <code>SSH_MSG_KEX_DH_GEX_REQUEST</code> request.
- * <p>
- * Note: older OpenSSH servers don't understand this request, in which
- * case you should use the {@link #DHGexParameters(int)} constructor.
- * <p>
- * All values have to be &gt= 1024 and &lt;= 8192. Furthermore,
- * min_group_len &lt;= pref_group_len &lt;= max_group_len.
- *
- * @param min_group_len
- * @param pref_group_len
- * @param max_group_len
- */
- public DHGexParameters(int min_group_len, int pref_group_len, int max_group_len)
- {
- if ((min_group_len < MIN_ALLOWED) || (min_group_len > MAX_ALLOWED))
- throw new IllegalArgumentException("min_group_len out of range!");
-
- if ((pref_group_len < MIN_ALLOWED) || (pref_group_len > MAX_ALLOWED))
- throw new IllegalArgumentException("pref_group_len out of range!");
-
- if ((max_group_len < MIN_ALLOWED) || (max_group_len > MAX_ALLOWED))
- throw new IllegalArgumentException("max_group_len out of range!");
-
- if ((pref_group_len < min_group_len) || (pref_group_len > max_group_len))
- throw new IllegalArgumentException("pref_group_len is incompatible with min and max!");
-
- if (max_group_len < min_group_len)
- throw new IllegalArgumentException("max_group_len must not be smaller than min_group_len!");
-
- this.min_group_len = min_group_len;
- this.pref_group_len = pref_group_len;
- this.max_group_len = max_group_len;
- }
-
- /**
- * Get the maximum group length.
- *
- * @return the maximum group length, may be <code>zero</code> if
- * SSH_MSG_KEX_DH_GEX_REQUEST_OLD should be requested
- */
- public int getMax_group_len()
- {
- return max_group_len;
- }
-
- /**
- * Get the minimum group length.
- *
- * @return minimum group length, may be <code>zero</code> if
- * SSH_MSG_KEX_DH_GEX_REQUEST_OLD should be requested
- */
- public int getMin_group_len()
- {
- return min_group_len;
- }
-
- /**
- * Get the preferred group length.
- *
- * @return the preferred group length
- */
- public int getPref_group_len()
- {
- return pref_group_len;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/DebugLogger.java b/app/src/main/java/com/trilead/ssh2/DebugLogger.java
deleted file mode 100644
index adf2c8e..0000000
--- a/app/src/main/java/com/trilead/ssh2/DebugLogger.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.trilead.ssh2;
-
-/**
- * An interface which needs to be implemented if you
- * want to capture debugging messages.
- *
- * @see Connection#enableDebugging(boolean, DebugLogger)
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: DebugLogger.java,v 1.1 2008/03/03 07:01:36 cplattne Exp $
- */
-public interface DebugLogger
-{
-
-/**
- * Log a debug message.
- *
- * @param level 0-99, 99 is a the most verbose level
- * @param className the class that generated the message
- * @param message the debug message
- */
- public void log(int level, String className, String message);
-}
diff --git a/app/src/main/java/com/trilead/ssh2/DynamicPortForwarder.java b/app/src/main/java/com/trilead/ssh2/DynamicPortForwarder.java
deleted file mode 100644
index a15efe7..0000000
--- a/app/src/main/java/com/trilead/ssh2/DynamicPortForwarder.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * ConnectBot: simple, powerful, open-source SSH client for Android
- * Copyright 2007 Kenny Root, Jeffrey Sharkey
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.trilead.ssh2;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-
-import com.trilead.ssh2.channel.ChannelManager;
-import com.trilead.ssh2.channel.DynamicAcceptThread;
-
-/**
- * A <code>DynamicPortForwarder</code> forwards TCP/IP connections to a local
- * port via the secure tunnel to another host which is selected via the
- * SOCKS protocol. Checkout {@link Connection#createDynamicPortForwarder(int)}
- * on how to create one.
- *
- * @author Kenny Root
- * @version $Id: $
- */
-public class DynamicPortForwarder {
- ChannelManager cm;
-
- DynamicAcceptThread dat;
-
- DynamicPortForwarder(ChannelManager cm, int local_port)
- throws IOException
- {
- this.cm = cm;
-
- dat = new DynamicAcceptThread(cm, local_port);
- dat.setDaemon(true);
- dat.start();
- }
-
- DynamicPortForwarder(ChannelManager cm, InetSocketAddress addr) throws IOException {
- this.cm = cm;
-
- dat = new DynamicAcceptThread(cm, addr);
- dat.setDaemon(true);
- dat.start();
- }
-
- /**
- * Stop TCP/IP forwarding of newly arriving connections.
- *
- * @throws IOException
- */
- public void close() throws IOException
- {
- dat.stopWorking();
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/HTTPProxyData.java b/app/src/main/java/com/trilead/ssh2/HTTPProxyData.java
deleted file mode 100644
index 2edffe6..0000000
--- a/app/src/main/java/com/trilead/ssh2/HTTPProxyData.java
+++ /dev/null
@@ -1,83 +0,0 @@
-
-package com.trilead.ssh2;
-
-/**
- * A <code>HTTPProxyData</code> object is used to specify the needed connection data
- * to connect through a HTTP proxy.
- *
- * @see Connection#setProxyData(ProxyData)
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: HTTPProxyData.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-
-public class HTTPProxyData implements ProxyData
-{
- public final String proxyHost;
- public final int proxyPort;
- public final String proxyUser;
- public final String proxyPass;
- public final String[] requestHeaderLines;
-
- /**
- * Same as calling {@link #HTTPProxyData(String, int, String, String) HTTPProxyData(proxyHost, proxyPort, <code>null</code>, <code>null</code>)}
- *
- * @param proxyHost Proxy hostname.
- * @param proxyPort Proxy port.
- */
- public HTTPProxyData(String proxyHost, int proxyPort)
- {
- this(proxyHost, proxyPort, null, null);
- }
-
- /**
- * Same as calling {@link #HTTPProxyData(String, int, String, String, String[]) HTTPProxyData(proxyHost, proxyPort, <code>null</code>, <code>null</code>, <code>null</code>)}
- *
- * @param proxyHost Proxy hostname.
- * @param proxyPort Proxy port.
- * @param proxyUser Username for basic authentication (<code>null</code> if no authentication is needed).
- * @param proxyPass Password for basic authentication (<code>null</code> if no authentication is needed).
- */
- public HTTPProxyData(String proxyHost, int proxyPort, String proxyUser, String proxyPass)
- {
- this(proxyHost, proxyPort, proxyUser, proxyPass, null);
- }
-
- /**
- * Connection data for a HTTP proxy. It is possible to specify a username and password
- * if the proxy requires basic authentication. Also, additional request header lines can
- * be specified (e.g., "User-Agent: CERN-LineMode/2.15 libwww/2.17b3").
- * <p>
- * Please note: if you want to use basic authentication, then both <code>proxyUser</code>
- * and <code>proxyPass</code> must be non-null.
- * <p>
- * Here is an example:
- * <p>
- * <code>
- * new HTTPProxyData("192.168.1.1", "3128", "proxyuser", "secret", new String[] {"User-Agent: TrileadBasedClient/1.0", "X-My-Proxy-Option: something"});
- * </code>
- *
- * @param proxyHost Proxy hostname.
- * @param proxyPort Proxy port.
- * @param proxyUser Username for basic authentication (<code>null</code> if no authentication is needed).
- * @param proxyPass Password for basic authentication (<code>null</code> if no authentication is needed).
- * @param requestHeaderLines An array with additional request header lines (without end-of-line markers)
- * that have to be sent to the server. May be <code>null</code>.
- */
-
- public HTTPProxyData(String proxyHost, int proxyPort, String proxyUser, String proxyPass,
- String[] requestHeaderLines)
- {
- if (proxyHost == null)
- throw new IllegalArgumentException("proxyHost must be non-null");
-
- if (proxyPort < 0)
- throw new IllegalArgumentException("proxyPort must be non-negative");
-
- this.proxyHost = proxyHost;
- this.proxyPort = proxyPort;
- this.proxyUser = proxyUser;
- this.proxyPass = proxyPass;
- this.requestHeaderLines = requestHeaderLines;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/HTTPProxyException.java b/app/src/main/java/com/trilead/ssh2/HTTPProxyException.java
deleted file mode 100644
index 4687dd1..0000000
--- a/app/src/main/java/com/trilead/ssh2/HTTPProxyException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-
-package com.trilead.ssh2;
-
-import java.io.IOException;
-
-/**
- * May be thrown upon connect() if a HTTP proxy is being used.
- *
- * @see Connection#connect()
- * @see Connection#setProxyData(ProxyData)
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: HTTPProxyException.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-
-public class HTTPProxyException extends IOException
-{
- private static final long serialVersionUID = 2241537397104426186L;
-
- public final String httpResponse;
- public final int httpErrorCode;
-
- public HTTPProxyException(String httpResponse, int httpErrorCode)
- {
- super("HTTP Proxy Error (" + httpErrorCode + " " + httpResponse + ")");
- this.httpResponse = httpResponse;
- this.httpErrorCode = httpErrorCode;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/InteractiveCallback.java b/app/src/main/java/com/trilead/ssh2/InteractiveCallback.java
deleted file mode 100644
index 3b83417..0000000
--- a/app/src/main/java/com/trilead/ssh2/InteractiveCallback.java
+++ /dev/null
@@ -1,55 +0,0 @@
-
-package com.trilead.ssh2;
-
-/**
- * An <code>InteractiveCallback</code> is used to respond to challenges sent
- * by the server if authentication mode "keyboard-interactive" is selected.
- *
- * @see Connection#authenticateWithKeyboardInteractive(String,
- * String[], InteractiveCallback)
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: InteractiveCallback.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-
-public interface InteractiveCallback
-{
- /**
- * This callback interface is used during a "keyboard-interactive"
- * authentication. Every time the server sends a set of challenges (however,
- * most often just one challenge at a time), this callback function will be
- * called to give your application a chance to talk to the user and to
- * determine the response(s).
- * <p>
- * Some copy-paste information from the standard: a command line interface
- * (CLI) client SHOULD print the name and instruction (if non-empty), adding
- * newlines. Then for each prompt in turn, the client SHOULD display the
- * prompt and read the user input. The name and instruction fields MAY be
- * empty strings, the client MUST be prepared to handle this correctly. The
- * prompt field(s) MUST NOT be empty strings.
- * <p>
- * Please refer to draft-ietf-secsh-auth-kbdinteract-XX.txt for the details.
- * <p>
- * Note: clients SHOULD use control character filtering as discussed in
- * RFC4251 to avoid attacks by including
- * terminal control characters in the fields to be displayed.
- *
- * @param name
- * the name String sent by the server.
- * @param instruction
- * the instruction String sent by the server.
- * @param numPrompts
- * number of prompts - may be zero (in this case, you should just
- * return a String array of length zero).
- * @param prompt
- * an array (length <code>numPrompts</code>) of Strings
- * @param echo
- * an array (length <code>numPrompts</code>) of booleans. For
- * each prompt, the corresponding echo field indicates whether or
- * not the user input should be echoed as characters are typed.
- * @return an array of reponses - the array size must match the parameter
- * <code>numPrompts</code>.
- */
- public String[] replyToChallenge(String name, String instruction, int numPrompts, String[] prompt, boolean[] echo)
- throws Exception;
-}
diff --git a/app/src/main/java/com/trilead/ssh2/KnownHosts.java b/app/src/main/java/com/trilead/ssh2/KnownHosts.java
deleted file mode 100644
index ec022ff..0000000
--- a/app/src/main/java/com/trilead/ssh2/KnownHosts.java
+++ /dev/null
@@ -1,844 +0,0 @@
-
-package com.trilead.ssh2;
-
-import java.io.BufferedReader;
-import java.io.CharArrayReader;
-import java.io.CharArrayWriter;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.io.UnsupportedEncodingException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.security.InvalidKeyException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.interfaces.DSAPublicKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAPublicKey;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Locale;
-import java.util.Vector;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-
-import com.trilead.ssh2.crypto.Base64;
-import com.trilead.ssh2.signature.DSASHA1Verify;
-import com.trilead.ssh2.signature.ECDSASHA2Verify;
-import com.trilead.ssh2.signature.RSASHA1Verify;
-
-
-/**
- * The <code>KnownHosts</code> class is a handy tool to verify received server hostkeys
- * based on the information in <code>known_hosts</code> files (the ones used by OpenSSH).
- * <p>
- * It offers basically an in-memory database for known_hosts entries, as well as some
- * helper functions. Entries from a <code>known_hosts</code> file can be loaded at construction time.
- * It is also possible to add more keys later (e.g., one can parse different
- * <code>known_hosts<code> files).
- * <p>
- * It is a thread safe implementation, therefore, you need only to instantiate one
- * <code>KnownHosts</code> for your whole application.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: KnownHosts.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
- */
-
-public class KnownHosts
-{
- public static final int HOSTKEY_IS_OK = 0;
- public static final int HOSTKEY_IS_NEW = 1;
- public static final int HOSTKEY_HAS_CHANGED = 2;
-
- private class KnownHostsEntry
- {
- String[] patterns;
- PublicKey key;
-
- KnownHostsEntry(String[] patterns, PublicKey key)
- {
- this.patterns = patterns;
- this.key = key;
- }
- }
-
- private LinkedList<KnownHostsEntry> publicKeys = new LinkedList<KnownHostsEntry>();
-
- public KnownHosts()
- {
- }
-
- public KnownHosts(char[] knownHostsData) throws IOException
- {
- initialize(knownHostsData);
- }
-
- public KnownHosts(File knownHosts) throws IOException
- {
- initialize(knownHosts);
- }
-
- /**
- * Adds a single public key entry to the database. Note: this will NOT add the public key
- * to any physical file (e.g., "~/.ssh/known_hosts") - use <code>addHostkeyToFile()</code> for that purpose.
- * This method is designed to be used in a {@link ServerHostKeyVerifier}.
- *
- * @param hostnames a list of hostname patterns - at least one most be specified. Check out the
- * OpenSSH sshd man page for a description of the pattern matching algorithm.
- * @param serverHostKeyAlgorithm as passed to the {@link ServerHostKeyVerifier}.
- * @param serverHostKey as passed to the {@link ServerHostKeyVerifier}.
- * @throws IOException
- */
- public void addHostkey(String hostnames[], String serverHostKeyAlgorithm, byte[] serverHostKey) throws IOException
- {
- if (hostnames == null)
- throw new IllegalArgumentException("hostnames may not be null");
-
- if ("ssh-rsa".equals(serverHostKeyAlgorithm))
- {
- RSAPublicKey rpk = RSASHA1Verify.decodeSSHRSAPublicKey(serverHostKey);
-
- synchronized (publicKeys)
- {
- publicKeys.add(new KnownHostsEntry(hostnames, rpk));
- }
- }
- else if ("ssh-dss".equals(serverHostKeyAlgorithm))
- {
- DSAPublicKey dpk = DSASHA1Verify.decodeSSHDSAPublicKey(serverHostKey);
-
- synchronized (publicKeys)
- {
- publicKeys.add(new KnownHostsEntry(hostnames, dpk));
- }
- }
- else if (serverHostKeyAlgorithm.startsWith(ECDSASHA2Verify.ECDSA_SHA2_PREFIX))
- {
- ECPublicKey epk = ECDSASHA2Verify.decodeSSHECDSAPublicKey(serverHostKey);
-
- synchronized (publicKeys) {
- publicKeys.add(new KnownHostsEntry(hostnames, epk));
- }
- }
- else
- throw new IOException("Unknwon host key type (" + serverHostKeyAlgorithm + ")");
- }
-
- /**
- * Parses the given known_hosts data and adds entries to the database.
- *
- * @param knownHostsData
- * @throws IOException
- */
- public void addHostkeys(char[] knownHostsData) throws IOException
- {
- initialize(knownHostsData);
- }
-
- /**
- * Parses the given known_hosts file and adds entries to the database.
- *
- * @param knownHosts
- * @throws IOException
- */
- public void addHostkeys(File knownHosts) throws IOException
- {
- initialize(knownHosts);
- }
-
- /**
- * Generate the hashed representation of the given hostname. Useful for adding entries
- * with hashed hostnames to a known_hosts file. (see -H option of OpenSSH key-gen).
- *
- * @param hostname
- * @return the hashed representation, e.g., "|1|cDhrv7zwEUV3k71CEPHnhHZezhA=|Xo+2y6rUXo2OIWRAYhBOIijbJMA="
- */
- public static final String createHashedHostname(String hostname)
- {
- MessageDigest sha1;
- try {
- sha1 = MessageDigest.getInstance("SHA1");
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException("VM doesn't support SHA1", e);
- }
-
- byte[] salt = new byte[sha1.getDigestLength()];
-
- new SecureRandom().nextBytes(salt);
-
- byte[] hash = hmacSha1Hash(salt, hostname);
-
- String base64_salt = new String(Base64.encode(salt));
- String base64_hash = new String(Base64.encode(hash));
-
- return new String("|1|" + base64_salt + "|" + base64_hash);
- }
-
- private static final byte[] hmacSha1Hash(byte[] salt, String hostname)
- {
- Mac hmac;
- try {
- hmac = Mac.getInstance("HmacSHA1");
- if (salt.length != hmac.getMacLength())
- throw new IllegalArgumentException("Salt has wrong length (" + salt.length + ")");
- hmac.init(new SecretKeySpec(salt, "HmacSHA1"));
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException("Unable to HMAC-SHA1", e);
- } catch (InvalidKeyException e) {
- throw new RuntimeException("Unable to create SecretKey", e);
- }
-
- try
- {
- hmac.update(hostname.getBytes("ISO-8859-1"));
- }catch(UnsupportedEncodingException ignore)
- {
- /* Actually, ISO-8859-1 is supported by all correct
- * Java implementations. But... you never know. */
- hmac.update(hostname.getBytes());
- }
-
- return hmac.doFinal();
- }
-
- private final boolean checkHashed(String entry, String hostname)
- {
- if (entry.startsWith("|1|") == false)
- return false;
-
- int delim_idx = entry.indexOf('|', 3);
-
- if (delim_idx == -1)
- return false;
-
- String salt_base64 = entry.substring(3, delim_idx);
- String hash_base64 = entry.substring(delim_idx + 1);
-
- byte[] salt = null;
- byte[] hash = null;
-
- try
- {
- salt = Base64.decode(salt_base64.toCharArray());
- hash = Base64.decode(hash_base64.toCharArray());
- }
- catch (IOException e)
- {
- return false;
- }
-
- try {
- MessageDigest sha1 = MessageDigest.getInstance("SHA1");
- if (salt.length != sha1.getDigestLength())
- return false;
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException("VM does not support SHA1", e);
- }
-
- byte[] dig = hmacSha1Hash(salt, hostname);
-
- for (int i = 0; i < dig.length; i++)
- if (dig[i] != hash[i])
- return false;
-
- return true;
- }
-
- private int checkKey(String remoteHostname, PublicKey remoteKey)
- {
- int result = HOSTKEY_IS_NEW;
-
- synchronized (publicKeys)
- {
- Iterator<KnownHostsEntry> i = publicKeys.iterator();
-
- while (i.hasNext())
- {
- KnownHostsEntry ke = i.next();
-
- if (hostnameMatches(ke.patterns, remoteHostname) == false)
- continue;
-
- boolean res = matchKeys(ke.key, remoteKey);
-
- if (res == true)
- return HOSTKEY_IS_OK;
-
- result = HOSTKEY_HAS_CHANGED;
- }
- }
- return result;
- }
-
- private Vector<PublicKey> getAllKeys(String hostname)
- {
- Vector<PublicKey> keys = new Vector<PublicKey>();
-
- synchronized (publicKeys)
- {
- Iterator<KnownHostsEntry> i = publicKeys.iterator();
-
- while (i.hasNext())
- {
- KnownHostsEntry ke = i.next();
-
- if (hostnameMatches(ke.patterns, hostname) == false)
- continue;
-
- keys.addElement(ke.key);
- }
- }
-
- return keys;
- }
-
- /**
- * Try to find the preferred order of hostkey algorithms for the given hostname.
- * Based on the type of hostkey that is present in the internal database
- * (i.e., either <code>ssh-rsa</code> or <code>ssh-dss</code>)
- * an ordered list of hostkey algorithms is returned which can be passed
- * to <code>Connection.setServerHostKeyAlgorithms</code>.
- *
- * @param hostname
- * @return <code>null</code> if no key for the given hostname is present or
- * there are keys of multiple types present for the given hostname. Otherwise,
- * an array with hostkey algorithms is returned (i.e., an array of length 2).
- */
- public String[] getPreferredServerHostkeyAlgorithmOrder(String hostname)
- {
- String[] algos = recommendHostkeyAlgorithms(hostname);
-
- if (algos != null)
- return algos;
-
- InetAddress[] ipAdresses = null;
-
- try
- {
- ipAdresses = InetAddress.getAllByName(hostname);
- }
- catch (UnknownHostException e)
- {
- return null;
- }
-
- for (int i = 0; i < ipAdresses.length; i++)
- {
- algos = recommendHostkeyAlgorithms(ipAdresses[i].getHostAddress());
-
- if (algos != null)
- return algos;
- }
-
- return null;
- }
-
- private final boolean hostnameMatches(String[] hostpatterns, String hostname)
- {
- boolean isMatch = false;
- boolean negate = false;
-
- hostname = hostname.toLowerCase(Locale.US);
-
- for (int k = 0; k < hostpatterns.length; k++)
- {
- if (hostpatterns[k] == null)
- continue;
-
- String pattern = null;
-
- /* In contrast to OpenSSH we also allow negated hash entries (as well as hashed
- * entries in lines with multiple entries).
- */
-
- if ((hostpatterns[k].length() > 0) && (hostpatterns[k].charAt(0) == '!'))
- {
- pattern = hostpatterns[k].substring(1);
- negate = true;
- }
- else
- {
- pattern = hostpatterns[k];
- negate = false;
- }
-
- /* Optimize, no need to check this entry */
-
- if ((isMatch) && (negate == false))
- continue;
-
- /* Now compare */
-
- if (pattern.charAt(0) == '|')
- {
- if (checkHashed(pattern, hostname))
- {
- if (negate)
- return false;
- isMatch = true;
- }
- }
- else
- {
- pattern = pattern.toLowerCase(Locale.US);
-
- if ((pattern.indexOf('?') != -1) || (pattern.indexOf('*') != -1))
- {
- if (pseudoRegex(pattern.toCharArray(), 0, hostname.toCharArray(), 0))
- {
- if (negate)
- return false;
- isMatch = true;
- }
- }
- else if (pattern.compareTo(hostname) == 0)
- {
- if (negate)
- return false;
- isMatch = true;
- }
- }
- }
-
- return isMatch;
- }
-
- private void initialize(char[] knownHostsData) throws IOException
- {
- BufferedReader br = new BufferedReader(new CharArrayReader(knownHostsData));
-
- while (true)
- {
- String line = br.readLine();
-
- if (line == null)
- break;
-
- line = line.trim();
-
- if (line.startsWith("#"))
- continue;
-
- String[] arr = line.split(" ");
-
- if (arr.length >= 3)
- {
- if ((arr[1].compareTo("ssh-rsa") == 0) || (arr[1].compareTo("ssh-dss") == 0))
- {
- String[] hostnames = arr[0].split(",");
-
- byte[] msg = Base64.decode(arr[2].toCharArray());
-
- addHostkey(hostnames, arr[1], msg);
- }
- }
- }
- }
-
- private void initialize(File knownHosts) throws IOException
- {
- char[] buff = new char[512];
-
- CharArrayWriter cw = new CharArrayWriter();
-
- knownHosts.createNewFile();
-
- FileReader fr = new FileReader(knownHosts);
-
- while (true)
- {
- int len = fr.read(buff);
- if (len < 0)
- break;
- cw.write(buff, 0, len);
- }
-
- fr.close();
-
- initialize(cw.toCharArray());
- }
-
- private final boolean matchKeys(PublicKey key1, PublicKey key2)
- {
- return key1.equals(key2);
- }
-
- private final boolean pseudoRegex(char[] pattern, int i, char[] match, int j)
- {
- /* This matching logic is equivalent to the one present in OpenSSH 4.1 */
-
- while (true)
- {
- /* Are we at the end of the pattern? */
-
- if (pattern.length == i)
- return (match.length == j);
-
- if (pattern[i] == '*')
- {
- i++;
-
- if (pattern.length == i)
- return true;
-
- if ((pattern[i] != '*') && (pattern[i] != '?'))
- {
- while (true)
- {
- if ((pattern[i] == match[j]) && pseudoRegex(pattern, i + 1, match, j + 1))
- return true;
- j++;
- if (match.length == j)
- return false;
- }
- }
-
- while (true)
- {
- if (pseudoRegex(pattern, i, match, j))
- return true;
- j++;
- if (match.length == j)
- return false;
- }
- }
-
- if (match.length == j)
- return false;
-
- if ((pattern[i] != '?') && (pattern[i] != match[j]))
- return false;
-
- i++;
- j++;
- }
- }
-
- private String[] recommendHostkeyAlgorithms(String hostname)
- {
- String preferredAlgo = null;
-
- Vector<PublicKey> keys = getAllKeys(hostname);
-
- for (int i = 0; i < keys.size(); i++)
- {
- String thisAlgo = null;
-
- if (keys.elementAt(i) instanceof RSAPublicKey)
- thisAlgo = "ssh-rsa";
- else if (keys.elementAt(i) instanceof DSAPublicKey)
- thisAlgo = "ssh-dss";
- else
- continue;
-
- if (preferredAlgo != null)
- {
- /* If we find different key types, then return null */
-
- if (preferredAlgo.compareTo(thisAlgo) != 0)
- return null;
-
- /* OK, we found the same algo again, optimize */
-
- continue;
- }
- }
-
- /* If we did not find anything that we know of, return null */
-
- if (preferredAlgo == null)
- return null;
-
- /* Now put the preferred algo to the start of the array.
- * You may ask yourself why we do it that way - basically, we could just
- * return only the preferred algorithm: since we have a saved key of that
- * type (sent earlier from the remote host), then that should work out.
- * However, imagine that the server is (for whatever reasons) not offering
- * that type of hostkey anymore (e.g., "ssh-rsa" was disabled and
- * now "ssh-dss" is being used). If we then do not let the server send us
- * a fresh key of the new type, then we shoot ourself into the foot:
- * the connection cannot be established and hence the user cannot decide
- * if he/she wants to accept the new key.
- */
-
- if (preferredAlgo.equals("ssh-rsa"))
- return new String[] { "ssh-rsa", "ssh-dss" };
-
- return new String[] { "ssh-dss", "ssh-rsa" };
- }
-
- /**
- * Checks the internal hostkey database for the given hostkey.
- * If no matching key can be found, then the hostname is resolved to an IP address
- * and the search is repeated using that IP address.
- *
- * @param hostname the server's hostname, will be matched with all hostname patterns
- * @param serverHostKeyAlgorithm type of hostkey, either <code>ssh-rsa</code> or <code>ssh-dss</code>
- * @param serverHostKey the key blob
- * @return <ul>
- * <li><code>HOSTKEY_IS_OK</code>: the given hostkey matches an entry for the given hostname</li>
- * <li><code>HOSTKEY_IS_NEW</code>: no entries found for this hostname and this type of hostkey</li>
- * <li><code>HOSTKEY_HAS_CHANGED</code>: hostname is known, but with another key of the same type
- * (man-in-the-middle attack?)</li>
- * </ul>
- * @throws IOException if the supplied key blob cannot be parsed or does not match the given hostkey type.
- */
- public int verifyHostkey(String hostname, String serverHostKeyAlgorithm, byte[] serverHostKey) throws IOException
- {
- PublicKey remoteKey = null;
-
- if ("ssh-rsa".equals(serverHostKeyAlgorithm))
- {
- remoteKey = RSASHA1Verify.decodeSSHRSAPublicKey(serverHostKey);
- }
- else if ("ssh-dss".equals(serverHostKeyAlgorithm))
- {
- remoteKey = DSASHA1Verify.decodeSSHDSAPublicKey(serverHostKey);
- }
- else if (serverHostKeyAlgorithm.startsWith("ecdsa-sha2-"))
- {
- remoteKey = ECDSASHA2Verify.decodeSSHECDSAPublicKey(serverHostKey);
- }
- else
- throw new IllegalArgumentException("Unknown hostkey type " + serverHostKeyAlgorithm);
-
- int result = checkKey(hostname, remoteKey);
-
- if (result == HOSTKEY_IS_OK)
- return result;
-
- InetAddress[] ipAdresses = null;
-
- try
- {
- ipAdresses = InetAddress.getAllByName(hostname);
- }
- catch (UnknownHostException e)
- {
- return result;
- }
-
- for (int i = 0; i < ipAdresses.length; i++)
- {
- int newresult = checkKey(ipAdresses[i].getHostAddress(), remoteKey);
-
- if (newresult == HOSTKEY_IS_OK)
- return newresult;
-
- if (newresult == HOSTKEY_HAS_CHANGED)
- result = HOSTKEY_HAS_CHANGED;
- }
-
- return result;
- }
-
- /**
- * Adds a single public key entry to the a known_hosts file.
- * This method is designed to be used in a {@link ServerHostKeyVerifier}.
- *
- * @param knownHosts the file where the publickey entry will be appended.
- * @param hostnames a list of hostname patterns - at least one most be specified. Check out the
- * OpenSSH sshd man page for a description of the pattern matching algorithm.
- * @param serverHostKeyAlgorithm as passed to the {@link ServerHostKeyVerifier}.
- * @param serverHostKey as passed to the {@link ServerHostKeyVerifier}.
- * @throws IOException
- */
- public final static void addHostkeyToFile(File knownHosts, String[] hostnames, String serverHostKeyAlgorithm,
- byte[] serverHostKey) throws IOException
- {
- if ((hostnames == null) || (hostnames.length == 0))
- throw new IllegalArgumentException("Need at least one hostname specification");
-
- if ((serverHostKeyAlgorithm == null) || (serverHostKey == null))
- throw new IllegalArgumentException();
-
- CharArrayWriter writer = new CharArrayWriter();
-
- for (int i = 0; i < hostnames.length; i++)
- {
- if (i != 0)
- writer.write(',');
- writer.write(hostnames[i]);
- }
-
- writer.write(' ');
- writer.write(serverHostKeyAlgorithm);
- writer.write(' ');
- writer.write(Base64.encode(serverHostKey));
- writer.write("\n");
-
- char[] entry = writer.toCharArray();
-
- RandomAccessFile raf = new RandomAccessFile(knownHosts, "rw");
-
- long len = raf.length();
-
- if (len > 0)
- {
- raf.seek(len - 1);
- int last = raf.read();
- if (last != '\n')
- raf.write('\n');
- }
-
- raf.write(new String(entry).getBytes("ISO-8859-1"));
- raf.close();
- }
-
- /**
- * Generates a "raw" fingerprint of a hostkey.
- *
- * @param type either "md5" or "sha1"
- * @param keyType either "ssh-rsa" or "ssh-dss"
- * @param hostkey the hostkey
- * @return the raw fingerprint
- */
- static final private byte[] rawFingerPrint(String type, String keyType, byte[] hostkey)
- {
- MessageDigest dig = null;
-
- try {
- if ("md5".equals(type))
- {
- dig = MessageDigest.getInstance("MD5");
- }
- else if ("sha1".equals(type))
- {
- dig = MessageDigest.getInstance("SHA1");
- }
- else
- {
- throw new IllegalArgumentException("Unknown hash type " + type);
- }
- } catch (NoSuchAlgorithmException e) {
- throw new IllegalArgumentException("Unknown hash type " + type);
- }
-
- if (keyType.startsWith("ecdsa-sha2-"))
- {
- }
- else if ("ssh-rsa".equals(keyType))
- {
- }
- else if ("ssh-dss".equals(keyType))
- {
- }
- else
- throw new IllegalArgumentException("Unknown key type " + keyType);
-
- if (hostkey == null)
- throw new IllegalArgumentException("hostkey is null");
-
- dig.update(hostkey);
- return dig.digest();
- }
-
- /**
- * Convert a raw fingerprint to hex representation (XX:YY:ZZ...).
- * @param fingerprint raw fingerprint
- * @return the hex representation
- */
- static final private String rawToHexFingerprint(byte[] fingerprint)
- {
- final char[] alpha = "0123456789abcdef".toCharArray();
-
- StringBuffer sb = new StringBuffer();
-
- for (int i = 0; i < fingerprint.length; i++)
- {
- if (i != 0)
- sb.append(':');
- int b = fingerprint[i] & 0xff;
- sb.append(alpha[b >> 4]);
- sb.append(alpha[b & 15]);
- }
-
- return sb.toString();
- }
-
- /**
- * Convert a raw fingerprint to bubblebabble representation.
- * @param raw raw fingerprint
- * @return the bubblebabble representation
- */
- static final private String rawToBubblebabbleFingerprint(byte[] raw)
- {
- final char[] v = "aeiouy".toCharArray();
- final char[] c = "bcdfghklmnprstvzx".toCharArray();
-
- StringBuffer sb = new StringBuffer();
-
- int seed = 1;
-
- int rounds = (raw.length / 2) + 1;
-
- sb.append('x');
-
- for (int i = 0; i < rounds; i++)
- {
- if (((i + 1) < rounds) || ((raw.length) % 2 != 0))
- {
- sb.append(v[(((raw[2 * i] >> 6) & 3) + seed) % 6]);
- sb.append(c[(raw[2 * i] >> 2) & 15]);
- sb.append(v[((raw[2 * i] & 3) + (seed / 6)) % 6]);
-
- if ((i + 1) < rounds)
- {
- sb.append(c[(((raw[(2 * i) + 1])) >> 4) & 15]);
- sb.append('-');
- sb.append(c[(((raw[(2 * i) + 1]))) & 15]);
- // As long as seed >= 0, seed will be >= 0 afterwards
- seed = ((seed * 5) + (((raw[2 * i] & 0xff) * 7) + (raw[(2 * i) + 1] & 0xff))) % 36;
- }
- }
- else
- {
- sb.append(v[seed % 6]); // seed >= 0, therefore index positive
- sb.append('x');
- sb.append(v[seed / 6]);
- }
- }
-
- sb.append('x');
-
- return sb.toString();
- }
-
- /**
- * Convert a ssh2 key-blob into a human readable hex fingerprint.
- * Generated fingerprints are identical to those generated by OpenSSH.
- * <p>
- * Example fingerprint: d0:cb:76:19:99:5a:03:fc:73:10:70:93:f2:44:63:47.
-
- * @param keytype either "ssh-rsa" or "ssh-dss"
- * @param publickey key blob
- * @return Hex fingerprint
- */
- public final static String createHexFingerprint(String keytype, byte[] publickey)
- {
- byte[] raw = rawFingerPrint("md5", keytype, publickey);
- return rawToHexFingerprint(raw);
- }
-
- /**
- * Convert a ssh2 key-blob into a human readable bubblebabble fingerprint.
- * The used bubblebabble algorithm (taken from OpenSSH) generates fingerprints
- * that are easier to remember for humans.
- * <p>
- * Example fingerprint: xofoc-bubuz-cazin-zufyl-pivuk-biduk-tacib-pybur-gonar-hotat-lyxux.
- *
- * @param keytype either "ssh-rsa" or "ssh-dss"
- * @param publickey key data
- * @return Bubblebabble fingerprint
- */
- public final static String createBubblebabbleFingerprint(String keytype, byte[] publickey)
- {
- byte[] raw = rawFingerPrint("sha1", keytype, publickey);
- return rawToBubblebabbleFingerprint(raw);
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/LocalPortForwarder.java b/app/src/main/java/com/trilead/ssh2/LocalPortForwarder.java
deleted file mode 100644
index 96fa082..0000000
--- a/app/src/main/java/com/trilead/ssh2/LocalPortForwarder.java
+++ /dev/null
@@ -1,63 +0,0 @@
-
-package com.trilead.ssh2;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-
-import com.trilead.ssh2.channel.ChannelManager;
-import com.trilead.ssh2.channel.LocalAcceptThread;
-
-
-/**
- * A <code>LocalPortForwarder</code> forwards TCP/IP connections to a local
- * port via the secure tunnel to another host (which may or may not be identical
- * to the remote SSH-2 server). Checkout {@link Connection#createLocalPortForwarder(int, String, int)}
- * on how to create one.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: LocalPortForwarder.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public class LocalPortForwarder
-{
- ChannelManager cm;
-
- String host_to_connect;
-
- int port_to_connect;
-
- LocalAcceptThread lat;
-
- LocalPortForwarder(ChannelManager cm, int local_port, String host_to_connect, int port_to_connect)
- throws IOException
- {
- this.cm = cm;
- this.host_to_connect = host_to_connect;
- this.port_to_connect = port_to_connect;
-
- lat = new LocalAcceptThread(cm, local_port, host_to_connect, port_to_connect);
- lat.setDaemon(true);
- lat.start();
- }
-
- LocalPortForwarder(ChannelManager cm, InetSocketAddress addr, String host_to_connect, int port_to_connect)
- throws IOException
- {
- this.cm = cm;
- this.host_to_connect = host_to_connect;
- this.port_to_connect = port_to_connect;
-
- lat = new LocalAcceptThread(cm, addr, host_to_connect, port_to_connect);
- lat.setDaemon(true);
- lat.start();
- }
-
- /**
- * Stop TCP/IP forwarding of newly arriving connections.
- *
- * @throws IOException
- */
- public void close() throws IOException
- {
- lat.stopWorking();
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/LocalStreamForwarder.java b/app/src/main/java/com/trilead/ssh2/LocalStreamForwarder.java
deleted file mode 100644
index 7899367..0000000
--- a/app/src/main/java/com/trilead/ssh2/LocalStreamForwarder.java
+++ /dev/null
@@ -1,78 +0,0 @@
-
-package com.trilead.ssh2;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import com.trilead.ssh2.channel.Channel;
-import com.trilead.ssh2.channel.ChannelManager;
-import com.trilead.ssh2.channel.LocalAcceptThread;
-
-
-/**
- * A <code>LocalStreamForwarder</code> forwards an Input- and Outputstream
- * pair via the secure tunnel to another host (which may or may not be identical
- * to the remote SSH-2 server).
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: LocalStreamForwarder.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public class LocalStreamForwarder
-{
- ChannelManager cm;
-
- String host_to_connect;
- int port_to_connect;
- LocalAcceptThread lat;
-
- Channel cn;
-
- LocalStreamForwarder(ChannelManager cm, String host_to_connect, int port_to_connect) throws IOException
- {
- this.cm = cm;
- this.host_to_connect = host_to_connect;
- this.port_to_connect = port_to_connect;
-
- cn = cm.openDirectTCPIPChannel(host_to_connect, port_to_connect, "127.0.0.1", 0);
- }
-
- /**
- * @return An <code>InputStream</code> object.
- * @throws IOException
- */
- public InputStream getInputStream() throws IOException
- {
- return cn.getStdoutStream();
- }
-
- /**
- * Get the OutputStream. Please be aware that the implementation MAY use an
- * internal buffer. To make sure that the buffered data is sent over the
- * tunnel, you have to call the <code>flush</code> method of the
- * <code>OutputStream</code>. To signal EOF, please use the
- * <code>close</code> method of the <code>OutputStream</code>.
- *
- * @return An <code>OutputStream</code> object.
- * @throws IOException
- */
- public OutputStream getOutputStream() throws IOException
- {
- return cn.getStdinStream();
- }
-
- /**
- * Close the underlying SSH forwarding channel and free up resources.
- * You can also use this method to force the shutdown of the underlying
- * forwarding channel. Pending output (OutputStream not flushed) will NOT
- * be sent. Pending input (InputStream) can still be read. If the shutdown
- * operation is already in progress (initiated from either side), then this
- * call is a no-op.
- *
- * @throws IOException
- */
- public void close() throws IOException
- {
- cm.closeChannel(cn, "Closed due to user request.", true);
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/ProxyData.java b/app/src/main/java/com/trilead/ssh2/ProxyData.java
deleted file mode 100644
index 059a6e3..0000000
--- a/app/src/main/java/com/trilead/ssh2/ProxyData.java
+++ /dev/null
@@ -1,15 +0,0 @@
-
-package com.trilead.ssh2;
-
-/**
- * An abstract marker interface implemented by all proxy data implementations.
- *
- * @see HTTPProxyData
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: ProxyData.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-
-public abstract interface ProxyData
-{
-}
diff --git a/app/src/main/java/com/trilead/ssh2/SCPClient.java b/app/src/main/java/com/trilead/ssh2/SCPClient.java
deleted file mode 100644
index b692750..0000000
--- a/app/src/main/java/com/trilead/ssh2/SCPClient.java
+++ /dev/null
@@ -1,729 +0,0 @@
-
-package com.trilead.ssh2;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * A very basic <code>SCPClient</code> that can be used to copy files from/to
- * the SSH-2 server. On the server side, the "scp" program must be in the PATH.
- * <p>
- * This scp client is thread safe - you can download (and upload) different sets
- * of files concurrently without any troubles. The <code>SCPClient</code> is
- * actually mapping every request to a distinct {@link Session}.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: SCPClient.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
- */
-
-public class SCPClient
-{
- Connection conn;
-
- class LenNamePair
- {
- long length;
- String filename;
- }
-
- public SCPClient(Connection conn)
- {
- if (conn == null)
- throw new IllegalArgumentException("Cannot accept null argument!");
- this.conn = conn;
- }
-
- private void readResponse(InputStream is) throws IOException
- {
- int c = is.read();
-
- if (c == 0)
- return;
-
- if (c == -1)
- throw new IOException("Remote scp terminated unexpectedly.");
-
- if ((c != 1) && (c != 2))
- throw new IOException("Remote scp sent illegal error code.");
-
- if (c == 2)
- throw new IOException("Remote scp terminated with error.");
-
- String err = receiveLine(is);
- throw new IOException("Remote scp terminated with error (" + err + ").");
- }
-
- private String receiveLine(InputStream is) throws IOException
- {
- StringBuffer sb = new StringBuffer(30);
-
- while (true)
- {
- /*
- * This is a random limit - if your path names are longer, then
- * adjust it
- */
-
- if (sb.length() > 8192)
- throw new IOException("Remote scp sent a too long line");
-
- int c = is.read();
-
- if (c < 0)
- throw new IOException("Remote scp terminated unexpectedly.");
-
- if (c == '\n')
- break;
-
- sb.append((char) c);
-
- }
- return sb.toString();
- }
-
- private LenNamePair parseCLine(String line) throws IOException
- {
- /* Minimum line: "xxxx y z" ---> 8 chars */
-
- long len;
-
- if (line.length() < 8)
- throw new IOException("Malformed C line sent by remote SCP binary, line too short.");
-
- if ((line.charAt(4) != ' ') || (line.charAt(5) == ' '))
- throw new IOException("Malformed C line sent by remote SCP binary.");
-
- int length_name_sep = line.indexOf(' ', 5);
-
- if (length_name_sep == -1)
- throw new IOException("Malformed C line sent by remote SCP binary.");
-
- String length_substring = line.substring(5, length_name_sep);
- String name_substring = line.substring(length_name_sep + 1);
-
- if ((length_substring.length() <= 0) || (name_substring.length() <= 0))
- throw new IOException("Malformed C line sent by remote SCP binary.");
-
- if ((6 + length_substring.length() + name_substring.length()) != line.length())
- throw new IOException("Malformed C line sent by remote SCP binary.");
-
- try
- {
- len = Long.parseLong(length_substring);
- }
- catch (NumberFormatException e)
- {
- throw new IOException("Malformed C line sent by remote SCP binary, cannot parse file length.");
- }
-
- if (len < 0)
- throw new IOException("Malformed C line sent by remote SCP binary, illegal file length.");
-
- LenNamePair lnp = new LenNamePair();
- lnp.length = len;
- lnp.filename = name_substring;
-
- return lnp;
- }
-
- private void sendBytes(Session sess, byte[] data, String fileName, String mode) throws IOException
- {
- OutputStream os = sess.getStdin();
- InputStream is = new BufferedInputStream(sess.getStdout(), 512);
-
- readResponse(is);
-
- String cline = "C" + mode + " " + data.length + " " + fileName + "\n";
-
- os.write(cline.getBytes("ISO-8859-1"));
- os.flush();
-
- readResponse(is);
-
- os.write(data, 0, data.length);
- os.write(0);
- os.flush();
-
- readResponse(is);
-
- os.write("E\n".getBytes("ISO-8859-1"));
- os.flush();
- }
-
- private void sendFiles(Session sess, String[] files, String[] remoteFiles, String mode) throws IOException
- {
- byte[] buffer = new byte[8192];
-
- OutputStream os = new BufferedOutputStream(sess.getStdin(), 40000);
- InputStream is = new BufferedInputStream(sess.getStdout(), 512);
-
- readResponse(is);
-
- for (int i = 0; i < files.length; i++)
- {
- File f = new File(files[i]);
- long remain = f.length();
-
- String remoteName;
-
- if ((remoteFiles != null) && (remoteFiles.length > i) && (remoteFiles[i] != null))
- remoteName = remoteFiles[i];
- else
- remoteName = f.getName();
-
- String cline = "C" + mode + " " + remain + " " + remoteName + "\n";
-
- os.write(cline.getBytes("ISO-8859-1"));
- os.flush();
-
- readResponse(is);
-
- FileInputStream fis = null;
-
- try
- {
- fis = new FileInputStream(f);
-
- while (remain > 0)
- {
- int trans;
- if (remain > buffer.length)
- trans = buffer.length;
- else
- trans = (int) remain;
-
- if (fis.read(buffer, 0, trans) != trans)
- throw new IOException("Cannot read enough from local file " + files[i]);
-
- os.write(buffer, 0, trans);
-
- remain -= trans;
- }
- }
- finally
- {
- if (fis != null)
- fis.close();
- }
-
- os.write(0);
- os.flush();
-
- readResponse(is);
- }
-
- os.write("E\n".getBytes("ISO-8859-1"));
- os.flush();
- }
-
- private void receiveFiles(Session sess, OutputStream[] targets) throws IOException
- {
- byte[] buffer = new byte[8192];
-
- OutputStream os = new BufferedOutputStream(sess.getStdin(), 512);
- InputStream is = new BufferedInputStream(sess.getStdout(), 40000);
-
- os.write(0x0);
- os.flush();
-
- for (int i = 0; i < targets.length; i++)
- {
- LenNamePair lnp = null;
-
- while (true)
- {
- int c = is.read();
- if (c < 0)
- throw new IOException("Remote scp terminated unexpectedly.");
-
- String line = receiveLine(is);
-
- if (c == 'T')
- {
- /* Ignore modification times */
-
- continue;
- }
-
- if ((c == 1) || (c == 2))
- throw new IOException("Remote SCP error: " + line);
-
- if (c == 'C')
- {
- lnp = parseCLine(line);
- break;
-
- }
- throw new IOException("Remote SCP error: " + ((char) c) + line);
- }
-
- os.write(0x0);
- os.flush();
-
- long remain = lnp.length;
-
- while (remain > 0)
- {
- int trans;
- if (remain > buffer.length)
- trans = buffer.length;
- else
- trans = (int) remain;
-
- int this_time_received = is.read(buffer, 0, trans);
-
- if (this_time_received < 0)
- {
- throw new IOException("Remote scp terminated connection unexpectedly");
- }
-
- targets[i].write(buffer, 0, this_time_received);
-
- remain -= this_time_received;
- }
-
- readResponse(is);
-
- os.write(0x0);
- os.flush();
- }
- }
-
- private void receiveFiles(Session sess, String[] files, String target) throws IOException
- {
- byte[] buffer = new byte[8192];
-
- OutputStream os = new BufferedOutputStream(sess.getStdin(), 512);
- InputStream is = new BufferedInputStream(sess.getStdout(), 40000);
-
- os.write(0x0);
- os.flush();
-
- for (int i = 0; i < files.length; i++)
- {
- LenNamePair lnp = null;
-
- while (true)
- {
- int c = is.read();
- if (c < 0)
- throw new IOException("Remote scp terminated unexpectedly.");
-
- String line = receiveLine(is);
-
- if (c == 'T')
- {
- /* Ignore modification times */
-
- continue;
- }
-
- if ((c == 1) || (c == 2))
- throw new IOException("Remote SCP error: " + line);
-
- if (c == 'C')
- {
- lnp = parseCLine(line);
- break;
-
- }
- throw new IOException("Remote SCP error: " + ((char) c) + line);
- }
-
- os.write(0x0);
- os.flush();
-
- File f = new File(target + File.separatorChar + lnp.filename);
- FileOutputStream fop = null;
-
- try
- {
- fop = new FileOutputStream(f);
-
- long remain = lnp.length;
-
- while (remain > 0)
- {
- int trans;
- if (remain > buffer.length)
- trans = buffer.length;
- else
- trans = (int) remain;
-
- int this_time_received = is.read(buffer, 0, trans);
-
- if (this_time_received < 0)
- {
- throw new IOException("Remote scp terminated connection unexpectedly");
- }
-
- fop.write(buffer, 0, this_time_received);
-
- remain -= this_time_received;
- }
- }
- finally
- {
- if (fop != null)
- fop.close();
- }
-
- readResponse(is);
-
- os.write(0x0);
- os.flush();
- }
- }
-
- /**
- * Copy a local file to a remote directory, uses mode 0600 when creating the
- * file on the remote side.
- *
- * @param localFile
- * Path and name of local file.
- * @param remoteTargetDirectory
- * Remote target directory. Use an empty string to specify the
- * default directory.
- *
- * @throws IOException
- */
- public void put(String localFile, String remoteTargetDirectory) throws IOException
- {
- put(new String[] { localFile }, remoteTargetDirectory, "0600");
- }
-
- /**
- * Copy a set of local files to a remote directory, uses mode 0600 when
- * creating files on the remote side.
- *
- * @param localFiles
- * Paths and names of local file names.
- * @param remoteTargetDirectory
- * Remote target directory. Use an empty string to specify the
- * default directory.
- *
- * @throws IOException
- */
-
- public void put(String[] localFiles, String remoteTargetDirectory) throws IOException
- {
- put(localFiles, remoteTargetDirectory, "0600");
- }
-
- /**
- * Copy a local file to a remote directory, uses the specified mode when
- * creating the file on the remote side.
- *
- * @param localFile
- * Path and name of local file.
- * @param remoteTargetDirectory
- * Remote target directory. Use an empty string to specify the
- * default directory.
- * @param mode
- * a four digit string (e.g., 0644, see "man chmod", "man open")
- * @throws IOException
- */
- public void put(String localFile, String remoteTargetDirectory, String mode) throws IOException
- {
- put(new String[] { localFile }, remoteTargetDirectory, mode);
- }
-
- /**
- * Copy a local file to a remote directory, uses the specified mode and
- * remote filename when creating the file on the remote side.
- *
- * @param localFile
- * Path and name of local file.
- * @param remoteFileName
- * The name of the file which will be created in the remote
- * target directory.
- * @param remoteTargetDirectory
- * Remote target directory. Use an empty string to specify the
- * default directory.
- * @param mode
- * a four digit string (e.g., 0644, see "man chmod", "man open")
- * @throws IOException
- */
- public void put(String localFile, String remoteFileName, String remoteTargetDirectory, String mode)
- throws IOException
- {
- put(new String[] { localFile }, new String[] { remoteFileName }, remoteTargetDirectory, mode);
- }
-
- /**
- * Create a remote file and copy the contents of the passed byte array into
- * it. Uses mode 0600 for creating the remote file.
- *
- * @param data
- * the data to be copied into the remote file.
- * @param remoteFileName
- * The name of the file which will be created in the remote
- * target directory.
- * @param remoteTargetDirectory
- * Remote target directory. Use an empty string to specify the
- * default directory.
- * @throws IOException
- */
-
- public void put(byte[] data, String remoteFileName, String remoteTargetDirectory) throws IOException
- {
- put(data, remoteFileName, remoteTargetDirectory, "0600");
- }
-
- /**
- * Create a remote file and copy the contents of the passed byte array into
- * it. The method use the specified mode when creating the file on the
- * remote side.
- *
- * @param data
- * the data to be copied into the remote file.
- * @param remoteFileName
- * The name of the file which will be created in the remote
- * target directory.
- * @param remoteTargetDirectory
- * Remote target directory. Use an empty string to specify the
- * default directory.
- * @param mode
- * a four digit string (e.g., 0644, see "man chmod", "man open")
- * @throws IOException
- */
- public void put(byte[] data, String remoteFileName, String remoteTargetDirectory, String mode) throws IOException
- {
- Session sess = null;
-
- if ((remoteFileName == null) || (remoteTargetDirectory == null) || (mode == null))
- throw new IllegalArgumentException("Null argument.");
-
- if (mode.length() != 4)
- throw new IllegalArgumentException("Invalid mode.");
-
- for (int i = 0; i < mode.length(); i++)
- if (Character.isDigit(mode.charAt(i)) == false)
- throw new IllegalArgumentException("Invalid mode.");
-
- remoteTargetDirectory = remoteTargetDirectory.trim();
- remoteTargetDirectory = (remoteTargetDirectory.length() > 0) ? remoteTargetDirectory : ".";
-
- String cmd = "scp -t -d " + remoteTargetDirectory;
-
- try
- {
- sess = conn.openSession();
- sess.execCommand(cmd);
- sendBytes(sess, data, remoteFileName, mode);
- }
- catch (IOException e)
- {
- throw (IOException) new IOException("Error during SCP transfer.").initCause(e);
- }
- finally
- {
- if (sess != null)
- sess.close();
- }
- }
-
- /**
- * Copy a set of local files to a remote directory, uses the specified mode
- * when creating the files on the remote side.
- *
- * @param localFiles
- * Paths and names of the local files.
- * @param remoteTargetDirectory
- * Remote target directory. Use an empty string to specify the
- * default directory.
- * @param mode
- * a four digit string (e.g., 0644, see "man chmod", "man open")
- * @throws IOException
- */
- public void put(String[] localFiles, String remoteTargetDirectory, String mode) throws IOException
- {
- put(localFiles, null, remoteTargetDirectory, mode);
- }
-
- public void put(String[] localFiles, String[] remoteFiles, String remoteTargetDirectory, String mode)
- throws IOException
- {
- Session sess = null;
-
- /*
- * remoteFiles may be null, indicating that the local filenames shall be
- * used
- */
-
- if ((localFiles == null) || (remoteTargetDirectory == null) || (mode == null))
- throw new IllegalArgumentException("Null argument.");
-
- if (mode.length() != 4)
- throw new IllegalArgumentException("Invalid mode.");
-
- for (int i = 0; i < mode.length(); i++)
- if (Character.isDigit(mode.charAt(i)) == false)
- throw new IllegalArgumentException("Invalid mode.");
-
- if (localFiles.length == 0)
- return;
-
- remoteTargetDirectory = remoteTargetDirectory.trim();
- remoteTargetDirectory = (remoteTargetDirectory.length() > 0) ? remoteTargetDirectory : ".";
-
- String cmd = "scp -t -d " + remoteTargetDirectory;
-
- for (int i = 0; i < localFiles.length; i++)
- {
- if (localFiles[i] == null)
- throw new IllegalArgumentException("Cannot accept null filename.");
- }
-
- try
- {
- sess = conn.openSession();
- sess.execCommand(cmd);
- sendFiles(sess, localFiles, remoteFiles, mode);
- }
- catch (IOException e)
- {
- throw (IOException) new IOException("Error during SCP transfer.").initCause(e);
- }
- finally
- {
- if (sess != null)
- sess.close();
- }
- }
-
- /**
- * Download a file from the remote server to a local directory.
- *
- * @param remoteFile
- * Path and name of the remote file.
- * @param localTargetDirectory
- * Local directory to put the downloaded file.
- *
- * @throws IOException
- */
- public void get(String remoteFile, String localTargetDirectory) throws IOException
- {
- get(new String[] { remoteFile }, localTargetDirectory);
- }
-
- /**
- * Download a file from the remote server and pipe its contents into an
- * <code>OutputStream</code>. Please note that, to enable flexible usage
- * of this method, the <code>OutputStream</code> will not be closed nor
- * flushed.
- *
- * @param remoteFile
- * Path and name of the remote file.
- * @param target
- * OutputStream where the contents of the file will be sent to.
- * @throws IOException
- */
- public void get(String remoteFile, OutputStream target) throws IOException
- {
- get(new String[] { remoteFile }, new OutputStream[] { target });
- }
-
- private void get(String remoteFiles[], OutputStream[] targets) throws IOException
- {
- Session sess = null;
-
- if ((remoteFiles == null) || (targets == null))
- throw new IllegalArgumentException("Null argument.");
-
- if (remoteFiles.length != targets.length)
- throw new IllegalArgumentException("Length of arguments does not match.");
-
- if (remoteFiles.length == 0)
- return;
-
- String cmd = "scp -f";
-
- for (int i = 0; i < remoteFiles.length; i++)
- {
- if (remoteFiles[i] == null)
- throw new IllegalArgumentException("Cannot accept null filename.");
-
- String tmp = remoteFiles[i].trim();
-
- if (tmp.length() == 0)
- throw new IllegalArgumentException("Cannot accept empty filename.");
-
- cmd += (" " + tmp);
- }
-
- try
- {
- sess = conn.openSession();
- sess.execCommand(cmd);
- receiveFiles(sess, targets);
- }
- catch (IOException e)
- {
- throw (IOException) new IOException("Error during SCP transfer.").initCause(e);
- }
- finally
- {
- if (sess != null)
- sess.close();
- }
- }
-
- /**
- * Download a set of files from the remote server to a local directory.
- *
- * @param remoteFiles
- * Paths and names of the remote files.
- * @param localTargetDirectory
- * Local directory to put the downloaded files.
- *
- * @throws IOException
- */
- public void get(String remoteFiles[], String localTargetDirectory) throws IOException
- {
- Session sess = null;
-
- if ((remoteFiles == null) || (localTargetDirectory == null))
- throw new IllegalArgumentException("Null argument.");
-
- if (remoteFiles.length == 0)
- return;
-
- String cmd = "scp -f";
-
- for (int i = 0; i < remoteFiles.length; i++)
- {
- if (remoteFiles[i] == null)
- throw new IllegalArgumentException("Cannot accept null filename.");
-
- String tmp = remoteFiles[i].trim();
-
- if (tmp.length() == 0)
- throw new IllegalArgumentException("Cannot accept empty filename.");
-
- cmd += (" " + tmp);
- }
-
- try
- {
- sess = conn.openSession();
- sess.execCommand(cmd);
- receiveFiles(sess, remoteFiles, localTargetDirectory);
- }
- catch (IOException e)
- {
- throw (IOException) new IOException("Error during SCP transfer.").initCause(e);
- }
- finally
- {
- if (sess != null)
- sess.close();
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/SFTPException.java b/app/src/main/java/com/trilead/ssh2/SFTPException.java
deleted file mode 100644
index d97723f..0000000
--- a/app/src/main/java/com/trilead/ssh2/SFTPException.java
+++ /dev/null
@@ -1,91 +0,0 @@
-
-package com.trilead.ssh2;
-
-import java.io.IOException;
-
-import com.trilead.ssh2.sftp.ErrorCodes;
-
-
-/**
- * Used in combination with the SFTPv3Client. This exception wraps
- * error messages sent by the SFTP server.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: SFTPException.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-
-public class SFTPException extends IOException
-{
- private static final long serialVersionUID = 578654644222421811L;
-
- private final String sftpErrorMessage;
- private final int sftpErrorCode;
-
- private static String constructMessage(String s, int errorCode)
- {
- String[] detail = ErrorCodes.getDescription(errorCode);
-
- if (detail == null)
- return s + " (UNKNOW SFTP ERROR CODE)";
-
- return s + " (" + detail[0] + ": " + detail[1] + ")";
- }
-
- SFTPException(String msg, int errorCode)
- {
- super(constructMessage(msg, errorCode));
- sftpErrorMessage = msg;
- sftpErrorCode = errorCode;
- }
-
- /**
- * Get the error message sent by the server. Often, this
- * message does not help a lot (e.g., "failure").
- *
- * @return the plain string as sent by the server.
- */
- public String getServerErrorMessage()
- {
- return sftpErrorMessage;
- }
-
- /**
- * Get the error code sent by the server.
- *
- * @return an error code as defined in the SFTP specs.
- */
- public int getServerErrorCode()
- {
- return sftpErrorCode;
- }
-
- /**
- * Get the symbolic name of the error code as given in the SFTP specs.
- *
- * @return e.g., "SSH_FX_INVALID_FILENAME".
- */
- public String getServerErrorCodeSymbol()
- {
- String[] detail = ErrorCodes.getDescription(sftpErrorCode);
-
- if (detail == null)
- return "UNKNOW SFTP ERROR CODE " + sftpErrorCode;
-
- return detail[0];
- }
-
- /**
- * Get the description of the error code as given in the SFTP specs.
- *
- * @return e.g., "The filename is not valid."
- */
- public String getServerErrorCodeVerbose()
- {
- String[] detail = ErrorCodes.getDescription(sftpErrorCode);
-
- if (detail == null)
- return "The error code " + sftpErrorCode + " is unknown.";
-
- return detail[1];
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/SFTPv3Client.java b/app/src/main/java/com/trilead/ssh2/SFTPv3Client.java
deleted file mode 100644
index 06796e9..0000000
--- a/app/src/main/java/com/trilead/ssh2/SFTPv3Client.java
+++ /dev/null
@@ -1,1388 +0,0 @@
-
-package com.trilead.ssh2;
-
-import java.io.BufferedOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.nio.charset.Charset;
-import java.util.HashMap;
-import java.util.Vector;
-
-import com.trilead.ssh2.packets.TypesReader;
-import com.trilead.ssh2.packets.TypesWriter;
-import com.trilead.ssh2.sftp.AttribFlags;
-import com.trilead.ssh2.sftp.ErrorCodes;
-import com.trilead.ssh2.sftp.Packet;
-
-
-/**
- * A <code>SFTPv3Client</code> represents a SFTP (protocol version 3)
- * client connection tunnelled over a SSH-2 connection. This is a very simple
- * (synchronous) implementation.
- * <p>
- * Basically, most methods in this class map directly to one of
- * the packet types described in draft-ietf-secsh-filexfer-02.txt.
- * <p>
- * Note: this is experimental code.
- * <p>
- * Error handling: the methods of this class throw IOExceptions. However, unless
- * there is catastrophic failure, exceptions of the type {@link SFTPv3Client} will
- * be thrown (a subclass of IOException). Therefore, you can implement more verbose
- * behavior by checking if a thrown exception if of this type. If yes, then you
- * can cast the exception and access detailed information about the failure.
- * <p>
- * Notes about file names, directory names and paths, copy-pasted
- * from the specs:
- * <ul>
- * <li>SFTP v3 represents file names as strings. File names are
- * assumed to use the slash ('/') character as a directory separator.</li>
- * <li>File names starting with a slash are "absolute", and are relative to
- * the root of the file system. Names starting with any other character
- * are relative to the user's default directory (home directory).</li>
- * <li>Servers SHOULD interpret a path name component ".." as referring to
- * the parent directory, and "." as referring to the current directory.
- * If the server implementation limits access to certain parts of the
- * file system, it must be extra careful in parsing file names when
- * enforcing such restrictions. There have been numerous reported
- * security bugs where a ".." in a path name has allowed access outside
- * the intended area.</li>
- * <li>An empty path name is valid, and it refers to the user's default
- * directory (usually the user's home directory).</li>
- * </ul>
- * <p>
- * If you are still not tired then please go on and read the comment for
- * {@link #setCharset(String)}.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: SFTPv3Client.java,v 1.3 2008/04/01 12:38:09 cplattne Exp $
- */
-public class SFTPv3Client
-{
- final Connection conn;
- final Session sess;
- final PrintStream debug;
-
- boolean flag_closed = false;
-
- InputStream is;
- OutputStream os;
-
- int protocol_version = 0;
- HashMap server_extensions = new HashMap();
-
- int next_request_id = 1000;
-
- String charsetName = null;
-
- /**
- * Create a SFTP v3 client.
- *
- * @param conn The underlying SSH-2 connection to be used.
- * @param debug
- * @throws IOException
- *
- * @deprecated this constructor (debug version) will disappear in the future,
- * use {@link #SFTPv3Client(Connection)} instead.
- */
- public SFTPv3Client(Connection conn, PrintStream debug) throws IOException
- {
- if (conn == null)
- throw new IllegalArgumentException("Cannot accept null argument!");
-
- this.conn = conn;
- this.debug = debug;
-
- if (debug != null)
- debug.println("Opening session and starting SFTP subsystem.");
-
- sess = conn.openSession();
- sess.startSubSystem("sftp");
-
- is = sess.getStdout();
- os = new BufferedOutputStream(sess.getStdin(), 2048);
-
- if ((is == null) || (os == null))
- throw new IOException("There is a problem with the streams of the underlying channel.");
-
- init();
- }
-
- /**
- * Create a SFTP v3 client.
- *
- * @param conn The underlying SSH-2 connection to be used.
- * @throws IOException
- */
- public SFTPv3Client(Connection conn) throws IOException
- {
- this(conn, null);
- }
-
- /**
- * Set the charset used to convert between Java Unicode Strings and byte encodings
- * used by the server for paths and file names. Unfortunately, the SFTP v3 draft
- * says NOTHING about such conversions (well, with the exception of error messages
- * which have to be in UTF-8). Newer drafts specify to use UTF-8 for file names
- * (if I remember correctly). However, a quick test using OpenSSH serving a EXT-3
- * filesystem has shown that UTF-8 seems to be a bad choice for SFTP v3 (tested with
- * filenames containing german umlauts). "windows-1252" seems to work better for Europe.
- * Luckily, "windows-1252" is the platform default in my case =).
- * <p>
- * If you don't set anything, then the platform default will be used (this is the default
- * behavior).
- *
- * @see #getCharset()
- *
- * @param charset the name of the charset to be used or <code>null</code> to use the platform's
- * default encoding.
- * @throws IOException
- */
- public void setCharset(String charset) throws IOException
- {
- if (charset == null)
- {
- charsetName = charset;
- return;
- }
-
- try
- {
- Charset.forName(charset);
- }
- catch (Exception e)
- {
- throw (IOException) new IOException("This charset is not supported").initCause(e);
- }
- charsetName = charset;
- }
-
- /**
- * The currently used charset for filename encoding/decoding.
- *
- * @see #setCharset(String)
- *
- * @return The name of the charset (<code>null</code> if the platform's default charset is being used)
- */
- public String getCharset()
- {
- return charsetName;
- }
-
- private final void checkHandleValidAndOpen(SFTPv3FileHandle handle) throws IOException
- {
- if (handle.client != this)
- throw new IOException("The file handle was created with another SFTPv3FileHandle instance.");
-
- if (handle.isClosed == true)
- throw new IOException("The file handle is closed.");
- }
-
- private final void sendMessage(int type, int requestId, byte[] msg, int off, int len) throws IOException
- {
- int msglen = len + 1;
-
- if (type != Packet.SSH_FXP_INIT)
- msglen += 4;
-
- os.write(msglen >> 24);
- os.write(msglen >> 16);
- os.write(msglen >> 8);
- os.write(msglen);
- os.write(type);
-
- if (type != Packet.SSH_FXP_INIT)
- {
- os.write(requestId >> 24);
- os.write(requestId >> 16);
- os.write(requestId >> 8);
- os.write(requestId);
- }
-
- os.write(msg, off, len);
- os.flush();
- }
-
- private final void sendMessage(int type, int requestId, byte[] msg) throws IOException
- {
- sendMessage(type, requestId, msg, 0, msg.length);
- }
-
- private final void readBytes(byte[] buff, int pos, int len) throws IOException
- {
- while (len > 0)
- {
- int count = is.read(buff, pos, len);
- if (count < 0)
- throw new IOException("Unexpected end of sftp stream.");
- if ((count == 0) || (count > len))
- throw new IOException("Underlying stream implementation is bogus!");
- len -= count;
- pos += count;
- }
- }
-
- /**
- * Read a message and guarantee that the <b>contents</b> is not larger than
- * <code>maxlen</code> bytes.
- * <p>
- * Note: receiveMessage(34000) actually means that the message may be up to 34004
- * bytes (the length attribute preceeding the contents is 4 bytes).
- *
- * @param maxlen
- * @return the message contents
- * @throws IOException
- */
- private final byte[] receiveMessage(int maxlen) throws IOException
- {
- byte[] msglen = new byte[4];
-
- readBytes(msglen, 0, 4);
-
- int len = (((msglen[0] & 0xff) << 24) | ((msglen[1] & 0xff) << 16) | ((msglen[2] & 0xff) << 8) | (msglen[3] & 0xff));
-
- if ((len > maxlen) || (len <= 0))
- throw new IOException("Illegal sftp packet len: " + len);
-
- byte[] msg = new byte[len];
-
- readBytes(msg, 0, len);
-
- return msg;
- }
-
- private final int generateNextRequestID()
- {
- synchronized (this)
- {
- return next_request_id++;
- }
- }
-
- private final void closeHandle(byte[] handle) throws IOException
- {
- int req_id = generateNextRequestID();
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(handle, 0, handle.length);
-
- sendMessage(Packet.SSH_FXP_CLOSE, req_id, tw.getBytes());
-
- expectStatusOKMessage(req_id);
- }
-
- private SFTPv3FileAttributes readAttrs(TypesReader tr) throws IOException
- {
- /*
- * uint32 flags
- * uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE
- * uint32 uid present only if flag SSH_FILEXFER_ATTR_V3_UIDGID
- * uint32 gid present only if flag SSH_FILEXFER_ATTR_V3_UIDGID
- * uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS
- * uint32 atime present only if flag SSH_FILEXFER_ATTR_V3_ACMODTIME
- * uint32 mtime present only if flag SSH_FILEXFER_ATTR_V3_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
- */
-
- SFTPv3FileAttributes fa = new SFTPv3FileAttributes();
-
- int flags = tr.readUINT32();
-
- if ((flags & AttribFlags.SSH_FILEXFER_ATTR_SIZE) != 0)
- {
- if (debug != null)
- debug.println("SSH_FILEXFER_ATTR_SIZE");
- fa.size = new Long(tr.readUINT64());
- }
-
- if ((flags & AttribFlags.SSH_FILEXFER_ATTR_V3_UIDGID) != 0)
- {
- if (debug != null)
- debug.println("SSH_FILEXFER_ATTR_V3_UIDGID");
- fa.uid = new Integer(tr.readUINT32());
- fa.gid = new Integer(tr.readUINT32());
- }
-
- if ((flags & AttribFlags.SSH_FILEXFER_ATTR_PERMISSIONS) != 0)
- {
- if (debug != null)
- debug.println("SSH_FILEXFER_ATTR_PERMISSIONS");
- fa.permissions = new Integer(tr.readUINT32());
- }
-
- if ((flags & AttribFlags.SSH_FILEXFER_ATTR_V3_ACMODTIME) != 0)
- {
- if (debug != null)
- debug.println("SSH_FILEXFER_ATTR_V3_ACMODTIME");
- fa.atime = new Long(((long)tr.readUINT32()) & 0xffffffffl);
- fa.mtime = new Long(((long)tr.readUINT32()) & 0xffffffffl);
-
- }
-
- if ((flags & AttribFlags.SSH_FILEXFER_ATTR_EXTENDED) != 0)
- {
- int count = tr.readUINT32();
-
- if (debug != null)
- debug.println("SSH_FILEXFER_ATTR_EXTENDED (" + count + ")");
-
- /* Read it anyway to detect corrupt packets */
-
- while (count > 0)
- {
- tr.readByteString();
- tr.readByteString();
- count--;
- }
- }
-
- return fa;
- }
-
- /**
- * Retrieve the file attributes of an open file.
- *
- * @param handle a SFTPv3FileHandle handle.
- * @return a SFTPv3FileAttributes object.
- * @throws IOException
- */
- public SFTPv3FileAttributes fstat(SFTPv3FileHandle handle) throws IOException
- {
- checkHandleValidAndOpen(handle);
-
- int req_id = generateNextRequestID();
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(handle.fileHandle, 0, handle.fileHandle.length);
-
- if (debug != null)
- {
- debug.println("Sending SSH_FXP_FSTAT...");
- debug.flush();
- }
-
- sendMessage(Packet.SSH_FXP_FSTAT, req_id, tw.getBytes());
-
- byte[] resp = receiveMessage(34000);
-
- if (debug != null)
- {
- debug.println("Got REPLY.");
- debug.flush();
- }
-
- TypesReader tr = new TypesReader(resp);
-
- int t = tr.readByte();
-
- int rep_id = tr.readUINT32();
- if (rep_id != req_id)
- throw new IOException("The server sent an invalid id field.");
-
- if (t == Packet.SSH_FXP_ATTRS)
- {
- return readAttrs(tr);
- }
-
- if (t != Packet.SSH_FXP_STATUS)
- throw new IOException("The SFTP server sent an unexpected packet type (" + t + ")");
-
- int errorCode = tr.readUINT32();
-
- throw new SFTPException(tr.readString(), errorCode);
- }
-
- private SFTPv3FileAttributes statBoth(String path, int statMethod) throws IOException
- {
- int req_id = generateNextRequestID();
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(path, charsetName);
-
- if (debug != null)
- {
- debug.println("Sending SSH_FXP_STAT/SSH_FXP_LSTAT...");
- debug.flush();
- }
-
- sendMessage(statMethod, req_id, tw.getBytes());
-
- byte[] resp = receiveMessage(34000);
-
- if (debug != null)
- {
- debug.println("Got REPLY.");
- debug.flush();
- }
-
- TypesReader tr = new TypesReader(resp);
-
- int t = tr.readByte();
-
- int rep_id = tr.readUINT32();
- if (rep_id != req_id)
- throw new IOException("The server sent an invalid id field.");
-
- if (t == Packet.SSH_FXP_ATTRS)
- {
- return readAttrs(tr);
- }
-
- if (t != Packet.SSH_FXP_STATUS)
- throw new IOException("The SFTP server sent an unexpected packet type (" + t + ")");
-
- int errorCode = tr.readUINT32();
-
- throw new SFTPException(tr.readString(), errorCode);
- }
-
- /**
- * Retrieve the file attributes of a file. This method
- * follows symbolic links on the server.
- *
- * @see #lstat(String)
- *
- * @param path See the {@link SFTPv3Client comment} for the class for more details.
- * @return a SFTPv3FileAttributes object.
- * @throws IOException
- */
- public SFTPv3FileAttributes stat(String path) throws IOException
- {
- return statBoth(path, Packet.SSH_FXP_STAT);
- }
-
- /**
- * Retrieve the file attributes of a file. This method
- * does NOT follow symbolic links on the server.
- *
- * @see #stat(String)
- *
- * @param path See the {@link SFTPv3Client comment} for the class for more details.
- * @return a SFTPv3FileAttributes object.
- * @throws IOException
- */
- public SFTPv3FileAttributes lstat(String path) throws IOException
- {
- return statBoth(path, Packet.SSH_FXP_LSTAT);
- }
-
- /**
- * Read the target of a symbolic link.
- *
- * @param path See the {@link SFTPv3Client comment} for the class for more details.
- * @return The target of the link.
- * @throws IOException
- */
- public String readLink(String path) throws IOException
- {
- int req_id = generateNextRequestID();
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(path, charsetName);
-
- if (debug != null)
- {
- debug.println("Sending SSH_FXP_READLINK...");
- debug.flush();
- }
-
- sendMessage(Packet.SSH_FXP_READLINK, req_id, tw.getBytes());
-
- byte[] resp = receiveMessage(34000);
-
- if (debug != null)
- {
- debug.println("Got REPLY.");
- debug.flush();
- }
-
- TypesReader tr = new TypesReader(resp);
-
- int t = tr.readByte();
-
- int rep_id = tr.readUINT32();
- if (rep_id != req_id)
- throw new IOException("The server sent an invalid id field.");
-
- if (t == Packet.SSH_FXP_NAME)
- {
- int count = tr.readUINT32();
-
- if (count != 1)
- throw new IOException("The server sent an invalid SSH_FXP_NAME packet.");
-
- return tr.readString(charsetName);
- }
-
- if (t != Packet.SSH_FXP_STATUS)
- throw new IOException("The SFTP server sent an unexpected packet type (" + t + ")");
-
- int errorCode = tr.readUINT32();
-
- throw new SFTPException(tr.readString(), errorCode);
- }
-
- private void expectStatusOKMessage(int id) throws IOException
- {
- byte[] resp = receiveMessage(34000);
-
- if (debug != null)
- {
- debug.println("Got REPLY.");
- debug.flush();
- }
-
- TypesReader tr = new TypesReader(resp);
-
- int t = tr.readByte();
-
- int rep_id = tr.readUINT32();
- if (rep_id != id)
- throw new IOException("The server sent an invalid id field.");
-
- if (t != Packet.SSH_FXP_STATUS)
- throw new IOException("The SFTP server sent an unexpected packet type (" + t + ")");
-
- int errorCode = tr.readUINT32();
-
- if (errorCode == ErrorCodes.SSH_FX_OK)
- return;
-
- throw new SFTPException(tr.readString(), errorCode);
- }
-
- /**
- * Modify the attributes of a file. Used for operations such as changing
- * the ownership, permissions or access times, as well as for truncating a file.
- *
- * @param path See the {@link SFTPv3Client comment} for the class for more details.
- * @param attr A SFTPv3FileAttributes object. Specifies the modifications to be
- * made to the attributes of the file. Empty fields will be ignored.
- * @throws IOException
- */
- public void setstat(String path, SFTPv3FileAttributes attr) throws IOException
- {
- int req_id = generateNextRequestID();
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(path, charsetName);
- tw.writeBytes(createAttrs(attr));
-
- if (debug != null)
- {
- debug.println("Sending SSH_FXP_SETSTAT...");
- debug.flush();
- }
-
- sendMessage(Packet.SSH_FXP_SETSTAT, req_id, tw.getBytes());
-
- expectStatusOKMessage(req_id);
- }
-
- /**
- * Modify the attributes of a file. Used for operations such as changing
- * the ownership, permissions or access times, as well as for truncating a file.
- *
- * @param handle a SFTPv3FileHandle handle
- * @param attr A SFTPv3FileAttributes object. Specifies the modifications to be
- * made to the attributes of the file. Empty fields will be ignored.
- * @throws IOException
- */
- public void fsetstat(SFTPv3FileHandle handle, SFTPv3FileAttributes attr) throws IOException
- {
- checkHandleValidAndOpen(handle);
-
- int req_id = generateNextRequestID();
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(handle.fileHandle, 0, handle.fileHandle.length);
- tw.writeBytes(createAttrs(attr));
-
- if (debug != null)
- {
- debug.println("Sending SSH_FXP_FSETSTAT...");
- debug.flush();
- }
-
- sendMessage(Packet.SSH_FXP_FSETSTAT, req_id, tw.getBytes());
-
- expectStatusOKMessage(req_id);
- }
-
- /**
- * Create a symbolic link on the server. Creates a link "src" that points
- * to "target".
- *
- * @param src See the {@link SFTPv3Client comment} for the class for more details.
- * @param target See the {@link SFTPv3Client comment} for the class for more details.
- * @throws IOException
- */
- public void createSymlink(String src, String target) throws IOException
- {
- int req_id = generateNextRequestID();
-
- /* Either I am too stupid to understand the SFTP draft
- * or the OpenSSH guys changed the semantics of src and target.
- */
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(target, charsetName);
- tw.writeString(src, charsetName);
-
- if (debug != null)
- {
- debug.println("Sending SSH_FXP_SYMLINK...");
- debug.flush();
- }
-
- sendMessage(Packet.SSH_FXP_SYMLINK, req_id, tw.getBytes());
-
- expectStatusOKMessage(req_id);
- }
-
- /**
- * Have the server canonicalize any given path name to an absolute path.
- * This is useful for converting path names containing ".." components or
- * relative pathnames without a leading slash into absolute paths.
- *
- * @param path See the {@link SFTPv3Client comment} for the class for more details.
- * @return An absolute path.
- * @throws IOException
- */
- public String canonicalPath(String path) throws IOException
- {
- int req_id = generateNextRequestID();
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(path, charsetName);
-
- if (debug != null)
- {
- debug.println("Sending SSH_FXP_REALPATH...");
- debug.flush();
- }
-
- sendMessage(Packet.SSH_FXP_REALPATH, req_id, tw.getBytes());
-
- byte[] resp = receiveMessage(34000);
-
- if (debug != null)
- {
- debug.println("Got REPLY.");
- debug.flush();
- }
-
- TypesReader tr = new TypesReader(resp);
-
- int t = tr.readByte();
-
- int rep_id = tr.readUINT32();
- if (rep_id != req_id)
- throw new IOException("The server sent an invalid id field.");
-
- if (t == Packet.SSH_FXP_NAME)
- {
- int count = tr.readUINT32();
-
- if (count != 1)
- throw new IOException("The server sent an invalid SSH_FXP_NAME packet.");
-
- return tr.readString(charsetName);
- }
-
- if (t != Packet.SSH_FXP_STATUS)
- throw new IOException("The SFTP server sent an unexpected packet type (" + t + ")");
-
- int errorCode = tr.readUINT32();
-
- throw new SFTPException(tr.readString(), errorCode);
- }
-
- private final Vector scanDirectory(byte[] handle) throws IOException
- {
- Vector files = new Vector();
-
- while (true)
- {
- int req_id = generateNextRequestID();
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(handle, 0, handle.length);
-
- if (debug != null)
- {
- debug.println("Sending SSH_FXP_READDIR...");
- debug.flush();
- }
-
- sendMessage(Packet.SSH_FXP_READDIR, req_id, tw.getBytes());
-
- /* Some servers send here a packet with size > 34000 */
- /* To whom it may concern: please learn to read the specs. */
-
- byte[] resp = receiveMessage(65536);
-
- if (debug != null)
- {
- debug.println("Got REPLY.");
- debug.flush();
- }
-
- TypesReader tr = new TypesReader(resp);
-
- int t = tr.readByte();
-
- int rep_id = tr.readUINT32();
- if (rep_id != req_id)
- throw new IOException("The server sent an invalid id field.");
-
- if (t == Packet.SSH_FXP_NAME)
- {
- int count = tr.readUINT32();
-
- if (debug != null)
- debug.println("Parsing " + count + " name entries...");
-
- while (count > 0)
- {
- SFTPv3DirectoryEntry dirEnt = new SFTPv3DirectoryEntry();
-
- dirEnt.filename = tr.readString(charsetName);
- dirEnt.longEntry = tr.readString(charsetName);
-
- dirEnt.attributes = readAttrs(tr);
- files.addElement(dirEnt);
-
- if (debug != null)
- debug.println("File: '" + dirEnt.filename + "'");
- count--;
- }
- continue;
- }
-
- if (t != Packet.SSH_FXP_STATUS)
- throw new IOException("The SFTP server sent an unexpected packet type (" + t + ")");
-
- int errorCode = tr.readUINT32();
-
- if (errorCode == ErrorCodes.SSH_FX_EOF)
- return files;
-
- throw new SFTPException(tr.readString(), errorCode);
- }
- }
-
- private final byte[] openDirectory(String path) throws IOException
- {
- int req_id = generateNextRequestID();
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(path, charsetName);
-
- if (debug != null)
- {
- debug.println("Sending SSH_FXP_OPENDIR...");
- debug.flush();
- }
-
- sendMessage(Packet.SSH_FXP_OPENDIR, req_id, tw.getBytes());
-
- byte[] resp = receiveMessage(34000);
-
- TypesReader tr = new TypesReader(resp);
-
- int t = tr.readByte();
-
- int rep_id = tr.readUINT32();
- if (rep_id != req_id)
- throw new IOException("The server sent an invalid id field.");
-
- if (t == Packet.SSH_FXP_HANDLE)
- {
- if (debug != null)
- {
- debug.println("Got SSH_FXP_HANDLE.");
- debug.flush();
- }
-
- byte[] handle = tr.readByteString();
- return handle;
- }
-
- if (t != Packet.SSH_FXP_STATUS)
- throw new IOException("The SFTP server sent an unexpected packet type (" + t + ")");
-
- int errorCode = tr.readUINT32();
- String errorMessage = tr.readString();
-
- throw new SFTPException(errorMessage, errorCode);
- }
-
- private final String expandString(byte[] b, int off, int len)
- {
- StringBuffer sb = new StringBuffer();
-
- for (int i = 0; i < len; i++)
- {
- int c = b[off + i] & 0xff;
-
- if ((c >= 32) && (c <= 126))
- {
- sb.append((char) c);
- }
- else
- {
- sb.append("{0x" + Integer.toHexString(c) + "}");
- }
- }
-
- return sb.toString();
- }
-
- private void init() throws IOException
- {
- /* Send SSH_FXP_INIT (version 3) */
-
- final int client_version = 3;
-
- if (debug != null)
- debug.println("Sending SSH_FXP_INIT (" + client_version + ")...");
-
- TypesWriter tw = new TypesWriter();
- tw.writeUINT32(client_version);
- sendMessage(Packet.SSH_FXP_INIT, 0, tw.getBytes());
-
- /* Receive SSH_FXP_VERSION */
-
- if (debug != null)
- debug.println("Waiting for SSH_FXP_VERSION...");
-
- TypesReader tr = new TypesReader(receiveMessage(34000)); /* Should be enough for any reasonable server */
-
- int type = tr.readByte();
-
- if (type != Packet.SSH_FXP_VERSION)
- {
- throw new IOException("The server did not send a SSH_FXP_VERSION packet (got " + type + ")");
- }
-
- protocol_version = tr.readUINT32();
-
- if (debug != null)
- debug.println("SSH_FXP_VERSION: protocol_version = " + protocol_version);
-
- if (protocol_version != 3)
- throw new IOException("Server version " + protocol_version + " is currently not supported");
-
- /* Read and save extensions (if any) for later use */
-
- while (tr.remain() != 0)
- {
- String name = tr.readString();
- byte[] value = tr.readByteString();
- server_extensions.put(name, value);
-
- if (debug != null)
- debug.println("SSH_FXP_VERSION: extension: " + name + " = '" + expandString(value, 0, value.length)
- + "'");
- }
- }
-
- /**
- * Returns the negotiated SFTP protocol version between the client and the server.
- *
- * @return SFTP protocol version, i.e., "3".
- *
- */
- public int getProtocolVersion()
- {
- return protocol_version;
- }
-
- /**
- * Close this SFTP session. NEVER forget to call this method to free up
- * resources - even if you got an exception from one of the other methods.
- * Sometimes these other methods may throw an exception, saying that the
- * underlying channel is closed (this can happen, e.g., if the other server
- * sent a close message.) However, as long as you have not called the
- * <code>close()</code> method, you are likely wasting resources.
- *
- */
- public void close()
- {
- sess.close();
- }
-
- /**
- * List the contents of a directory.
- *
- * @param dirName See the {@link SFTPv3Client comment} for the class for more details.
- * @return A Vector containing {@link SFTPv3DirectoryEntry} objects.
- * @throws IOException
- */
- public Vector ls(String dirName) throws IOException
- {
- byte[] handle = openDirectory(dirName);
- Vector result = scanDirectory(handle);
- closeHandle(handle);
- return result;
- }
-
- /**
- * Create a new directory.
- *
- * @param dirName See the {@link SFTPv3Client comment} for the class for more details.
- * @param posixPermissions the permissions for this directory, e.g., "0700" (remember that
- * this is octal noation). The server will likely apply a umask.
- *
- * @throws IOException
- */
- public void mkdir(String dirName, int posixPermissions) throws IOException
- {
- int req_id = generateNextRequestID();
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(dirName, charsetName);
- tw.writeUINT32(AttribFlags.SSH_FILEXFER_ATTR_PERMISSIONS);
- tw.writeUINT32(posixPermissions);
-
- sendMessage(Packet.SSH_FXP_MKDIR, req_id, tw.getBytes());
-
- expectStatusOKMessage(req_id);
- }
-
- /**
- * Remove a file.
- *
- * @param fileName See the {@link SFTPv3Client comment} for the class for more details.
- * @throws IOException
- */
- public void rm(String fileName) throws IOException
- {
- int req_id = generateNextRequestID();
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(fileName, charsetName);
-
- sendMessage(Packet.SSH_FXP_REMOVE, req_id, tw.getBytes());
-
- expectStatusOKMessage(req_id);
- }
-
- /**
- * Remove an empty directory.
- *
- * @param dirName See the {@link SFTPv3Client comment} for the class for more details.
- * @throws IOException
- */
- public void rmdir(String dirName) throws IOException
- {
- int req_id = generateNextRequestID();
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(dirName, charsetName);
-
- sendMessage(Packet.SSH_FXP_RMDIR, req_id, tw.getBytes());
-
- expectStatusOKMessage(req_id);
- }
-
- /**
- * Move a file or directory.
- *
- * @param oldPath See the {@link SFTPv3Client comment} for the class for more details.
- * @param newPath See the {@link SFTPv3Client comment} for the class for more details.
- * @throws IOException
- */
- public void mv(String oldPath, String newPath) throws IOException
- {
- int req_id = generateNextRequestID();
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(oldPath, charsetName);
- tw.writeString(newPath, charsetName);
-
- sendMessage(Packet.SSH_FXP_RENAME, req_id, tw.getBytes());
-
- expectStatusOKMessage(req_id);
- }
-
- /**
- * Open a file for reading.
- *
- * @param fileName See the {@link SFTPv3Client comment} for the class for more details.
- * @return a SFTPv3FileHandle handle
- * @throws IOException
- */
- public SFTPv3FileHandle openFileRO(String fileName) throws IOException
- {
- return openFile(fileName, 0x00000001, null); // SSH_FXF_READ
- }
-
- /**
- * Open a file for reading and writing.
- *
- * @param fileName See the {@link SFTPv3Client comment} for the class for more details.
- * @return a SFTPv3FileHandle handle
- * @throws IOException
- */
- public SFTPv3FileHandle openFileRW(String fileName) throws IOException
- {
- return openFile(fileName, 0x00000003, null); // SSH_FXF_READ | SSH_FXF_WRITE
- }
-
- // Append is broken (already in the specification, because there is no way to
- // send a write operation (what offset to use??))
- // public SFTPv3FileHandle openFileRWAppend(String fileName) throws IOException
- // {
- // return openFile(fileName, 0x00000007, null); // SSH_FXF_READ | SSH_FXF_WRITE | SSH_FXF_APPEND
- // }
-
- /**
- * Create a file and open it for reading and writing.
- * Same as {@link #createFile(String, SFTPv3FileAttributes) createFile(fileName, null)}.
- *
- * @param fileName See the {@link SFTPv3Client comment} for the class for more details.
- * @return a SFTPv3FileHandle handle
- * @throws IOException
- */
- public SFTPv3FileHandle createFile(String fileName) throws IOException
- {
- return createFile(fileName, null);
- }
-
- /**
- * Create a file and open it for reading and writing.
- * You can specify the default attributes of the file (the server may or may
- * not respect your wishes).
- *
- * @param fileName See the {@link SFTPv3Client comment} for the class for more details.
- * @param attr may be <code>null</code> to use server defaults. Probably only
- * the <code>uid</code>, <code>gid</code> and <code>permissions</code>
- * (remember the server may apply a umask) entries of the {@link SFTPv3FileHandle}
- * structure make sense. You need only to set those fields where you want
- * to override the server's defaults.
- * @return a SFTPv3FileHandle handle
- * @throws IOException
- */
- public SFTPv3FileHandle createFile(String fileName, SFTPv3FileAttributes attr) throws IOException
- {
- return openFile(fileName, 0x00000008 | 0x00000003, attr); // SSH_FXF_CREAT | SSH_FXF_READ | SSH_FXF_WRITE
- }
-
- /**
- * Create a file (truncate it if it already exists) and open it for reading and writing.
- * Same as {@link #createFileTruncate(String, SFTPv3FileAttributes) createFileTruncate(fileName, null)}.
- *
- * @param fileName See the {@link SFTPv3Client comment} for the class for more details.
- * @return a SFTPv3FileHandle handle
- * @throws IOException
- */
- public SFTPv3FileHandle createFileTruncate(String fileName) throws IOException
- {
- return createFileTruncate(fileName, null);
- }
-
- /**
- * reate a file (truncate it if it already exists) and open it for reading and writing.
- * You can specify the default attributes of the file (the server may or may
- * not respect your wishes).
- *
- * @param fileName See the {@link SFTPv3Client comment} for the class for more details.
- * @param attr may be <code>null</code> to use server defaults. Probably only
- * the <code>uid</code>, <code>gid</code> and <code>permissions</code>
- * (remember the server may apply a umask) entries of the {@link SFTPv3FileHandle}
- * structure make sense. You need only to set those fields where you want
- * to override the server's defaults.
- * @return a SFTPv3FileHandle handle
- * @throws IOException
- */
- public SFTPv3FileHandle createFileTruncate(String fileName, SFTPv3FileAttributes attr) throws IOException
- {
- return openFile(fileName, 0x00000018 | 0x00000003, attr); // SSH_FXF_CREAT | SSH_FXF_TRUNC | SSH_FXF_READ | SSH_FXF_WRITE
- }
-
- private byte[] createAttrs(SFTPv3FileAttributes attr)
- {
- TypesWriter tw = new TypesWriter();
-
- int attrFlags = 0;
-
- if (attr == null)
- {
- tw.writeUINT32(0);
- }
- else
- {
- if (attr.size != null)
- attrFlags = attrFlags | AttribFlags.SSH_FILEXFER_ATTR_SIZE;
-
- if ((attr.uid != null) && (attr.gid != null))
- attrFlags = attrFlags | AttribFlags.SSH_FILEXFER_ATTR_V3_UIDGID;
-
- if (attr.permissions != null)
- attrFlags = attrFlags | AttribFlags.SSH_FILEXFER_ATTR_PERMISSIONS;
-
- if ((attr.atime != null) && (attr.mtime != null))
- attrFlags = attrFlags | AttribFlags.SSH_FILEXFER_ATTR_V3_ACMODTIME;
-
- tw.writeUINT32(attrFlags);
-
- if (attr.size != null)
- tw.writeUINT64(attr.size.longValue());
-
- if ((attr.uid != null) && (attr.gid != null))
- {
- tw.writeUINT32(attr.uid.intValue());
- tw.writeUINT32(attr.gid.intValue());
- }
-
- if (attr.permissions != null)
- tw.writeUINT32(attr.permissions.intValue());
-
- if ((attr.atime != null) && (attr.mtime != null))
- {
- tw.writeUINT32(attr.atime.intValue());
- tw.writeUINT32(attr.mtime.intValue());
- }
- }
-
- return tw.getBytes();
- }
-
- private SFTPv3FileHandle openFile(String fileName, int flags, SFTPv3FileAttributes attr) throws IOException
- {
- int req_id = generateNextRequestID();
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(fileName, charsetName);
- tw.writeUINT32(flags);
- tw.writeBytes(createAttrs(attr));
-
- if (debug != null)
- {
- debug.println("Sending SSH_FXP_OPEN...");
- debug.flush();
- }
-
- sendMessage(Packet.SSH_FXP_OPEN, req_id, tw.getBytes());
-
- byte[] resp = receiveMessage(34000);
-
- TypesReader tr = new TypesReader(resp);
-
- int t = tr.readByte();
-
- int rep_id = tr.readUINT32();
- if (rep_id != req_id)
- throw new IOException("The server sent an invalid id field.");
-
- if (t == Packet.SSH_FXP_HANDLE)
- {
- if (debug != null)
- {
- debug.println("Got SSH_FXP_HANDLE.");
- debug.flush();
- }
-
- return new SFTPv3FileHandle(this, tr.readByteString());
- }
-
- if (t != Packet.SSH_FXP_STATUS)
- throw new IOException("The SFTP server sent an unexpected packet type (" + t + ")");
-
- int errorCode = tr.readUINT32();
- String errorMessage = tr.readString();
-
- throw new SFTPException(errorMessage, errorCode);
- }
-
- /**
- * Read bytes from a file. No more than 32768 bytes may be read at once.
- * Be aware that the semantics of read() are different than for Java streams.
- * <p>
- * <ul>
- * <li>The server will read as many bytes as it can from the file (up to <code>len</code>),
- * and return them.</li>
- * <li>If EOF is encountered before reading any data, <code>-1</code> is returned.
- * <li>If an error occurs, an exception is thrown</li>.
- * <li>For normal disk files, it is guaranteed that the server will return the specified
- * number of bytes, or up to end of file. For, e.g., device files this may return
- * fewer bytes than requested.</li>
- * </ul>
- *
- * @param handle a SFTPv3FileHandle handle
- * @param fileOffset offset (in bytes) in the file
- * @param dst the destination byte array
- * @param dstoff offset in the destination byte array
- * @param len how many bytes to read, 0 &lt; len &lt;= 32768 bytes
- * @return the number of bytes that could be read, may be less than requested if
- * the end of the file is reached, -1 is returned in case of <code>EOF</code>
- * @throws IOException
- */
- public int read(SFTPv3FileHandle handle, long fileOffset, byte[] dst, int dstoff, int len) throws IOException
- {
- checkHandleValidAndOpen(handle);
-
- if ((len > 32768) || (len <= 0))
- throw new IllegalArgumentException("invalid len argument");
-
- int req_id = generateNextRequestID();
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(handle.fileHandle, 0, handle.fileHandle.length);
- tw.writeUINT64(fileOffset);
- tw.writeUINT32(len);
-
- if (debug != null)
- {
- debug.println("Sending SSH_FXP_READ...");
- debug.flush();
- }
-
- sendMessage(Packet.SSH_FXP_READ, req_id, tw.getBytes());
-
- byte[] resp = receiveMessage(34000);
-
- TypesReader tr = new TypesReader(resp);
-
- int t = tr.readByte();
-
- int rep_id = tr.readUINT32();
- if (rep_id != req_id)
- throw new IOException("The server sent an invalid id field.");
-
- if (t == Packet.SSH_FXP_DATA)
- {
- if (debug != null)
- {
- debug.println("Got SSH_FXP_DATA...");
- debug.flush();
- }
-
- int readLen = tr.readUINT32();
-
- if ((readLen < 0) || (readLen > len))
- throw new IOException("The server sent an invalid length field.");
-
- tr.readBytes(dst, dstoff, readLen);
-
- return readLen;
- }
-
- if (t != Packet.SSH_FXP_STATUS)
- throw new IOException("The SFTP server sent an unexpected packet type (" + t + ")");
-
- int errorCode = tr.readUINT32();
-
- if (errorCode == ErrorCodes.SSH_FX_EOF)
- {
- if (debug != null)
- {
- debug.println("Got SSH_FX_EOF.");
- debug.flush();
- }
-
- return -1;
- }
-
- String errorMessage = tr.readString();
-
- throw new SFTPException(errorMessage, errorCode);
- }
-
- /**
- * Write bytes to a file. If <code>len</code> &gt; 32768, then the write operation will
- * be split into multiple writes.
- *
- * @param handle a SFTPv3FileHandle handle.
- * @param fileOffset offset (in bytes) in the file.
- * @param src the source byte array.
- * @param srcoff offset in the source byte array.
- * @param len how many bytes to write.
- * @throws IOException
- */
- public void write(SFTPv3FileHandle handle, long fileOffset, byte[] src, int srcoff, int len) throws IOException
- {
- checkHandleValidAndOpen(handle);
-
- while (len > 0)
- {
- int writeRequestLen = len;
-
- if (writeRequestLen > 32768)
- writeRequestLen = 32768;
-
- int req_id = generateNextRequestID();
-
- TypesWriter tw = new TypesWriter();
- tw.writeString(handle.fileHandle, 0, handle.fileHandle.length);
- tw.writeUINT64(fileOffset);
- tw.writeString(src, srcoff, writeRequestLen);
-
- if (debug != null)
- {
- debug.println("Sending SSH_FXP_WRITE...");
- debug.flush();
- }
-
- sendMessage(Packet.SSH_FXP_WRITE, req_id, tw.getBytes());
-
- fileOffset += writeRequestLen;
-
- srcoff += writeRequestLen;
- len -= writeRequestLen;
-
- byte[] resp = receiveMessage(34000);
-
- TypesReader tr = new TypesReader(resp);
-
- int t = tr.readByte();
-
- int rep_id = tr.readUINT32();
- if (rep_id != req_id)
- throw new IOException("The server sent an invalid id field.");
-
- if (t != Packet.SSH_FXP_STATUS)
- throw new IOException("The SFTP server sent an unexpected packet type (" + t + ")");
-
- int errorCode = tr.readUINT32();
-
- if (errorCode == ErrorCodes.SSH_FX_OK)
- continue;
-
- String errorMessage = tr.readString();
-
- throw new SFTPException(errorMessage, errorCode);
- }
- }
-
- /**
- * Close a file.
- *
- * @param handle a SFTPv3FileHandle handle
- * @throws IOException
- */
- public void closeFile(SFTPv3FileHandle handle) throws IOException
- {
- if (handle == null)
- throw new IllegalArgumentException("the handle argument may not be null");
-
- try
- {
- if (handle.isClosed == false)
- {
- closeHandle(handle.fileHandle);
- }
- }
- finally
- {
- handle.isClosed = true;
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/SFTPv3DirectoryEntry.java b/app/src/main/java/com/trilead/ssh2/SFTPv3DirectoryEntry.java
deleted file mode 100644
index 669ba87..0000000
--- a/app/src/main/java/com/trilead/ssh2/SFTPv3DirectoryEntry.java
+++ /dev/null
@@ -1,38 +0,0 @@
-
-package com.trilead.ssh2;
-
-/**
- * A <code>SFTPv3DirectoryEntry</code> as returned by {@link SFTPv3Client#ls(String)}.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: SFTPv3DirectoryEntry.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-
-public class SFTPv3DirectoryEntry
-{
- /**
- * A relative name within the directory, without any path components.
- */
- public String filename;
-
- /**
- * An expanded format for the file name, similar to what is returned by
- * "ls -l" on Un*x systems.
- * <p>
- * The format of this field is unspecified by the SFTP v3 protocol.
- * It MUST be suitable for use in the output of a directory listing
- * command (in fact, the recommended operation for a directory listing
- * command is to simply display this data). However, clients SHOULD NOT
- * attempt to parse the longname field for file attributes; they SHOULD
- * use the attrs field instead.
- * <p>
- * The recommended format for the longname field is as follows:<br>
- * <code>-rwxr-xr-x 1 mjos staff 348911 Mar 25 14:29 t-filexfer</code>
- */
- public String longEntry;
-
- /**
- * The attributes of this entry.
- */
- public SFTPv3FileAttributes attributes;
-}
diff --git a/app/src/main/java/com/trilead/ssh2/SFTPv3FileAttributes.java b/app/src/main/java/com/trilead/ssh2/SFTPv3FileAttributes.java
deleted file mode 100644
index 7b1d321..0000000
--- a/app/src/main/java/com/trilead/ssh2/SFTPv3FileAttributes.java
+++ /dev/null
@@ -1,145 +0,0 @@
-
-package com.trilead.ssh2;
-
-/**
- * A <code>SFTPv3FileAttributes</code> object represents detail information
- * about a file on the server. Not all fields may/must be present.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: SFTPv3FileAttributes.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
- */
-
-public class SFTPv3FileAttributes
-{
- /**
- * The SIZE attribute. <code>NULL</code> if not present.
- */
- public Long size = null;
-
- /**
- * The UID attribute. <code>NULL</code> if not present.
- */
- public Integer uid = null;
-
- /**
- * The GID attribute. <code>NULL</code> if not present.
- */
- public Integer gid = null;
-
- /**
- * The POSIX permissions. <code>NULL</code> if not present.
- * <p>
- * Here is a list:
- * <p>
- * <pre>Note: these numbers are all OCTAL.
- *
- * S_IFMT 0170000 bitmask for the file type bitfields
- * S_IFSOCK 0140000 socket
- * S_IFLNK 0120000 symbolic link
- * S_IFREG 0100000 regular file
- * S_IFBLK 0060000 block device
- * S_IFDIR 0040000 directory
- * S_IFCHR 0020000 character device
- * S_IFIFO 0010000 fifo
- * S_ISUID 0004000 set UID bit
- * S_ISGID 0002000 set GID bit
- * S_ISVTX 0001000 sticky bit
- *
- * S_IRWXU 00700 mask for file owner permissions
- * S_IRUSR 00400 owner has read permission
- * S_IWUSR 00200 owner has write permission
- * S_IXUSR 00100 owner has execute permission
- * S_IRWXG 00070 mask for group permissions
- * S_IRGRP 00040 group has read permission
- * S_IWGRP 00020 group has write permission
- * S_IXGRP 00010 group has execute permission
- * S_IRWXO 00007 mask for permissions for others (not in group)
- * S_IROTH 00004 others have read permission
- * S_IWOTH 00002 others have write permisson
- * S_IXOTH 00001 others have execute permission
- * </pre>
- */
- public Integer permissions = null;
-
- /**
- * The ATIME attribute. Represented as seconds from Jan 1, 1970 in UTC.
- * <code>NULL</code> if not present.
- */
- public Long atime = null;
-
- /**
- * The MTIME attribute. Represented as seconds from Jan 1, 1970 in UTC.
- * <code>NULL</code> if not present.
- */
- public Long mtime = null;
-
- /**
- * Checks if this entry is a directory.
- *
- * @return Returns true if permissions are available and they indicate
- * that this entry represents a directory.
- */
- public boolean isDirectory()
- {
- if (permissions == null)
- return false;
-
- return ((permissions.intValue() & 0040000) != 0);
- }
-
- /**
- * Checks if this entry is a regular file.
- *
- * @return Returns true if permissions are available and they indicate
- * that this entry represents a regular file.
- */
- public boolean isRegularFile()
- {
- if (permissions == null)
- return false;
-
- return ((permissions.intValue() & 0100000) != 0);
- }
-
- /**
- * Checks if this entry is a a symlink.
- *
- * @return Returns true if permissions are available and they indicate
- * that this entry represents a symlink.
- */
- public boolean isSymlink()
- {
- if (permissions == null)
- return false;
-
- return ((permissions.intValue() & 0120000) != 0);
- }
-
- /**
- * Turn the POSIX permissions into a 7 digit octal representation.
- * Note: the returned value is first masked with <code>0177777</code>.
- *
- * @return <code>NULL</code> if permissions are not available.
- */
- public String getOctalPermissions()
- {
- if (permissions == null)
- return null;
-
- String res = Integer.toString(permissions.intValue() & 0177777, 8);
-
- StringBuffer sb = new StringBuffer();
-
- int leadingZeros = 7 - res.length();
-
- while (leadingZeros > 0)
- {
- sb.append('0');
- leadingZeros--;
- }
-
- sb.append(res);
-
- return sb.toString();
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/SFTPv3FileHandle.java b/app/src/main/java/com/trilead/ssh2/SFTPv3FileHandle.java
deleted file mode 100644
index 9b3dbb6..0000000
--- a/app/src/main/java/com/trilead/ssh2/SFTPv3FileHandle.java
+++ /dev/null
@@ -1,45 +0,0 @@
-
-package com.trilead.ssh2;
-
-/**
- * A <code>SFTPv3FileHandle</code>.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: SFTPv3FileHandle.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-
-public class SFTPv3FileHandle
-{
- final SFTPv3Client client;
- final byte[] fileHandle;
- boolean isClosed = false;
-
- /* The constructor is NOT public */
-
- SFTPv3FileHandle(SFTPv3Client client, byte[] h)
- {
- this.client = client;
- this.fileHandle = h;
- }
-
- /**
- * Get the SFTPv3Client instance which created this handle.
- *
- * @return A SFTPv3Client instance.
- */
- public SFTPv3Client getClient()
- {
- return client;
- }
-
- /**
- * Check if this handle was closed with the {@link SFTPv3Client#closeFile(SFTPv3FileHandle)} method
- * of the <code>SFTPv3Client</code> instance which created the handle.
- *
- * @return if the handle is closed.
- */
- public boolean isClosed()
- {
- return isClosed;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/ServerHostKeyVerifier.java b/app/src/main/java/com/trilead/ssh2/ServerHostKeyVerifier.java
deleted file mode 100644
index ac65955..0000000
--- a/app/src/main/java/com/trilead/ssh2/ServerHostKeyVerifier.java
+++ /dev/null
@@ -1,31 +0,0 @@
-
-package com.trilead.ssh2;
-
-/**
- * A callback interface used to implement a client specific method of checking
- * server host keys.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: ServerHostKeyVerifier.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-
-public interface ServerHostKeyVerifier
-{
- /**
- * The actual verifier method, it will be called by the key exchange code
- * on EVERY key exchange - this can happen several times during the lifetime
- * of a connection.
- * <p>
- * Note: SSH-2 servers are allowed to change their hostkey at ANY time.
- *
- * @param hostname the hostname used to create the {@link Connection} object
- * @param port the remote TCP port
- * @param serverHostKeyAlgorithm the public key algorithm (<code>ssh-rsa</code> or <code>ssh-dss</code>)
- * @param serverHostKey the server's public key blob
- * @return if the client wants to accept the server's host key - if not, the
- * connection will be closed.
- * @throws Exception Will be wrapped with an IOException, extended version of returning false =)
- */
- public boolean verifyServerHostKey(String hostname, int port, String serverHostKeyAlgorithm, byte[] serverHostKey)
- throws Exception;
-}
diff --git a/app/src/main/java/com/trilead/ssh2/Session.java b/app/src/main/java/com/trilead/ssh2/Session.java
deleted file mode 100644
index bf3c7e0..0000000
--- a/app/src/main/java/com/trilead/ssh2/Session.java
+++ /dev/null
@@ -1,530 +0,0 @@
-
-package com.trilead.ssh2;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.SecureRandom;
-
-import com.trilead.ssh2.channel.Channel;
-import com.trilead.ssh2.channel.ChannelManager;
-import com.trilead.ssh2.channel.X11ServerData;
-
-
-/**
- * A <code>Session</code> is a remote execution of a program. "Program" means
- * in this context either a shell, an application or a system command. The
- * program may or may not have a tty. Only one single program can be started on
- * a session. However, multiple sessions can be active simultaneously.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: Session.java,v 1.2 2008/03/03 07:01:36 cplattne Exp $
- */
-public class Session
-{
- ChannelManager cm;
- Channel cn;
-
- boolean flag_pty_requested = false;
- boolean flag_x11_requested = false;
- boolean flag_execution_started = false;
- boolean flag_closed = false;
-
- String x11FakeCookie = null;
-
- final SecureRandom rnd;
-
- Session(ChannelManager cm, SecureRandom rnd) throws IOException
- {
- this.cm = cm;
- this.cn = cm.openSessionChannel();
- this.rnd = rnd;
- }
-
- /**
- * Basically just a wrapper for lazy people - identical to calling
- * <code>requestPTY("dumb", 0, 0, 0, 0, null)</code>.
- *
- * @throws IOException
- */
- public void requestDumbPTY() throws IOException
- {
- requestPTY("dumb", 0, 0, 0, 0, null);
- }
-
- /**
- * Basically just another wrapper for lazy people - identical to calling
- * <code>requestPTY(term, 0, 0, 0, 0, null)</code>.
- *
- * @throws IOException
- */
- public void requestPTY(String term) throws IOException
- {
- requestPTY(term, 0, 0, 0, 0, null);
- }
-
- /**
- * Allocate a pseudo-terminal for this session.
- * <p>
- * This method may only be called before a program or shell is started in
- * this session.
- * <p>
- * Different aspects can be specified:
- * <p>
- * <ul>
- * <li>The TERM environment variable value (e.g., vt100)</li>
- * <li>The terminal's dimensions.</li>
- * <li>The encoded terminal modes.</li>
- * </ul>
- * Zero dimension parameters are ignored. The character/row dimensions
- * override the pixel dimensions (when nonzero). Pixel dimensions refer to
- * the drawable area of the window. The dimension parameters are only
- * informational. The encoding of terminal modes (parameter
- * <code>terminal_modes</code>) is described in RFC4254.
- *
- * @param term
- * The TERM environment variable value (e.g., vt100)
- * @param term_width_characters
- * terminal width, characters (e.g., 80)
- * @param term_height_characters
- * terminal height, rows (e.g., 24)
- * @param term_width_pixels
- * terminal width, pixels (e.g., 640)
- * @param term_height_pixels
- * terminal height, pixels (e.g., 480)
- * @param terminal_modes
- * encoded terminal modes (may be <code>null</code>)
- * @throws IOException
- */
- public void requestPTY(String term, int term_width_characters, int term_height_characters, int term_width_pixels,
- int term_height_pixels, byte[] terminal_modes) throws IOException
- {
- if (term == null)
- throw new IllegalArgumentException("TERM cannot be null.");
-
- if ((terminal_modes != null) && (terminal_modes.length > 0))
- {
- if (terminal_modes[terminal_modes.length - 1] != 0)
- throw new IOException("Illegal terminal modes description, does not end in zero byte");
- }
- else
- terminal_modes = new byte[] { 0 };
-
- synchronized (this)
- {
- /* The following is just a nicer error, we would catch it anyway later in the channel code */
- if (flag_closed)
- throw new IOException("This session is closed.");
-
- if (flag_pty_requested)
- throw new IOException("A PTY was already requested.");
-
- if (flag_execution_started)
- throw new IOException(
- "Cannot request PTY at this stage anymore, a remote execution has already started.");
-
- flag_pty_requested = true;
- }
-
- cm.requestPTY(cn, term, term_width_characters, term_height_characters, term_width_pixels, term_height_pixels,
- terminal_modes);
- }
-
- /**
- * Inform other side of connection that our PTY has resized.
- * <p>
- * Zero dimension parameters are ignored. The character/row dimensions
- * override the pixel dimensions (when nonzero). Pixel dimensions refer to
- * the drawable area of the window. The dimension parameters are only
- * informational.
- *
- * @param term_width_characters
- * terminal width, characters (e.g., 80)
- * @param term_height_characters
- * terminal height, rows (e.g., 24)
- * @param term_width_pixels
- * terminal width, pixels (e.g., 640)
- * @param term_height_pixels
- * terminal height, pixels (e.g., 480)
- * @throws IOException
- */
- public void resizePTY(int term_width_characters, int term_height_characters, int term_width_pixels,
- int term_height_pixels) throws IOException {
- synchronized (this)
- {
- /* The following is just a nicer error, we would catch it anyway later in the channel code */
- if (flag_closed)
- throw new IOException("This session is closed.");
- }
-
- cm.resizePTY(cn, term_width_characters, term_height_characters, term_width_pixels, term_height_pixels);
- }
-
- /**
- * Request X11 forwarding for the current session.
- * <p>
- * You have to supply the name and port of your X-server.
- * <p>
- * This method may only be called before a program or shell is started in
- * this session.
- *
- * @param hostname the hostname of the real (target) X11 server (e.g., 127.0.0.1)
- * @param port the port of the real (target) X11 server (e.g., 6010)
- * @param cookie if non-null, then present this cookie to the real X11 server
- * @param singleConnection if true, then the server is instructed to only forward one single
- * connection, no more connections shall be forwarded after first, or after the session
- * channel has been closed
- * @throws IOException
- */
- public void requestX11Forwarding(String hostname, int port, byte[] cookie, boolean singleConnection)
- throws IOException
- {
- if (hostname == null)
- throw new IllegalArgumentException("hostname argument may not be null");
-
- synchronized (this)
- {
- /* The following is just a nicer error, we would catch it anyway later in the channel code */
- if (flag_closed)
- throw new IOException("This session is closed.");
-
- if (flag_x11_requested)
- throw new IOException("X11 forwarding was already requested.");
-
- if (flag_execution_started)
- throw new IOException(
- "Cannot request X11 forwarding at this stage anymore, a remote execution has already started.");
-
- flag_x11_requested = true;
- }
-
- /* X11ServerData - used to store data about the target X11 server */
-
- X11ServerData x11data = new X11ServerData();
-
- x11data.hostname = hostname;
- x11data.port = port;
- x11data.x11_magic_cookie = cookie; /* if non-null, then present this cookie to the real X11 server */
-
- /* Generate fake cookie - this one is used between remote clients and our proxy */
-
- byte[] fakeCookie = new byte[16];
- String hexEncodedFakeCookie;
-
- /* Make sure that this fake cookie is unique for this connection */
-
- while (true)
- {
- rnd.nextBytes(fakeCookie);
-
- /* Generate also hex representation of fake cookie */
-
- StringBuffer tmp = new StringBuffer(32);
- for (int i = 0; i < fakeCookie.length; i++)
- {
- String digit2 = Integer.toHexString(fakeCookie[i] & 0xff);
- tmp.append((digit2.length() == 2) ? digit2 : "0" + digit2);
- }
- hexEncodedFakeCookie = tmp.toString();
-
- /* Well, yes, chances are low, but we want to be on the safe side */
-
- if (cm.checkX11Cookie(hexEncodedFakeCookie) == null)
- break;
- }
-
- /* Ask for X11 forwarding */
-
- cm.requestX11(cn, singleConnection, "MIT-MAGIC-COOKIE-1", hexEncodedFakeCookie, 0);
-
- /* OK, that went fine, get ready to accept X11 connections... */
- /* ... but only if the user has not called close() in the meantime =) */
-
- synchronized (this)
- {
- if (flag_closed == false)
- {
- this.x11FakeCookie = hexEncodedFakeCookie;
- cm.registerX11Cookie(hexEncodedFakeCookie, x11data);
- }
- }
-
- /* Now it is safe to start remote X11 programs */
- }
-
- /**
- * Execute a command on the remote machine.
- *
- * @param cmd
- * The command to execute on the remote host.
- * @throws IOException
- */
- public void execCommand(String cmd) throws IOException
- {
- if (cmd == null)
- throw new IllegalArgumentException("cmd argument may not be null");
-
- synchronized (this)
- {
- /* The following is just a nicer error, we would catch it anyway later in the channel code */
- if (flag_closed)
- throw new IOException("This session is closed.");
-
- if (flag_execution_started)
- throw new IOException("A remote execution has already started.");
-
- flag_execution_started = true;
- }
-
- cm.requestExecCommand(cn, cmd);
- }
-
- /**
- * Start a shell on the remote machine.
- *
- * @throws IOException
- */
- public void startShell() throws IOException
- {
- synchronized (this)
- {
- /* The following is just a nicer error, we would catch it anyway later in the channel code */
- if (flag_closed)
- throw new IOException("This session is closed.");
-
- if (flag_execution_started)
- throw new IOException("A remote execution has already started.");
-
- flag_execution_started = true;
- }
-
- cm.requestShell(cn);
- }
-
- /**
- * Start a subsystem on the remote machine.
- * Unless you know what you are doing, you will never need this.
- *
- * @param name the name of the subsystem.
- * @throws IOException
- */
- public void startSubSystem(String name) throws IOException
- {
- if (name == null)
- throw new IllegalArgumentException("name argument may not be null");
-
- synchronized (this)
- {
- /* The following is just a nicer error, we would catch it anyway later in the channel code */
- if (flag_closed)
- throw new IOException("This session is closed.");
-
- if (flag_execution_started)
- throw new IOException("A remote execution has already started.");
-
- flag_execution_started = true;
- }
-
- cm.requestSubSystem(cn, name);
- }
-
- /**
- * This method can be used to perform end-to-end session (i.e., SSH channel)
- * testing. It sends a 'ping' message to the server and waits for the 'pong'
- * from the server.
- * <p>
- * Implementation details: this method sends a SSH_MSG_CHANNEL_REQUEST request
- * ('trilead-ping') to the server and waits for the SSH_MSG_CHANNEL_FAILURE reply
- * packet.
- *
- * @throws IOException in case of any problem or when the session is closed
- */
- public void ping() throws IOException
- {
- synchronized (this)
- {
- /*
- * The following is just a nicer error, we would catch it anyway
- * later in the channel code
- */
- if (flag_closed)
- throw new IOException("This session is closed.");
- }
-
- cm.requestChannelTrileadPing(cn);
- }
-
- /**
- * Request authentication agent forwarding.
- * @param agent object that implements the callbacks
- *
- * @throws IOException in case of any problem or when the session is closed
- */
- public synchronized boolean requestAuthAgentForwarding(AuthAgentCallback agent) throws IOException
- {
- synchronized (this)
- {
- /*
- * The following is just a nicer error, we would catch it anyway
- * later in the channel code
- */
- if (flag_closed)
- throw new IOException("This session is closed.");
- }
-
- return cm.requestChannelAgentForwarding(cn, agent);
- }
-
- public InputStream getStdout()
- {
- return cn.getStdoutStream();
- }
-
- public InputStream getStderr()
- {
- return cn.getStderrStream();
- }
-
- public OutputStream getStdin()
- {
- return cn.getStdinStream();
- }
-
- /**
- * This method blocks until there is more data available on either the
- * stdout or stderr InputStream of this <code>Session</code>. Very useful
- * if you do not want to use two parallel threads for reading from the two
- * InputStreams. One can also specify a timeout. NOTE: do NOT call this
- * method if you use concurrent threads that operate on either of the two
- * InputStreams of this <code>Session</code> (otherwise this method may
- * block, even though more data is available).
- *
- * @param timeout
- * The (non-negative) timeout in <code>ms</code>. <code>0</code> means no
- * timeout, the call may block forever.
- * @return
- * <ul>
- * <li><code>0</code> if no more data will arrive.</li>
- * <li><code>1</code> if more data is available.</li>
- * <li><code>-1</code> if a timeout occurred.</li>
- * </ul>
- *
- * @throws IOException
- * @deprecated This method has been replaced with a much more powerful wait-for-condition
- * interface and therefore acts only as a wrapper.
- *
- */
- public int waitUntilDataAvailable(long timeout) throws IOException
- {
- if (timeout < 0)
- throw new IllegalArgumentException("timeout must not be negative!");
-
- int conditions = cm.waitForCondition(cn, timeout, ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA
- | ChannelCondition.EOF);
-
- if ((conditions & ChannelCondition.TIMEOUT) != 0)
- return -1;
-
- if ((conditions & (ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA)) != 0)
- return 1;
-
- /* Here we do not need to check separately for CLOSED, since CLOSED implies EOF */
-
- if ((conditions & ChannelCondition.EOF) != 0)
- return 0;
-
- throw new IllegalStateException("Unexpected condition result (" + conditions + ")");
- }
-
- /**
- * This method blocks until certain conditions hold true on the underlying SSH-2 channel.
- * <p>
- * This method returns as soon as one of the following happens:
- * <ul>
- * <li>at least of the specified conditions (see {@link ChannelCondition}) holds true</li>
- * <li>timeout > 0 and a timeout occured (TIMEOUT will be set in result conditions)</a>
- * <li>the underlying channel was closed (CLOSED will be set in result conditions)</a>
- * </ul>
- * <p>
- * In any case, the result value contains ALL current conditions, which may be more
- * than the specified condition set (i.e., never use the "==" operator to test for conditions
- * in the bitmask, see also comments in {@link ChannelCondition}).
- * <p>
- * Note: do NOT call this method if you want to wait for STDOUT_DATA or STDERR_DATA and
- * there are concurrent threads (e.g., StreamGobblers) that operate on either of the two
- * InputStreams of this <code>Session</code> (otherwise this method may
- * block, even though more data is available in the StreamGobblers).
- *
- * @param condition_set a bitmask based on {@link ChannelCondition} values
- * @param timeout non-negative timeout in ms, <code>0</code> means no timeout
- * @return all bitmask specifying all current conditions that are true
- */
-
- public int waitForCondition(int condition_set, long timeout)
- {
- if (timeout < 0)
- throw new IllegalArgumentException("timeout must be non-negative!");
-
- return cm.waitForCondition(cn, timeout, condition_set);
- }
-
- /**
- * Get the exit code/status from the remote command - if available. Be
- * careful - not all server implementations return this value. It is
- * generally a good idea to call this method only when all data from the
- * remote side has been consumed (see also the <code<WaitForCondition</code> method).
- *
- * @return An <code>Integer</code> holding the exit code, or
- * <code>null</code> if no exit code is (yet) available.
- */
- public Integer getExitStatus()
- {
- return cn.getExitStatus();
- }
-
- /**
- * Get the name of the signal by which the process on the remote side was
- * stopped - if available and applicable. Be careful - not all server
- * implementations return this value.
- *
- * @return An <code>String</code> holding the name of the signal, or
- * <code>null</code> if the process exited normally or is still
- * running (or if the server forgot to send this information).
- */
- public String getExitSignal()
- {
- return cn.getExitSignal();
- }
-
- /**
- * Close this session. NEVER forget to call this method to free up resources -
- * even if you got an exception from one of the other methods (or when
- * getting an Exception on the Input- or OutputStreams). Sometimes these other
- * methods may throw an exception, saying that the underlying channel is
- * closed (this can happen, e.g., if the other server sent a close message.)
- * However, as long as you have not called the <code>close()</code>
- * method, you may be wasting (local) resources.
- *
- */
- public void close()
- {
- synchronized (this)
- {
- if (flag_closed)
- return;
-
- flag_closed = true;
-
- if (x11FakeCookie != null)
- cm.unRegisterX11Cookie(x11FakeCookie, true);
-
- try
- {
- cm.closeChannel(cn, "Closed due to user request", true);
- }
- catch (IOException ignored)
- {
- }
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/StreamGobbler.java b/app/src/main/java/com/trilead/ssh2/StreamGobbler.java
deleted file mode 100644
index e93c388..0000000
--- a/app/src/main/java/com/trilead/ssh2/StreamGobbler.java
+++ /dev/null
@@ -1,229 +0,0 @@
-
-package com.trilead.ssh2;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A <code>StreamGobbler</code> is an InputStream that uses an internal worker
- * thread to constantly consume input from another InputStream. It uses a buffer
- * to store the consumed data. The buffer size is automatically adjusted, if needed.
- * <p>
- * This class is sometimes very convenient - if you wrap a session's STDOUT and STDERR
- * InputStreams with instances of this class, then you don't have to bother about
- * the shared window of STDOUT and STDERR in the low level SSH-2 protocol,
- * since all arriving data will be immediatelly consumed by the worker threads.
- * Also, as a side effect, the streams will be buffered (e.g., single byte
- * read() operations are faster).
- * <p>
- * Other SSH for Java libraries include this functionality by default in
- * their STDOUT and STDERR InputStream implementations, however, please be aware
- * that this approach has also a downside:
- * <p>
- * If you do not call the StreamGobbler's <code>read()</code> method often enough
- * and the peer is constantly sending huge amounts of data, then you will sooner or later
- * encounter a low memory situation due to the aggregated data (well, it also depends on the Java heap size).
- * Joe Average will like this class anyway - a paranoid programmer would never use such an approach.
- * <p>
- * The term "StreamGobbler" was taken from an article called "When Runtime.exec() won't",
- * see http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: StreamGobbler.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-
-public class StreamGobbler extends InputStream
-{
- class GobblerThread extends Thread
- {
- public void run()
- {
- byte[] buff = new byte[8192];
-
- while (true)
- {
- try
- {
- int avail = is.read(buff);
-
- synchronized (synchronizer)
- {
- if (avail <= 0)
- {
- isEOF = true;
- synchronizer.notifyAll();
- break;
- }
-
- int space_available = buffer.length - write_pos;
-
- if (space_available < avail)
- {
- /* compact/resize buffer */
-
- int unread_size = write_pos - read_pos;
- int need_space = unread_size + avail;
-
- byte[] new_buffer = buffer;
-
- if (need_space > buffer.length)
- {
- int inc = need_space / 3;
- inc = (inc < 256) ? 256 : inc;
- inc = (inc > 8192) ? 8192 : inc;
- new_buffer = new byte[need_space + inc];
- }
-
- if (unread_size > 0)
- System.arraycopy(buffer, read_pos, new_buffer, 0, unread_size);
-
- buffer = new_buffer;
-
- read_pos = 0;
- write_pos = unread_size;
- }
-
- System.arraycopy(buff, 0, buffer, write_pos, avail);
- write_pos += avail;
-
- synchronizer.notifyAll();
- }
- }
- catch (IOException e)
- {
- synchronized (synchronizer)
- {
- exception = e;
- synchronizer.notifyAll();
- break;
- }
- }
- }
- }
- }
-
- private InputStream is;
- private GobblerThread t;
-
- private Object synchronizer = new Object();
-
- private boolean isEOF = false;
- private boolean isClosed = false;
- private IOException exception = null;
-
- private byte[] buffer = new byte[2048];
- private int read_pos = 0;
- private int write_pos = 0;
-
- public StreamGobbler(InputStream is)
- {
- this.is = is;
- t = new GobblerThread();
- t.setDaemon(true);
- t.start();
- }
-
- public int read() throws IOException
- {
- synchronized (synchronizer)
- {
- if (isClosed)
- throw new IOException("This StreamGobbler is closed.");
-
- while (read_pos == write_pos)
- {
- if (exception != null)
- throw exception;
-
- if (isEOF)
- return -1;
-
- try
- {
- synchronizer.wait();
- }
- catch (InterruptedException e)
- {
- }
- }
-
- int b = buffer[read_pos++] & 0xff;
-
- return b;
- }
- }
-
- public int available() throws IOException
- {
- synchronized (synchronizer)
- {
- if (isClosed)
- throw new IOException("This StreamGobbler is closed.");
-
- return write_pos - read_pos;
- }
- }
-
- public int read(byte[] b) throws IOException
- {
- return read(b, 0, b.length);
- }
-
- public void close() throws IOException
- {
- synchronized (synchronizer)
- {
- if (isClosed)
- return;
- isClosed = true;
- isEOF = true;
- synchronizer.notifyAll();
- is.close();
- }
- }
-
- public int read(byte[] b, int off, int len) throws IOException
- {
- if (b == null)
- throw new NullPointerException();
-
- if ((off < 0) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0) || (off > b.length))
- throw new IndexOutOfBoundsException();
-
- if (len == 0)
- return 0;
-
- synchronized (synchronizer)
- {
- if (isClosed)
- throw new IOException("This StreamGobbler is closed.");
-
- while (read_pos == write_pos)
- {
- if (exception != null)
- throw exception;
-
- if (isEOF)
- return -1;
-
- try
- {
- synchronizer.wait();
- }
- catch (InterruptedException e)
- {
- }
- }
-
- int avail = write_pos - read_pos;
-
- avail = (avail > len) ? len : avail;
-
- System.arraycopy(buffer, read_pos, b, off, avail);
-
- read_pos += avail;
-
- return avail;
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/auth/AuthenticationManager.java b/app/src/main/java/com/trilead/ssh2/auth/AuthenticationManager.java
deleted file mode 100644
index e551495..0000000
--- a/app/src/main/java/com/trilead/ssh2/auth/AuthenticationManager.java
+++ /dev/null
@@ -1,466 +0,0 @@
-
-package com.trilead.ssh2.auth;
-
-import java.io.IOException;
-import java.security.KeyPair;
-import java.security.PrivateKey;
-import java.security.SecureRandom;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.DSAPublicKey;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
-import java.util.Vector;
-
-import com.trilead.ssh2.InteractiveCallback;
-import com.trilead.ssh2.crypto.PEMDecoder;
-import com.trilead.ssh2.packets.PacketServiceAccept;
-import com.trilead.ssh2.packets.PacketServiceRequest;
-import com.trilead.ssh2.packets.PacketUserauthBanner;
-import com.trilead.ssh2.packets.PacketUserauthFailure;
-import com.trilead.ssh2.packets.PacketUserauthInfoRequest;
-import com.trilead.ssh2.packets.PacketUserauthInfoResponse;
-import com.trilead.ssh2.packets.PacketUserauthRequestInteractive;
-import com.trilead.ssh2.packets.PacketUserauthRequestNone;
-import com.trilead.ssh2.packets.PacketUserauthRequestPassword;
-import com.trilead.ssh2.packets.PacketUserauthRequestPublicKey;
-import com.trilead.ssh2.packets.Packets;
-import com.trilead.ssh2.packets.TypesWriter;
-import com.trilead.ssh2.signature.DSASHA1Verify;
-import com.trilead.ssh2.signature.ECDSASHA2Verify;
-import com.trilead.ssh2.signature.RSASHA1Verify;
-import com.trilead.ssh2.transport.MessageHandler;
-import com.trilead.ssh2.transport.TransportManager;
-
-
-/**
- * AuthenticationManager.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: AuthenticationManager.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
- */
-public class AuthenticationManager implements MessageHandler
-{
- TransportManager tm;
-
- Vector packets = new Vector();
- boolean connectionClosed = false;
-
- String banner;
-
- String[] remainingMethods = new String[0];
- boolean isPartialSuccess = false;
-
- boolean authenticated = false;
- boolean initDone = false;
-
- public AuthenticationManager(TransportManager tm)
- {
- this.tm = tm;
- }
-
- boolean methodPossible(String methName)
- {
- if (remainingMethods == null)
- return false;
-
- for (int i = 0; i < remainingMethods.length; i++)
- {
- if (remainingMethods[i].compareTo(methName) == 0)
- return true;
- }
- return false;
- }
-
- byte[] deQueue() throws IOException
- {
- synchronized (packets)
- {
- while (packets.size() == 0)
- {
- if (connectionClosed)
- throw (IOException) new IOException("The connection is closed.").initCause(tm
- .getReasonClosedCause());
-
- try
- {
- packets.wait();
- }
- catch (InterruptedException ign)
- {
- }
- }
- /* This sequence works with J2ME */
- byte[] res = (byte[]) packets.firstElement();
- packets.removeElementAt(0);
- return res;
- }
- }
-
- byte[] getNextMessage() throws IOException
- {
- while (true)
- {
- byte[] msg = deQueue();
-
- if (msg[0] != Packets.SSH_MSG_USERAUTH_BANNER)
- return msg;
-
- PacketUserauthBanner sb = new PacketUserauthBanner(msg, 0, msg.length);
-
- banner = sb.getBanner();
- }
- }
-
- public String[] getRemainingMethods(String user) throws IOException
- {
- initialize(user);
- return remainingMethods;
- }
-
- public boolean getPartialSuccess()
- {
- return isPartialSuccess;
- }
-
- private boolean initialize(String user) throws IOException
- {
- if (initDone == false)
- {
- tm.registerMessageHandler(this, 0, 255);
-
- PacketServiceRequest sr = new PacketServiceRequest("ssh-userauth");
- tm.sendMessage(sr.getPayload());
-
- PacketUserauthRequestNone urn = new PacketUserauthRequestNone("ssh-connection", user);
- tm.sendMessage(urn.getPayload());
-
- byte[] msg = getNextMessage();
- new PacketServiceAccept(msg, 0, msg.length);
- msg = getNextMessage();
-
- initDone = true;
-
- if (msg[0] == Packets.SSH_MSG_USERAUTH_SUCCESS)
- {
- authenticated = true;
- tm.removeMessageHandler(this, 0, 255);
- return true;
- }
-
- if (msg[0] == Packets.SSH_MSG_USERAUTH_FAILURE)
- {
- PacketUserauthFailure puf = new PacketUserauthFailure(msg, 0, msg.length);
-
- remainingMethods = puf.getAuthThatCanContinue();
- isPartialSuccess = puf.isPartialSuccess();
- return false;
- }
-
- throw new IOException("Unexpected SSH message (type " + msg[0] + ")");
- }
- return authenticated;
- }
-
- public boolean authenticatePublicKey(String user, char[] PEMPrivateKey, String password, SecureRandom rnd)
- throws IOException
- {
- KeyPair pair = PEMDecoder.decode(PEMPrivateKey, password);
-
- return authenticatePublicKey(user, pair, rnd);
- }
-
- public boolean authenticatePublicKey(String user, KeyPair pair, SecureRandom rnd)
- throws IOException
- {
- PrivateKey key = pair.getPrivate();
-
- try
- {
- initialize(user);
-
- if (methodPossible("publickey") == false)
- throw new IOException("Authentication method publickey not supported by the server at this stage.");
-
- if (key instanceof DSAPrivateKey)
- {
- DSAPrivateKey pk = (DSAPrivateKey) key;
-
- byte[] pk_enc = DSASHA1Verify.encodeSSHDSAPublicKey((DSAPublicKey) pair.getPublic());
-
- TypesWriter tw = new TypesWriter();
-
- byte[] H = tm.getSessionIdentifier();
-
- tw.writeString(H, 0, H.length);
- tw.writeByte(Packets.SSH_MSG_USERAUTH_REQUEST);
- tw.writeString(user);
- tw.writeString("ssh-connection");
- tw.writeString("publickey");
- tw.writeBoolean(true);
- tw.writeString("ssh-dss");
- tw.writeString(pk_enc, 0, pk_enc.length);
-
- byte[] msg = tw.getBytes();
-
- byte[] ds = DSASHA1Verify.generateSignature(msg, pk, rnd);
-
- byte[] ds_enc = DSASHA1Verify.encodeSSHDSASignature(ds);
-
- PacketUserauthRequestPublicKey ua = new PacketUserauthRequestPublicKey("ssh-connection", user,
- "ssh-dss", pk_enc, ds_enc);
- tm.sendMessage(ua.getPayload());
- }
- else if (key instanceof RSAPrivateKey)
- {
- RSAPrivateKey pk = (RSAPrivateKey) key;
-
- byte[] pk_enc = RSASHA1Verify.encodeSSHRSAPublicKey((RSAPublicKey) pair.getPublic());
-
- TypesWriter tw = new TypesWriter();
- {
- byte[] H = tm.getSessionIdentifier();
-
- tw.writeString(H, 0, H.length);
- tw.writeByte(Packets.SSH_MSG_USERAUTH_REQUEST);
- tw.writeString(user);
- tw.writeString("ssh-connection");
- tw.writeString("publickey");
- tw.writeBoolean(true);
- tw.writeString("ssh-rsa");
- tw.writeString(pk_enc, 0, pk_enc.length);
- }
-
- byte[] msg = tw.getBytes();
-
- byte[] ds = RSASHA1Verify.generateSignature(msg, pk);
-
- byte[] rsa_sig_enc = RSASHA1Verify.encodeSSHRSASignature(ds);
-
- PacketUserauthRequestPublicKey ua = new PacketUserauthRequestPublicKey("ssh-connection", user,
- "ssh-rsa", pk_enc, rsa_sig_enc);
-
- tm.sendMessage(ua.getPayload());
- }
- else if (key instanceof ECPrivateKey)
- {
- ECPrivateKey pk = (ECPrivateKey) key;
- final String algo = ECDSASHA2Verify.ECDSA_SHA2_PREFIX
- + ECDSASHA2Verify.getCurveName(pk.getParams());
-
- byte[] pk_enc = ECDSASHA2Verify.encodeSSHECDSAPublicKey((ECPublicKey) pair.getPublic());
-
- TypesWriter tw = new TypesWriter();
- {
- byte[] H = tm.getSessionIdentifier();
-
- tw.writeString(H, 0, H.length);
- tw.writeByte(Packets.SSH_MSG_USERAUTH_REQUEST);
- tw.writeString(user);
- tw.writeString("ssh-connection");
- tw.writeString("publickey");
- tw.writeBoolean(true);
- tw.writeString(algo);
- tw.writeString(pk_enc, 0, pk_enc.length);
- }
-
- byte[] msg = tw.getBytes();
-
- byte[] ds = ECDSASHA2Verify.generateSignature(msg, pk);
-
- byte[] ec_sig_enc = ECDSASHA2Verify.encodeSSHECDSASignature(ds, pk.getParams());
-
- PacketUserauthRequestPublicKey ua = new PacketUserauthRequestPublicKey("ssh-connection", user,
- algo, pk_enc, ec_sig_enc);
-
- tm.sendMessage(ua.getPayload());
- }
- else
- {
- throw new IOException("Unknown private key type returned by the PEM decoder.");
- }
-
- byte[] ar = getNextMessage();
- if (ar[0] == Packets.SSH_MSG_USERAUTH_SUCCESS)
- {
- authenticated = true;
- tm.removeMessageHandler(this, 0, 255);
- return true;
- }
-
- if (ar[0] == Packets.SSH_MSG_USERAUTH_FAILURE)
- {
- PacketUserauthFailure puf = new PacketUserauthFailure(ar, 0, ar.length);
-
- remainingMethods = puf.getAuthThatCanContinue();
- isPartialSuccess = puf.isPartialSuccess();
-
- return false;
- }
-
- throw new IOException("Unexpected SSH message (type " + ar[0] + ")");
-
- }
- catch (IOException e)
- {
-e.printStackTrace();
- tm.close(e, false);
- throw (IOException) new IOException("Publickey authentication failed.").initCause(e);
- }
- }
-
- public boolean authenticateNone(String user) throws IOException
- {
- try
- {
- initialize(user);
- return authenticated;
- }
- catch (IOException e)
- {
- tm.close(e, false);
- throw (IOException) new IOException("None authentication failed.").initCause(e);
- }
- }
-
- public boolean authenticatePassword(String user, String pass) throws IOException
- {
- try
- {
- initialize(user);
-
- if (methodPossible("password") == false)
- throw new IOException("Authentication method password not supported by the server at this stage.");
-
- PacketUserauthRequestPassword ua = new PacketUserauthRequestPassword("ssh-connection", user, pass);
- tm.sendMessage(ua.getPayload());
-
- byte[] ar = getNextMessage();
-
- if (ar[0] == Packets.SSH_MSG_USERAUTH_SUCCESS)
- {
- authenticated = true;
- tm.removeMessageHandler(this, 0, 255);
- return true;
- }
-
- if (ar[0] == Packets.SSH_MSG_USERAUTH_FAILURE)
- {
- PacketUserauthFailure puf = new PacketUserauthFailure(ar, 0, ar.length);
-
- remainingMethods = puf.getAuthThatCanContinue();
- isPartialSuccess = puf.isPartialSuccess();
-
- return false;
- }
-
- throw new IOException("Unexpected SSH message (type " + ar[0] + ")");
-
- }
- catch (IOException e)
- {
- tm.close(e, false);
- throw (IOException) new IOException("Password authentication failed.").initCause(e);
- }
- }
-
- public boolean authenticateInteractive(String user, String[] submethods, InteractiveCallback cb) throws IOException
- {
- try
- {
- initialize(user);
-
- if (methodPossible("keyboard-interactive") == false)
- throw new IOException(
- "Authentication method keyboard-interactive not supported by the server at this stage.");
-
- if (submethods == null)
- submethods = new String[0];
-
- PacketUserauthRequestInteractive ua = new PacketUserauthRequestInteractive("ssh-connection", user,
- submethods);
-
- tm.sendMessage(ua.getPayload());
-
- while (true)
- {
- byte[] ar = getNextMessage();
-
- if (ar[0] == Packets.SSH_MSG_USERAUTH_SUCCESS)
- {
- authenticated = true;
- tm.removeMessageHandler(this, 0, 255);
- return true;
- }
-
- if (ar[0] == Packets.SSH_MSG_USERAUTH_FAILURE)
- {
- PacketUserauthFailure puf = new PacketUserauthFailure(ar, 0, ar.length);
-
- remainingMethods = puf.getAuthThatCanContinue();
- isPartialSuccess = puf.isPartialSuccess();
-
- return false;
- }
-
- if (ar[0] == Packets.SSH_MSG_USERAUTH_INFO_REQUEST)
- {
- PacketUserauthInfoRequest pui = new PacketUserauthInfoRequest(ar, 0, ar.length);
-
- String[] responses;
-
- try
- {
- responses = cb.replyToChallenge(pui.getName(), pui.getInstruction(), pui.getNumPrompts(), pui
- .getPrompt(), pui.getEcho());
- }
- catch (Exception e)
- {
- throw (IOException) new IOException("Exception in callback.").initCause(e);
- }
-
- if (responses == null)
- throw new IOException("Your callback may not return NULL!");
-
- PacketUserauthInfoResponse puir = new PacketUserauthInfoResponse(responses);
- tm.sendMessage(puir.getPayload());
-
- continue;
- }
-
- throw new IOException("Unexpected SSH message (type " + ar[0] + ")");
- }
- }
- catch (IOException e)
- {
- tm.close(e, false);
- throw (IOException) new IOException("Keyboard-interactive authentication failed.").initCause(e);
- }
- }
-
- public void handleMessage(byte[] msg, int msglen) throws IOException
- {
- synchronized (packets)
- {
- if (msg == null)
- {
- connectionClosed = true;
- }
- else
- {
- byte[] tmp = new byte[msglen];
- System.arraycopy(msg, 0, tmp, 0, msglen);
- packets.addElement(tmp);
- }
-
- packets.notifyAll();
-
- if (packets.size() > 5)
- {
- connectionClosed = true;
- throw new IOException("Error, peer is flooding us with authentication packets.");
- }
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/channel/AuthAgentForwardThread.java b/app/src/main/java/com/trilead/ssh2/channel/AuthAgentForwardThread.java
deleted file mode 100644
index c6831e6..0000000
--- a/app/src/main/java/com/trilead/ssh2/channel/AuthAgentForwardThread.java
+++ /dev/null
@@ -1,579 +0,0 @@
-/*
- * ConnectBot: simple, powerful, open-source SSH client for Android
- * Copyright 2007 Kenny Root, Jeffrey Sharkey
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.trilead.ssh2.channel;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.math.BigInteger;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.spec.DSAPrivateKeySpec;
-import java.security.spec.DSAPublicKeySpec;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
-import java.security.spec.ECPrivateKeySpec;
-import java.security.spec.ECPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import java.security.spec.RSAPrivateCrtKeySpec;
-import java.security.spec.RSAPublicKeySpec;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import com.trilead.ssh2.AuthAgentCallback;
-import com.trilead.ssh2.log.Logger;
-import com.trilead.ssh2.packets.TypesReader;
-import com.trilead.ssh2.packets.TypesWriter;
-import com.trilead.ssh2.signature.DSASHA1Verify;
-import com.trilead.ssh2.signature.ECDSASHA2Verify;
-import com.trilead.ssh2.signature.RSASHA1Verify;
-
-/**
- * AuthAgentForwardThread.
- *
- * @author Kenny Root
- * @version $Id$
- */
-public class AuthAgentForwardThread extends Thread implements IChannelWorkerThread
-{
- private static final byte[] SSH_AGENT_FAILURE = {0, 0, 0, 1, 5}; // 5
- private static final byte[] SSH_AGENT_SUCCESS = {0, 0, 0, 1, 6}; // 6
-
- private static final int SSH2_AGENTC_REQUEST_IDENTITIES = 11;
- private static final int SSH2_AGENT_IDENTITIES_ANSWER = 12;
-
- private static final int SSH2_AGENTC_SIGN_REQUEST = 13;
- private static final int SSH2_AGENT_SIGN_RESPONSE = 14;
-
- private static final int SSH2_AGENTC_ADD_IDENTITY = 17;
- private static final int SSH2_AGENTC_REMOVE_IDENTITY = 18;
- private static final int SSH2_AGENTC_REMOVE_ALL_IDENTITIES = 19;
-
-// private static final int SSH_AGENTC_ADD_SMARTCARD_KEY = 20;
-// private static final int SSH_AGENTC_REMOVE_SMARTCARD_KEY = 21;
-
- private static final int SSH_AGENTC_LOCK = 22;
- private static final int SSH_AGENTC_UNLOCK = 23;
-
- private static final int SSH2_AGENTC_ADD_ID_CONSTRAINED = 25;
-// private static final int SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED = 26;
-
- // Constraints for adding keys
- private static final int SSH_AGENT_CONSTRAIN_LIFETIME = 1;
- private static final int SSH_AGENT_CONSTRAIN_CONFIRM = 2;
-
- // Flags for signature requests
-// private static final int SSH_AGENT_OLD_SIGNATURE = 1;
-
- private static final Logger log = Logger.getLogger(RemoteAcceptThread.class);
-
- AuthAgentCallback authAgent;
- OutputStream os;
- InputStream is;
- Channel c;
-
- byte[] buffer = new byte[Channel.CHANNEL_BUFFER_SIZE];
-
- public AuthAgentForwardThread(Channel c, AuthAgentCallback authAgent)
- {
- this.c = c;
- this.authAgent = authAgent;
-
- if (log.isEnabled())
- log.log(20, "AuthAgentForwardThread started");
- }
-
- @Override
- public void run()
- {
- try
- {
- c.cm.registerThread(this);
- }
- catch (IOException e)
- {
- stopWorking();
- return;
- }
-
- try
- {
- c.cm.sendOpenConfirmation(c);
-
- is = c.getStdoutStream();
- os = c.getStdinStream();
-
- int totalSize = 4;
- int readSoFar = 0;
-
- while (true) {
- int len;
-
- try
- {
- len = is.read(buffer, readSoFar, buffer.length - readSoFar);
- }
- catch (IOException e)
- {
- stopWorking();
- return;
- }
-
- if (len <= 0)
- break;
-
- readSoFar += len;
-
- if (readSoFar >= 4) {
- TypesReader tr = new TypesReader(buffer, 0, 4);
- totalSize = tr.readUINT32() + 4;
- }
-
- if (totalSize == readSoFar) {
- TypesReader tr = new TypesReader(buffer, 4, readSoFar - 4);
- int messageType = tr.readByte();
-
- switch (messageType) {
- case SSH2_AGENTC_REQUEST_IDENTITIES:
- sendIdentities();
- break;
- case SSH2_AGENTC_ADD_IDENTITY:
- addIdentity(tr, false);
- break;
- case SSH2_AGENTC_ADD_ID_CONSTRAINED:
- addIdentity(tr, true);
- break;
- case SSH2_AGENTC_REMOVE_IDENTITY:
- removeIdentity(tr);
- break;
- case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
- removeAllIdentities(tr);
- break;
- case SSH2_AGENTC_SIGN_REQUEST:
- processSignRequest(tr);
- break;
- case SSH_AGENTC_LOCK:
- processLockRequest(tr);
- break;
- case SSH_AGENTC_UNLOCK:
- processUnlockRequest(tr);
- break;
- default:
- os.write(SSH_AGENT_FAILURE);
- break;
- }
-
- readSoFar = 0;
- }
- }
-
- c.cm.closeChannel(c, "EOF on both streams reached.", true);
- }
- catch (IOException e)
- {
- log.log(50, "IOException in agent forwarder: " + e.getMessage());
-
- try
- {
- is.close();
- }
- catch (IOException e1)
- {
- }
-
- try
- {
- os.close();
- }
- catch (IOException e2)
- {
- }
-
- try
- {
- c.cm.closeChannel(c, "IOException in agent forwarder (" + e.getMessage() + ")", true);
- }
- catch (IOException e3)
- {
- }
- }
- }
-
- public void stopWorking() {
- try
- {
- /* This will lead to an IOException in the is.read() call */
- is.close();
- }
- catch (IOException e)
- {
- }
- }
-
- /**
- * @return whether the agent is locked
- */
- private boolean failWhenLocked() throws IOException
- {
- if (authAgent.isAgentLocked()) {
- os.write(SSH_AGENT_FAILURE);
- return true;
- } else
- return false;
- }
-
- private void sendIdentities() throws IOException
- {
- Map<String,byte[]> keys = null;
-
- TypesWriter tw = new TypesWriter();
- tw.writeByte(SSH2_AGENT_IDENTITIES_ANSWER);
- int numKeys = 0;
-
- if (!authAgent.isAgentLocked())
- keys = authAgent.retrieveIdentities();
-
- if (keys != null)
- numKeys = keys.size();
-
- tw.writeUINT32(numKeys);
-
- if (keys != null) {
- for (Entry<String,byte[]> entry : keys.entrySet()) {
- byte[] keyBytes = entry.getValue();
- tw.writeString(keyBytes, 0, keyBytes.length);
- tw.writeString(entry.getKey());
- }
- }
-
- sendPacket(tw.getBytes());
- }
-
- /**
- * @param tr
- */
- private void addIdentity(TypesReader tr, boolean checkConstraints) {
- try
- {
- if (failWhenLocked())
- return;
-
- String type = tr.readString();
-
- String comment;
- String keyType;
- KeySpec pubSpec;
- KeySpec privSpec;
-
- if (type.equals("ssh-rsa")) {
- keyType = "RSA";
-
- BigInteger n = tr.readMPINT();
- BigInteger e = tr.readMPINT();
- BigInteger d = tr.readMPINT();
- BigInteger iqmp = tr.readMPINT();
- BigInteger p = tr.readMPINT();
- BigInteger q = tr.readMPINT();
- comment = tr.readString();
-
- // Derive the extra values Java needs.
- BigInteger dmp1 = d.mod(p.subtract(BigInteger.ONE));
- BigInteger dmq1 = d.mod(q.subtract(BigInteger.ONE));
-
- pubSpec = new RSAPublicKeySpec(n, e);
- privSpec = new RSAPrivateCrtKeySpec(n, e, d, p, q, dmp1, dmq1, iqmp);
- } else if (type.equals("ssh-dss")) {
- keyType = "DSA";
-
- BigInteger p = tr.readMPINT();
- BigInteger q = tr.readMPINT();
- BigInteger g = tr.readMPINT();
- BigInteger y = tr.readMPINT();
- BigInteger x = tr.readMPINT();
- comment = tr.readString();
-
- pubSpec = new DSAPublicKeySpec(y, p, q, g);
- privSpec = new DSAPrivateKeySpec(x, p, q, g);
- } else if (type.equals("ecdsa-sha2-nistp256")) {
- keyType = "EC";
-
- String curveName = tr.readString();
- byte[] groupBytes = tr.readByteString();
- BigInteger exponent = tr.readMPINT();
- comment = tr.readString();
-
- if (!"nistp256".equals(curveName)) {
- log.log(2, "Invalid curve name for ecdsa-sha2-nistp256: " + curveName);
- os.write(SSH_AGENT_FAILURE);
- return;
- }
-
- ECParameterSpec nistp256 = ECDSASHA2Verify.EllipticCurves.nistp256;
- ECPoint group = ECDSASHA2Verify.decodeECPoint(groupBytes, nistp256.getCurve());
- if (group == null) {
- // TODO log error
- os.write(SSH_AGENT_FAILURE);
- return;
- }
-
- pubSpec = new ECPublicKeySpec(group, nistp256);
- privSpec = new ECPrivateKeySpec(exponent, nistp256);
- } else {
- log.log(2, "Unknown key type: " + type);
- os.write(SSH_AGENT_FAILURE);
- return;
- }
-
- PublicKey pubKey;
- PrivateKey privKey;
- try {
- KeyFactory kf = KeyFactory.getInstance(keyType);
- pubKey = kf.generatePublic(pubSpec);
- privKey = kf.generatePrivate(privSpec);
- } catch (NoSuchAlgorithmException ex) {
- // TODO: log error
- os.write(SSH_AGENT_FAILURE);
- return;
- } catch (InvalidKeySpecException ex) {
- // TODO: log error
- os.write(SSH_AGENT_FAILURE);
- return;
- }
-
- KeyPair pair = new KeyPair(pubKey, privKey);
-
- boolean confirmUse = false;
- int lifetime = 0;
-
- if (checkConstraints) {
- while (tr.remain() > 0) {
- int constraint = tr.readByte();
- if (constraint == SSH_AGENT_CONSTRAIN_CONFIRM)
- confirmUse = true;
- else if (constraint == SSH_AGENT_CONSTRAIN_LIFETIME)
- lifetime = tr.readUINT32();
- else {
- // Unknown constraint. Bail.
- os.write(SSH_AGENT_FAILURE);
- return;
- }
- }
- }
-
- if (authAgent.addIdentity(pair, comment, confirmUse, lifetime))
- os.write(SSH_AGENT_SUCCESS);
- else
- os.write(SSH_AGENT_FAILURE);
- }
- catch (IOException e)
- {
- try
- {
- os.write(SSH_AGENT_FAILURE);
- }
- catch (IOException e1)
- {
- }
- }
- }
-
- /**
- * @param tr
- */
- private void removeIdentity(TypesReader tr) {
- try
- {
- if (failWhenLocked())
- return;
-
- byte[] publicKey = tr.readByteString();
- if (authAgent.removeIdentity(publicKey))
- os.write(SSH_AGENT_SUCCESS);
- else
- os.write(SSH_AGENT_FAILURE);
- }
- catch (IOException e)
- {
- try
- {
- os.write(SSH_AGENT_FAILURE);
- }
- catch (IOException e1)
- {
- }
- }
- }
-
- /**
- * @param tr
- */
- private void removeAllIdentities(TypesReader tr) {
- try
- {
- if (failWhenLocked())
- return;
-
- if (authAgent.removeAllIdentities())
- os.write(SSH_AGENT_SUCCESS);
- else
- os.write(SSH_AGENT_FAILURE);
- }
- catch (IOException e)
- {
- try
- {
- os.write(SSH_AGENT_FAILURE);
- }
- catch (IOException e1)
- {
- }
- }
- }
-
- private void processSignRequest(TypesReader tr)
- {
- try
- {
- if (failWhenLocked())
- return;
-
- byte[] publicKeyBytes = tr.readByteString();
- byte[] challenge = tr.readByteString();
-
- int flags = tr.readUINT32();
-
- if (flags != 0) {
- // We don't understand any flags; abort!
- os.write(SSH_AGENT_FAILURE);
- return;
- }
-
- KeyPair pair = authAgent.getKeyPair(publicKeyBytes);
-
- if (pair == null) {
- os.write(SSH_AGENT_FAILURE);
- return;
- }
-
- byte[] response;
-
- PrivateKey privKey = pair.getPrivate();
- if (privKey instanceof RSAPrivateKey) {
- byte[] signature = RSASHA1Verify.generateSignature(challenge,
- (RSAPrivateKey) privKey);
- response = RSASHA1Verify.encodeSSHRSASignature(signature);
- } else if (privKey instanceof DSAPrivateKey) {
- byte[] signature = DSASHA1Verify.generateSignature(challenge,
- (DSAPrivateKey) privKey, new SecureRandom());
- response = DSASHA1Verify.encodeSSHDSASignature(signature);
- } else {
- os.write(SSH_AGENT_FAILURE);
- return;
- }
-
- TypesWriter tw = new TypesWriter();
- tw.writeByte(SSH2_AGENT_SIGN_RESPONSE);
- tw.writeString(response, 0, response.length);
-
- sendPacket(tw.getBytes());
- }
- catch (IOException e)
- {
- try
- {
- os.write(SSH_AGENT_FAILURE);
- }
- catch (IOException e1)
- {
- }
- }
- }
-
- /**
- * @param tr
- */
- private void processLockRequest(TypesReader tr) {
- try
- {
- if (failWhenLocked())
- return;
-
- String lockPassphrase = tr.readString();
- if (!authAgent.setAgentLock(lockPassphrase)) {
- os.write(SSH_AGENT_FAILURE);
- return;
- } else
- os.write(SSH_AGENT_SUCCESS);
- }
- catch (IOException e)
- {
- try
- {
- os.write(SSH_AGENT_FAILURE);
- }
- catch (IOException e1)
- {
- }
- }
- }
-
- /**
- * @param tr
- */
- private void processUnlockRequest(TypesReader tr)
- {
- try
- {
- String unlockPassphrase = tr.readString();
-
- if (authAgent.requestAgentUnlock(unlockPassphrase))
- os.write(SSH_AGENT_SUCCESS);
- else
- os.write(SSH_AGENT_FAILURE);
- }
- catch (IOException e)
- {
- try
- {
- os.write(SSH_AGENT_FAILURE);
- }
- catch (IOException e1)
- {
- }
- }
- }
-
- /**
- * @param tw
- * @throws IOException
- */
- private void sendPacket(byte[] message) throws IOException
- {
- TypesWriter packet = new TypesWriter();
- packet.writeUINT32(message.length);
- packet.writeBytes(message);
- os.write(packet.getBytes());
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/channel/Channel.java b/app/src/main/java/com/trilead/ssh2/channel/Channel.java
deleted file mode 100644
index 8365f12..0000000
--- a/app/src/main/java/com/trilead/ssh2/channel/Channel.java
+++ /dev/null
@@ -1,207 +0,0 @@
-
-package com.trilead.ssh2.channel;
-
-/**
- * Channel.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: Channel.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public class Channel
-{
- /*
- * OK. Here is an important part of the JVM Specification:
- * (http://java.sun.com/docs/books/vmspec/2nd-edition/html/Threads.doc.html#22214)
- *
- * Any association between locks and variables is purely conventional.
- * Locking any lock conceptually flushes all variables from a thread's
- * working memory, and unlocking any lock forces the writing out to main
- * memory of all variables that the thread has assigned. That a lock may be
- * associated with a particular object or a class is purely a convention.
- * (...)
- *
- * If a thread uses a particular shared variable only after locking a
- * particular lock and before the corresponding unlocking of that same lock,
- * then the thread will read the shared value of that variable from main
- * memory after the lock operation, if necessary, and will copy back to main
- * memory the value most recently assigned to that variable before the
- * unlock operation.
- *
- * This, in conjunction with the mutual exclusion rules for locks, suffices
- * to guarantee that values are correctly transmitted from one thread to
- * another through shared variables.
- *
- * ====> Always keep that in mind when modifying the Channel/ChannelManger
- * code.
- *
- */
-
- static final int STATE_OPENING = 1;
- static final int STATE_OPEN = 2;
- static final int STATE_CLOSED = 4;
-
- static final int CHANNEL_BUFFER_SIZE = 30000;
-
- /*
- * To achieve correctness, the following rules have to be respected when
- * accessing this object:
- */
-
- // These fields can always be read
- final ChannelManager cm;
- final ChannelOutputStream stdinStream;
- final ChannelInputStream stdoutStream;
- final ChannelInputStream stderrStream;
-
- // These two fields will only be written while the Channel is in state
- // STATE_OPENING.
- // The code makes sure that the two fields are written out when the state is
- // changing to STATE_OPEN.
- // Therefore, if you know that the Channel is in state STATE_OPEN, then you
- // can read these two fields without synchronizing on the Channel. However, make
- // sure that you get the latest values (e.g., flush caches by synchronizing on any
- // object). However, to be on the safe side, you can lock the channel.
-
- int localID = -1;
- int remoteID = -1;
-
- /*
- * Make sure that we never send a data/EOF/WindowChange msg after a CLOSE
- * msg.
- *
- * This is a little bit complicated, but we have to do it in that way, since
- * we cannot keep a lock on the Channel during the send operation (this
- * would block sometimes the receiver thread, and, in extreme cases, can
- * lead to a deadlock on both sides of the connection (senders are blocked
- * since the receive buffers on the other side are full, and receiver
- * threads wait for the senders to finish). It all depends on the
- * implementation on the other side. But we cannot make any assumptions, we
- * have to assume the worst case. Confused? Just believe me.
- */
-
- /*
- * If you send a message on a channel, then you have to aquire the
- * "channelSendLock" and check the "closeMessageSent" flag (this variable
- * may only be accessed while holding the "channelSendLock" !!!
- *
- * BTW: NEVER EVER SEND MESSAGES FROM THE RECEIVE THREAD - see explanation
- * above.
- */
-
- final Object channelSendLock = new Object();
- boolean closeMessageSent = false;
-
- /*
- * Stop memory fragmentation by allocating this often used buffer.
- * May only be used while holding the channelSendLock
- */
-
- final byte[] msgWindowAdjust = new byte[9];
-
- // If you access (read or write) any of the following fields, then you have
- // to synchronize on the channel.
-
- int state = STATE_OPENING;
-
- boolean closeMessageRecv = false;
-
- /* This is a stupid implementation. At the moment we can only wait
- * for one pending request per channel.
- */
- int successCounter = 0;
- int failedCounter = 0;
-
- int localWindow = 0; /* locally, we use a small window, < 2^31 */
- long remoteWindow = 0; /* long for readable 2^32 - 1 window support */
-
- int localMaxPacketSize = -1;
- int remoteMaxPacketSize = -1;
-
- final byte[] stdoutBuffer = new byte[CHANNEL_BUFFER_SIZE];
- final byte[] stderrBuffer = new byte[CHANNEL_BUFFER_SIZE];
-
- int stdoutReadpos = 0;
- int stdoutWritepos = 0;
- int stderrReadpos = 0;
- int stderrWritepos = 0;
-
- boolean EOF = false;
-
- Integer exit_status;
-
- String exit_signal;
-
- // we keep the x11 cookie so that this channel can be closed when this
- // specific x11 forwarding gets stopped
-
- String hexX11FakeCookie;
-
- // reasonClosed is special, since we sometimes need to access it
- // while holding the channelSendLock.
- // We protect it with a private short term lock.
-
- private final Object reasonClosedLock = new Object();
- private String reasonClosed = null;
-
- public Channel(ChannelManager cm)
- {
- this.cm = cm;
-
- this.localWindow = CHANNEL_BUFFER_SIZE;
- this.localMaxPacketSize = 35000 - 1024; // leave enough slack
-
- this.stdinStream = new ChannelOutputStream(this);
- this.stdoutStream = new ChannelInputStream(this, false);
- this.stderrStream = new ChannelInputStream(this, true);
- }
-
- /* Methods to allow access from classes outside of this package */
-
- public ChannelInputStream getStderrStream()
- {
- return stderrStream;
- }
-
- public ChannelOutputStream getStdinStream()
- {
- return stdinStream;
- }
-
- public ChannelInputStream getStdoutStream()
- {
- return stdoutStream;
- }
-
- public String getExitSignal()
- {
- synchronized (this)
- {
- return exit_signal;
- }
- }
-
- public Integer getExitStatus()
- {
- synchronized (this)
- {
- return exit_status;
- }
- }
-
- public String getReasonClosed()
- {
- synchronized (reasonClosedLock)
- {
- return reasonClosed;
- }
- }
-
- public void setReasonClosed(String reasonClosed)
- {
- synchronized (reasonClosedLock)
- {
- if (this.reasonClosed == null)
- this.reasonClosed = reasonClosed;
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/channel/ChannelInputStream.java b/app/src/main/java/com/trilead/ssh2/channel/ChannelInputStream.java
deleted file mode 100644
index f88522c..0000000
--- a/app/src/main/java/com/trilead/ssh2/channel/ChannelInputStream.java
+++ /dev/null
@@ -1,86 +0,0 @@
-
-package com.trilead.ssh2.channel;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * ChannelInputStream.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: ChannelInputStream.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public final class ChannelInputStream extends InputStream
-{
- Channel c;
-
- boolean isClosed = false;
- boolean isEOF = false;
- boolean extendedFlag = false;
-
- ChannelInputStream(Channel c, boolean isExtended)
- {
- this.c = c;
- this.extendedFlag = isExtended;
- }
-
- public int available() throws IOException
- {
- if (isEOF)
- return 0;
-
- int avail = c.cm.getAvailable(c, extendedFlag);
-
- /* We must not return -1 on EOF */
-
- return (avail > 0) ? avail : 0;
- }
-
- public void close() throws IOException
- {
- isClosed = true;
- }
-
- public int read(byte[] b, int off, int len) throws IOException
- {
- if (b == null)
- throw new NullPointerException();
-
- if ((off < 0) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0) || (off > b.length))
- throw new IndexOutOfBoundsException();
-
- if (len == 0)
- return 0;
-
- if (isEOF)
- return -1;
-
- int ret = c.cm.getChannelData(c, extendedFlag, b, off, len);
-
- if (ret == -1)
- {
- isEOF = true;
- }
-
- return ret;
- }
-
- public int read(byte[] b) throws IOException
- {
- return read(b, 0, b.length);
- }
-
- public int read() throws IOException
- {
- /* Yes, this stream is pure and unbuffered, a single byte read() is slow */
-
- final byte b[] = new byte[1];
-
- int ret = read(b, 0, 1);
-
- if (ret != 1)
- return -1;
-
- return b[0] & 0xff;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/channel/ChannelManager.java b/app/src/main/java/com/trilead/ssh2/channel/ChannelManager.java
deleted file mode 100644
index 88beffd..0000000
--- a/app/src/main/java/com/trilead/ssh2/channel/ChannelManager.java
+++ /dev/null
@@ -1,1756 +0,0 @@
-
-package com.trilead.ssh2.channel;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Vector;
-
-import com.trilead.ssh2.AuthAgentCallback;
-import com.trilead.ssh2.ChannelCondition;
-import com.trilead.ssh2.log.Logger;
-import com.trilead.ssh2.packets.PacketChannelAuthAgentReq;
-import com.trilead.ssh2.packets.PacketChannelOpenConfirmation;
-import com.trilead.ssh2.packets.PacketChannelOpenFailure;
-import com.trilead.ssh2.packets.PacketChannelTrileadPing;
-import com.trilead.ssh2.packets.PacketGlobalCancelForwardRequest;
-import com.trilead.ssh2.packets.PacketGlobalForwardRequest;
-import com.trilead.ssh2.packets.PacketGlobalTrileadPing;
-import com.trilead.ssh2.packets.PacketOpenDirectTCPIPChannel;
-import com.trilead.ssh2.packets.PacketOpenSessionChannel;
-import com.trilead.ssh2.packets.PacketSessionExecCommand;
-import com.trilead.ssh2.packets.PacketSessionPtyRequest;
-import com.trilead.ssh2.packets.PacketSessionPtyResize;
-import com.trilead.ssh2.packets.PacketSessionStartShell;
-import com.trilead.ssh2.packets.PacketSessionSubsystemRequest;
-import com.trilead.ssh2.packets.PacketSessionX11Request;
-import com.trilead.ssh2.packets.Packets;
-import com.trilead.ssh2.packets.TypesReader;
-import com.trilead.ssh2.transport.MessageHandler;
-import com.trilead.ssh2.transport.TransportManager;
-
-/**
- * ChannelManager. Please read the comments in Channel.java.
- * <p>
- * Besides the crypto part, this is the core of the library.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: ChannelManager.java,v 1.2 2008/03/03 07:01:36 cplattne Exp $
- */
-public class ChannelManager implements MessageHandler
-{
- private static final Logger log = Logger.getLogger(ChannelManager.class);
-
- private HashMap<String, X11ServerData> x11_magic_cookies = new HashMap<String, X11ServerData>();
-
- private TransportManager tm;
-
- private Vector<Channel> channels = new Vector<Channel>();
- private int nextLocalChannel = 100;
- private boolean shutdown = false;
- private int globalSuccessCounter = 0;
- private int globalFailedCounter = 0;
-
- private HashMap<Integer, RemoteForwardingData> remoteForwardings = new HashMap<Integer, RemoteForwardingData>();
-
- private AuthAgentCallback authAgent;
-
- private Vector<IChannelWorkerThread> listenerThreads = new Vector<IChannelWorkerThread>();
-
- private boolean listenerThreadsAllowed = true;
-
- public ChannelManager(TransportManager tm)
- {
- this.tm = tm;
- tm.registerMessageHandler(this, 80, 100);
- }
-
- private Channel getChannel(int id)
- {
- synchronized (channels)
- {
- for (int i = 0; i < channels.size(); i++)
- {
- Channel c = channels.elementAt(i);
- if (c.localID == id)
- return c;
- }
- }
- return null;
- }
-
- private void removeChannel(int id)
- {
- synchronized (channels)
- {
- for (int i = 0; i < channels.size(); i++)
- {
- Channel c = channels.elementAt(i);
- if (c.localID == id)
- {
- channels.removeElementAt(i);
- break;
- }
- }
- }
- }
-
- private int addChannel(Channel c)
- {
- synchronized (channels)
- {
- channels.addElement(c);
- return nextLocalChannel++;
- }
- }
-
- private void waitUntilChannelOpen(Channel c) throws IOException
- {
- synchronized (c)
- {
- while (c.state == Channel.STATE_OPENING)
- {
- try
- {
- c.wait();
- }
- catch (InterruptedException ignore)
- {
- }
- }
-
- if (c.state != Channel.STATE_OPEN)
- {
- removeChannel(c.localID);
-
- String detail = c.getReasonClosed();
-
- if (detail == null)
- detail = "state: " + c.state;
-
- throw new IOException("Could not open channel (" + detail + ")");
- }
- }
- }
-
- private final boolean waitForGlobalRequestResult() throws IOException
- {
- synchronized (channels)
- {
- while ((globalSuccessCounter == 0) && (globalFailedCounter == 0))
- {
- if (shutdown)
- {
- throw new IOException("The connection is being shutdown");
- }
-
- try
- {
- channels.wait();
- }
- catch (InterruptedException ignore)
- {
- }
- }
-
- if ((globalFailedCounter == 0) && (globalSuccessCounter == 1))
- return true;
-
- if ((globalFailedCounter == 1) && (globalSuccessCounter == 0))
- return false;
-
- throw new IOException("Illegal state. The server sent " + globalSuccessCounter
- + " SSH_MSG_REQUEST_SUCCESS and " + globalFailedCounter + " SSH_MSG_REQUEST_FAILURE messages.");
- }
- }
-
- private final boolean waitForChannelRequestResult(Channel c) throws IOException
- {
- synchronized (c)
- {
- while ((c.successCounter == 0) && (c.failedCounter == 0))
- {
- if (c.state != Channel.STATE_OPEN)
- {
- String detail = c.getReasonClosed();
-
- if (detail == null)
- detail = "state: " + c.state;
-
- throw new IOException("This SSH2 channel is not open (" + detail + ")");
- }
-
- try
- {
- c.wait();
- }
- catch (InterruptedException ignore)
- {
- }
- }
-
- if ((c.failedCounter == 0) && (c.successCounter == 1))
- return true;
-
- if ((c.failedCounter == 1) && (c.successCounter == 0))
- return false;
-
- throw new IOException("Illegal state. The server sent " + c.successCounter
- + " SSH_MSG_CHANNEL_SUCCESS and " + c.failedCounter + " SSH_MSG_CHANNEL_FAILURE messages.");
- }
- }
-
- public void registerX11Cookie(String hexFakeCookie, X11ServerData data)
- {
- synchronized (x11_magic_cookies)
- {
- x11_magic_cookies.put(hexFakeCookie, data);
- }
- }
-
- public void unRegisterX11Cookie(String hexFakeCookie, boolean killChannels)
- {
- if (hexFakeCookie == null)
- throw new IllegalStateException("hexFakeCookie may not be null");
-
- synchronized (x11_magic_cookies)
- {
- x11_magic_cookies.remove(hexFakeCookie);
- }
-
- if (killChannels == false)
- return;
-
- if (log.isEnabled())
- log.log(50, "Closing all X11 channels for the given fake cookie");
-
- Vector<Channel> channel_copy;
-
- synchronized (channels)
- {
- channel_copy = (Vector<Channel>) channels.clone();
- }
-
- for (int i = 0; i < channel_copy.size(); i++)
- {
- Channel c = channel_copy.elementAt(i);
-
- synchronized (c)
- {
- if (hexFakeCookie.equals(c.hexX11FakeCookie) == false)
- continue;
- }
-
- try
- {
- closeChannel(c, "Closing X11 channel since the corresponding session is closing", true);
- }
- catch (IOException e)
- {
- }
- }
- }
-
- public X11ServerData checkX11Cookie(String hexFakeCookie)
- {
- synchronized (x11_magic_cookies)
- {
- if (hexFakeCookie != null)
- return x11_magic_cookies.get(hexFakeCookie);
- }
- return null;
- }
-
- public void closeAllChannels()
- {
- if (log.isEnabled())
- log.log(50, "Closing all channels");
-
- Vector<Channel> channel_copy;
-
- synchronized (channels)
- {
- channel_copy = (Vector<Channel>) channels.clone();
- }
-
- for (int i = 0; i < channel_copy.size(); i++)
- {
- Channel c = channel_copy.elementAt(i);
- try
- {
- closeChannel(c, "Closing all channels", true);
- }
- catch (IOException e)
- {
- }
- }
- }
-
- public void closeChannel(Channel c, String reason, boolean force) throws IOException
- {
- byte msg[] = new byte[5];
-
- synchronized (c)
- {
- if (force)
- {
- c.state = Channel.STATE_CLOSED;
- c.EOF = true;
- }
-
- c.setReasonClosed(reason);
-
- msg[0] = Packets.SSH_MSG_CHANNEL_CLOSE;
- msg[1] = (byte) (c.remoteID >> 24);
- msg[2] = (byte) (c.remoteID >> 16);
- msg[3] = (byte) (c.remoteID >> 8);
- msg[4] = (byte) (c.remoteID);
-
- c.notifyAll();
- }
-
- synchronized (c.channelSendLock)
- {
- if (c.closeMessageSent == true)
- return;
- tm.sendMessage(msg);
- c.closeMessageSent = true;
- }
-
- if (log.isEnabled())
- log.log(50, "Sent SSH_MSG_CHANNEL_CLOSE (channel " + c.localID + ")");
- }
-
- public void sendEOF(Channel c) throws IOException
- {
- byte[] msg = new byte[5];
-
- synchronized (c)
- {
- if (c.state != Channel.STATE_OPEN)
- return;
-
- msg[0] = Packets.SSH_MSG_CHANNEL_EOF;
- msg[1] = (byte) (c.remoteID >> 24);
- msg[2] = (byte) (c.remoteID >> 16);
- msg[3] = (byte) (c.remoteID >> 8);
- msg[4] = (byte) (c.remoteID);
- }
-
- synchronized (c.channelSendLock)
- {
- if (c.closeMessageSent == true)
- return;
- tm.sendMessage(msg);
- }
-
- if (log.isEnabled())
- log.log(50, "Sent EOF (Channel " + c.localID + "/" + c.remoteID + ")");
- }
-
- public void sendOpenConfirmation(Channel c) throws IOException
- {
- PacketChannelOpenConfirmation pcoc = null;
-
- synchronized (c)
- {
- if (c.state != Channel.STATE_OPENING)
- return;
-
- c.state = Channel.STATE_OPEN;
-
- pcoc = new PacketChannelOpenConfirmation(c.remoteID, c.localID, c.localWindow, c.localMaxPacketSize);
- }
-
- synchronized (c.channelSendLock)
- {
- if (c.closeMessageSent == true)
- return;
- tm.sendMessage(pcoc.getPayload());
- }
- }
-
- public void sendData(Channel c, byte[] buffer, int pos, int len) throws IOException
- {
- while (len > 0)
- {
- int thislen = 0;
- byte[] msg;
-
- synchronized (c)
- {
- while (true)
- {
- if (c.state == Channel.STATE_CLOSED)
- throw new IOException("SSH channel is closed. (" + c.getReasonClosed() + ")");
-
- if (c.state != Channel.STATE_OPEN)
- throw new IOException("SSH channel in strange state. (" + c.state + ")");
-
- if (c.remoteWindow != 0)
- break;
-
- try
- {
- c.wait();
- }
- catch (InterruptedException ignore)
- {
- }
- }
-
- /* len > 0, no sign extension can happen when comparing */
-
- thislen = (c.remoteWindow >= len) ? len : (int) c.remoteWindow;
-
- int estimatedMaxDataLen = c.remoteMaxPacketSize - (tm.getPacketOverheadEstimate() + 9);
-
- /* The worst case scenario =) a true bottleneck */
-
- if (estimatedMaxDataLen <= 0)
- {
- estimatedMaxDataLen = 1;
- }
-
- if (thislen > estimatedMaxDataLen)
- thislen = estimatedMaxDataLen;
-
- c.remoteWindow -= thislen;
-
- msg = new byte[1 + 8 + thislen];
-
- msg[0] = Packets.SSH_MSG_CHANNEL_DATA;
- msg[1] = (byte) (c.remoteID >> 24);
- msg[2] = (byte) (c.remoteID >> 16);
- msg[3] = (byte) (c.remoteID >> 8);
- msg[4] = (byte) (c.remoteID);
- msg[5] = (byte) (thislen >> 24);
- msg[6] = (byte) (thislen >> 16);
- msg[7] = (byte) (thislen >> 8);
- msg[8] = (byte) (thislen);
-
- System.arraycopy(buffer, pos, msg, 9, thislen);
- }
-
- synchronized (c.channelSendLock)
- {
- if (c.closeMessageSent == true)
- throw new IOException("SSH channel is closed. (" + c.getReasonClosed() + ")");
-
- tm.sendMessage(msg);
- }
-
- pos += thislen;
- len -= thislen;
- }
- }
-
- public int requestGlobalForward(String bindAddress, int bindPort, String targetAddress, int targetPort)
- throws IOException
- {
- RemoteForwardingData rfd = new RemoteForwardingData();
-
- rfd.bindAddress = bindAddress;
- rfd.bindPort = bindPort;
- rfd.targetAddress = targetAddress;
- rfd.targetPort = targetPort;
-
- synchronized (remoteForwardings)
- {
- Integer key = Integer.valueOf(bindPort);
-
- if (remoteForwardings.get(key) != null)
- {
- throw new IOException("There is already a forwarding for remote port " + bindPort);
- }
-
- remoteForwardings.put(key, rfd);
- }
-
- synchronized (channels)
- {
- globalSuccessCounter = globalFailedCounter = 0;
- }
-
- PacketGlobalForwardRequest pgf = new PacketGlobalForwardRequest(true, bindAddress, bindPort);
- tm.sendMessage(pgf.getPayload());
-
- if (log.isEnabled())
- log.log(50, "Requesting a remote forwarding ('" + bindAddress + "', " + bindPort + ")");
-
- try
- {
- if (waitForGlobalRequestResult() == false)
- throw new IOException("The server denied the request (did you enable port forwarding?)");
- }
- catch (IOException e)
- {
- synchronized (remoteForwardings)
- {
- remoteForwardings.remove(rfd);
- }
- throw e;
- }
-
- return bindPort;
- }
-
- public void requestCancelGlobalForward(int bindPort) throws IOException
- {
- RemoteForwardingData rfd = null;
-
- synchronized (remoteForwardings)
- {
- rfd = remoteForwardings.get(Integer.valueOf(bindPort));
-
- if (rfd == null)
- throw new IOException("Sorry, there is no known remote forwarding for remote port " + bindPort);
- }
-
- synchronized (channels)
- {
- globalSuccessCounter = globalFailedCounter = 0;
- }
-
- PacketGlobalCancelForwardRequest pgcf = new PacketGlobalCancelForwardRequest(true, rfd.bindAddress,
- rfd.bindPort);
- tm.sendMessage(pgcf.getPayload());
-
- if (log.isEnabled())
- log.log(50, "Requesting cancelation of remote forward ('" + rfd.bindAddress + "', " + rfd.bindPort + ")");
-
- try
- {
- if (waitForGlobalRequestResult() == false)
- throw new IOException("The server denied the request.");
- }
- finally
- {
- synchronized (remoteForwardings)
- {
- /* Only now we are sure that no more forwarded connections will arrive */
- remoteForwardings.remove(rfd);
- }
- }
-
- }
-
- /**
- * @param agent
- * @throws IOException
- */
- public boolean requestChannelAgentForwarding(Channel c, AuthAgentCallback authAgent) throws IOException {
- synchronized (this)
- {
- if (this.authAgent != null)
- throw new IllegalStateException("Auth agent already exists");
-
- this.authAgent = authAgent;
- }
-
- synchronized (channels)
- {
- globalSuccessCounter = globalFailedCounter = 0;
- }
-
- if (log.isEnabled())
- log.log(50, "Requesting agent forwarding");
-
- PacketChannelAuthAgentReq aar = new PacketChannelAuthAgentReq(c.remoteID);
- tm.sendMessage(aar.getPayload());
-
- if (waitForChannelRequestResult(c) == false) {
- authAgent = null;
- return false;
- }
-
- return true;
- }
-
- public void registerThread(IChannelWorkerThread thr) throws IOException
- {
- synchronized (listenerThreads)
- {
- if (listenerThreadsAllowed == false)
- throw new IOException("Too late, this connection is closed.");
- listenerThreads.addElement(thr);
- }
- }
-
- public Channel openDirectTCPIPChannel(String host_to_connect, int port_to_connect, String originator_IP_address,
- int originator_port) throws IOException
- {
- Channel c = new Channel(this);
-
- synchronized (c)
- {
- c.localID = addChannel(c);
- // end of synchronized block forces writing out to main memory
- }
-
- PacketOpenDirectTCPIPChannel dtc = new PacketOpenDirectTCPIPChannel(c.localID, c.localWindow,
- c.localMaxPacketSize, host_to_connect, port_to_connect, originator_IP_address, originator_port);
-
- tm.sendMessage(dtc.getPayload());
-
- waitUntilChannelOpen(c);
-
- return c;
- }
-
- public Channel openSessionChannel() throws IOException
- {
- Channel c = new Channel(this);
-
- synchronized (c)
- {
- c.localID = addChannel(c);
- // end of synchronized block forces the writing out to main memory
- }
-
- if (log.isEnabled())
- log.log(50, "Sending SSH_MSG_CHANNEL_OPEN (Channel " + c.localID + ")");
-
- PacketOpenSessionChannel smo = new PacketOpenSessionChannel(c.localID, c.localWindow, c.localMaxPacketSize);
- tm.sendMessage(smo.getPayload());
-
- waitUntilChannelOpen(c);
-
- return c;
- }
-
- public void requestGlobalTrileadPing() throws IOException
- {
- synchronized (channels)
- {
- globalSuccessCounter = globalFailedCounter = 0;
- }
-
- PacketGlobalTrileadPing pgtp = new PacketGlobalTrileadPing();
-
- tm.sendMessage(pgtp.getPayload());
-
- if (log.isEnabled())
- log.log(50, "Sending SSH_MSG_GLOBAL_REQUEST 'trilead-ping'.");
-
- try
- {
- if (waitForGlobalRequestResult() == true)
- throw new IOException("Your server is alive - but buggy. "
- + "It replied with SSH_MSG_REQUEST_SUCCESS when it actually should not.");
-
- }
- catch (IOException e)
- {
- throw (IOException) new IOException("The ping request failed.").initCause(e);
- }
- }
-
- public void requestChannelTrileadPing(Channel c) throws IOException
- {
- PacketChannelTrileadPing pctp;
-
- synchronized (c)
- {
- if (c.state != Channel.STATE_OPEN)
- throw new IOException("Cannot ping this channel (" + c.getReasonClosed() + ")");
-
- pctp = new PacketChannelTrileadPing(c.remoteID);
-
- c.successCounter = c.failedCounter = 0;
- }
-
- synchronized (c.channelSendLock)
- {
- if (c.closeMessageSent)
- throw new IOException("Cannot ping this channel (" + c.getReasonClosed() + ")");
- tm.sendMessage(pctp.getPayload());
- }
-
- try
- {
- if (waitForChannelRequestResult(c) == true)
- throw new IOException("Your server is alive - but buggy. "
- + "It replied with SSH_MSG_SESSION_SUCCESS when it actually should not.");
-
- }
- catch (IOException e)
- {
- throw (IOException) new IOException("The ping request failed.").initCause(e);
- }
- }
-
- public void requestPTY(Channel c, String term, int term_width_characters, int term_height_characters,
- int term_width_pixels, int term_height_pixels, byte[] terminal_modes) throws IOException
- {
- PacketSessionPtyRequest spr;
-
- synchronized (c)
- {
- if (c.state != Channel.STATE_OPEN)
- throw new IOException("Cannot request PTY on this channel (" + c.getReasonClosed() + ")");
-
- spr = new PacketSessionPtyRequest(c.remoteID, true, term, term_width_characters, term_height_characters,
- term_width_pixels, term_height_pixels, terminal_modes);
-
- c.successCounter = c.failedCounter = 0;
- }
-
- synchronized (c.channelSendLock)
- {
- if (c.closeMessageSent)
- throw new IOException("Cannot request PTY on this channel (" + c.getReasonClosed() + ")");
- tm.sendMessage(spr.getPayload());
- }
-
- try
- {
- if (waitForChannelRequestResult(c) == false)
- throw new IOException("The server denied the request.");
- }
- catch (IOException e)
- {
- throw (IOException) new IOException("PTY request failed").initCause(e);
- }
- }
-
-
- public void resizePTY(Channel c, int term_width_characters, int term_height_characters,
- int term_width_pixels, int term_height_pixels) throws IOException {
- PacketSessionPtyResize spr;
-
- synchronized (c) {
- if (c.state != Channel.STATE_OPEN)
- throw new IOException("Cannot request PTY on this channel ("
- + c.getReasonClosed() + ")");
-
- spr = new PacketSessionPtyResize(c.remoteID, term_width_characters, term_height_characters,
- term_width_pixels, term_height_pixels);
- c.successCounter = c.failedCounter = 0;
- }
-
- synchronized (c.channelSendLock) {
- if (c.closeMessageSent)
- throw new IOException("Cannot request PTY on this channel ("
- + c.getReasonClosed() + ")");
- tm.sendMessage(spr.getPayload());
- }
- }
-
-
- public void requestX11(Channel c, boolean singleConnection, String x11AuthenticationProtocol,
- String x11AuthenticationCookie, int x11ScreenNumber) throws IOException
- {
- PacketSessionX11Request psr;
-
- synchronized (c)
- {
- if (c.state != Channel.STATE_OPEN)
- throw new IOException("Cannot request X11 on this channel (" + c.getReasonClosed() + ")");
-
- psr = new PacketSessionX11Request(c.remoteID, true, singleConnection, x11AuthenticationProtocol,
- x11AuthenticationCookie, x11ScreenNumber);
-
- c.successCounter = c.failedCounter = 0;
- }
-
- synchronized (c.channelSendLock)
- {
- if (c.closeMessageSent)
- throw new IOException("Cannot request X11 on this channel (" + c.getReasonClosed() + ")");
- tm.sendMessage(psr.getPayload());
- }
-
- if (log.isEnabled())
- log.log(50, "Requesting X11 forwarding (Channel " + c.localID + "/" + c.remoteID + ")");
-
- try
- {
- if (waitForChannelRequestResult(c) == false)
- throw new IOException("The server denied the request.");
- }
- catch (IOException e)
- {
- throw (IOException) new IOException("The X11 request failed.").initCause(e);
- }
- }
-
- public void requestSubSystem(Channel c, String subSystemName) throws IOException
- {
- PacketSessionSubsystemRequest ssr;
-
- synchronized (c)
- {
- if (c.state != Channel.STATE_OPEN)
- throw new IOException("Cannot request subsystem on this channel (" + c.getReasonClosed() + ")");
-
- ssr = new PacketSessionSubsystemRequest(c.remoteID, true, subSystemName);
-
- c.successCounter = c.failedCounter = 0;
- }
-
- synchronized (c.channelSendLock)
- {
- if (c.closeMessageSent)
- throw new IOException("Cannot request subsystem on this channel (" + c.getReasonClosed() + ")");
- tm.sendMessage(ssr.getPayload());
- }
-
- try
- {
- if (waitForChannelRequestResult(c) == false)
- throw new IOException("The server denied the request.");
- }
- catch (IOException e)
- {
- throw (IOException) new IOException("The subsystem request failed.").initCause(e);
- }
- }
-
- public void requestExecCommand(Channel c, String cmd) throws IOException
- {
- PacketSessionExecCommand sm;
-
- synchronized (c)
- {
- if (c.state != Channel.STATE_OPEN)
- throw new IOException("Cannot execute command on this channel (" + c.getReasonClosed() + ")");
-
- sm = new PacketSessionExecCommand(c.remoteID, true, cmd);
-
- c.successCounter = c.failedCounter = 0;
- }
-
- synchronized (c.channelSendLock)
- {
- if (c.closeMessageSent)
- throw new IOException("Cannot execute command on this channel (" + c.getReasonClosed() + ")");
- tm.sendMessage(sm.getPayload());
- }
-
- if (log.isEnabled())
- log.log(50, "Executing command (channel " + c.localID + ", '" + cmd + "')");
-
- try
- {
- if (waitForChannelRequestResult(c) == false)
- throw new IOException("The server denied the request.");
- }
- catch (IOException e)
- {
- throw (IOException) new IOException("The execute request failed.").initCause(e);
- }
- }
-
- public void requestShell(Channel c) throws IOException
- {
- PacketSessionStartShell sm;
-
- synchronized (c)
- {
- if (c.state != Channel.STATE_OPEN)
- throw new IOException("Cannot start shell on this channel (" + c.getReasonClosed() + ")");
-
- sm = new PacketSessionStartShell(c.remoteID, true);
-
- c.successCounter = c.failedCounter = 0;
- }
-
- synchronized (c.channelSendLock)
- {
- if (c.closeMessageSent)
- throw new IOException("Cannot start shell on this channel (" + c.getReasonClosed() + ")");
- tm.sendMessage(sm.getPayload());
- }
-
- try
- {
- if (waitForChannelRequestResult(c) == false)
- throw new IOException("The server denied the request.");
- }
- catch (IOException e)
- {
- throw (IOException) new IOException("The shell request failed.").initCause(e);
- }
- }
-
- public void msgChannelExtendedData(byte[] msg, int msglen) throws IOException
- {
- if (msglen <= 13)
- throw new IOException("SSH_MSG_CHANNEL_EXTENDED_DATA message has wrong size (" + msglen + ")");
-
- int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);
- int dataType = ((msg[5] & 0xff) << 24) | ((msg[6] & 0xff) << 16) | ((msg[7] & 0xff) << 8) | (msg[8] & 0xff);
- int len = ((msg[9] & 0xff) << 24) | ((msg[10] & 0xff) << 16) | ((msg[11] & 0xff) << 8) | (msg[12] & 0xff);
-
- Channel c = getChannel(id);
-
- if (c == null)
- throw new IOException("Unexpected SSH_MSG_CHANNEL_EXTENDED_DATA message for non-existent channel " + id);
-
- if (dataType != Packets.SSH_EXTENDED_DATA_STDERR)
- throw new IOException("SSH_MSG_CHANNEL_EXTENDED_DATA message has unknown type (" + dataType + ")");
-
- if (len != (msglen - 13))
- throw new IOException("SSH_MSG_CHANNEL_EXTENDED_DATA message has wrong len (calculated " + (msglen - 13)
- + ", got " + len + ")");
-
- if (log.isEnabled())
- log.log(80, "Got SSH_MSG_CHANNEL_EXTENDED_DATA (channel " + id + ", " + len + ")");
-
- synchronized (c)
- {
- if (c.state == Channel.STATE_CLOSED)
- return; // ignore
-
- if (c.state != Channel.STATE_OPEN)
- throw new IOException("Got SSH_MSG_CHANNEL_EXTENDED_DATA, but channel is not in correct state ("
- + c.state + ")");
-
- if (c.localWindow < len)
- throw new IOException("Remote sent too much data, does not fit into window.");
-
- c.localWindow -= len;
-
- System.arraycopy(msg, 13, c.stderrBuffer, c.stderrWritepos, len);
- c.stderrWritepos += len;
-
- c.notifyAll();
- }
- }
-
- /**
- * Wait until for a condition.
- *
- * @param c
- * Channel
- * @param timeout
- * in ms, 0 means no timeout.
- * @param condition_mask
- * minimum event mask
- * @return all current events
- *
- */
- public int waitForCondition(Channel c, long timeout, int condition_mask)
- {
- long end_time = 0;
- boolean end_time_set = false;
-
- synchronized (c)
- {
- while (true)
- {
- int current_cond = 0;
-
- int stdoutAvail = c.stdoutWritepos - c.stdoutReadpos;
- int stderrAvail = c.stderrWritepos - c.stderrReadpos;
-
- if (stdoutAvail > 0)
- current_cond = current_cond | ChannelCondition.STDOUT_DATA;
-
- if (stderrAvail > 0)
- current_cond = current_cond | ChannelCondition.STDERR_DATA;
-
- if (c.EOF)
- current_cond = current_cond | ChannelCondition.EOF;
-
- if (c.getExitStatus() != null)
- current_cond = current_cond | ChannelCondition.EXIT_STATUS;
-
- if (c.getExitSignal() != null)
- current_cond = current_cond | ChannelCondition.EXIT_SIGNAL;
-
- if (c.state == Channel.STATE_CLOSED)
- return current_cond | ChannelCondition.CLOSED | ChannelCondition.EOF;
-
- if ((current_cond & condition_mask) != 0)
- return current_cond;
-
- if (timeout > 0)
- {
- if (!end_time_set)
- {
- end_time = System.currentTimeMillis() + timeout;
- end_time_set = true;
- }
- else
- {
- timeout = end_time - System.currentTimeMillis();
-
- if (timeout <= 0)
- return current_cond | ChannelCondition.TIMEOUT;
- }
- }
-
- try
- {
- if (timeout > 0)
- c.wait(timeout);
- else
- c.wait();
- }
- catch (InterruptedException e)
- {
- }
- }
- }
- }
-
- public int getAvailable(Channel c, boolean extended) throws IOException
- {
- synchronized (c)
- {
- int avail;
-
- if (extended)
- avail = c.stderrWritepos - c.stderrReadpos;
- else
- avail = c.stdoutWritepos - c.stdoutReadpos;
-
- return ((avail > 0) ? avail : (c.EOF ? -1 : 0));
- }
- }
-
- public int getChannelData(Channel c, boolean extended, byte[] target, int off, int len) throws IOException
- {
- int copylen = 0;
- int increment = 0;
- int remoteID = 0;
- int localID = 0;
-
- synchronized (c)
- {
- int stdoutAvail = 0;
- int stderrAvail = 0;
-
- while (true)
- {
- /*
- * Data available? We have to return remaining data even if the
- * channel is already closed.
- */
-
- stdoutAvail = c.stdoutWritepos - c.stdoutReadpos;
- stderrAvail = c.stderrWritepos - c.stderrReadpos;
-
- if ((!extended) && (stdoutAvail != 0))
- break;
-
- if ((extended) && (stderrAvail != 0))
- break;
-
- /* Do not wait if more data will never arrive (EOF or CLOSED) */
-
- if ((c.EOF) || (c.state != Channel.STATE_OPEN))
- return -1;
-
- try
- {
- c.wait();
- }
- catch (InterruptedException ignore)
- {
- }
- }
-
- /* OK, there is some data. Return it. */
-
- if (!extended)
- {
- copylen = (stdoutAvail > len) ? len : stdoutAvail;
- System.arraycopy(c.stdoutBuffer, c.stdoutReadpos, target, off, copylen);
- c.stdoutReadpos += copylen;
-
- if (c.stdoutReadpos != c.stdoutWritepos)
-
- System.arraycopy(c.stdoutBuffer, c.stdoutReadpos, c.stdoutBuffer, 0, c.stdoutWritepos
- - c.stdoutReadpos);
-
- c.stdoutWritepos -= c.stdoutReadpos;
- c.stdoutReadpos = 0;
- }
- else
- {
- copylen = (stderrAvail > len) ? len : stderrAvail;
- System.arraycopy(c.stderrBuffer, c.stderrReadpos, target, off, copylen);
- c.stderrReadpos += copylen;
-
- if (c.stderrReadpos != c.stderrWritepos)
-
- System.arraycopy(c.stderrBuffer, c.stderrReadpos, c.stderrBuffer, 0, c.stderrWritepos
- - c.stderrReadpos);
-
- c.stderrWritepos -= c.stderrReadpos;
- c.stderrReadpos = 0;
- }
-
- if (c.state != Channel.STATE_OPEN)
- return copylen;
-
- if (c.localWindow < ((Channel.CHANNEL_BUFFER_SIZE + 1) / 2))
- {
- int minFreeSpace = Math.min(Channel.CHANNEL_BUFFER_SIZE - c.stdoutWritepos, Channel.CHANNEL_BUFFER_SIZE
- - c.stderrWritepos);
-
- increment = minFreeSpace - c.localWindow;
- c.localWindow = minFreeSpace;
- }
-
- remoteID = c.remoteID; /* read while holding the lock */
- localID = c.localID; /* read while holding the lock */
- }
-
- /*
- * If a consumer reads stdout and stdin in parallel, we may end up with
- * sending two msgWindowAdjust messages. Luckily, it
- * does not matter in which order they arrive at the server.
- */
-
- if (increment > 0)
- {
- if (log.isEnabled())
- log.log(80, "Sending SSH_MSG_CHANNEL_WINDOW_ADJUST (channel " + localID + ", " + increment + ")");
-
- synchronized (c.channelSendLock)
- {
- byte[] msg = c.msgWindowAdjust;
-
- msg[0] = Packets.SSH_MSG_CHANNEL_WINDOW_ADJUST;
- msg[1] = (byte) (remoteID >> 24);
- msg[2] = (byte) (remoteID >> 16);
- msg[3] = (byte) (remoteID >> 8);
- msg[4] = (byte) (remoteID);
- msg[5] = (byte) (increment >> 24);
- msg[6] = (byte) (increment >> 16);
- msg[7] = (byte) (increment >> 8);
- msg[8] = (byte) (increment);
-
- if (c.closeMessageSent == false)
- tm.sendMessage(msg);
- }
- }
-
- return copylen;
- }
-
- public void msgChannelData(byte[] msg, int msglen) throws IOException
- {
- if (msglen <= 9)
- throw new IOException("SSH_MSG_CHANNEL_DATA message has wrong size (" + msglen + ")");
-
- int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);
- int len = ((msg[5] & 0xff) << 24) | ((msg[6] & 0xff) << 16) | ((msg[7] & 0xff) << 8) | (msg[8] & 0xff);
-
- Channel c = getChannel(id);
-
- if (c == null)
- throw new IOException("Unexpected SSH_MSG_CHANNEL_DATA message for non-existent channel " + id);
-
- if (len != (msglen - 9))
- throw new IOException("SSH_MSG_CHANNEL_DATA message has wrong len (calculated " + (msglen - 9) + ", got "
- + len + ")");
-
- if (log.isEnabled())
- log.log(80, "Got SSH_MSG_CHANNEL_DATA (channel " + id + ", " + len + ")");
-
- synchronized (c)
- {
- if (c.state == Channel.STATE_CLOSED)
- return; // ignore
-
- if (c.state != Channel.STATE_OPEN)
- throw new IOException("Got SSH_MSG_CHANNEL_DATA, but channel is not in correct state (" + c.state + ")");
-
- if (c.localWindow < len)
- throw new IOException("Remote sent too much data, does not fit into window.");
-
- c.localWindow -= len;
-
- System.arraycopy(msg, 9, c.stdoutBuffer, c.stdoutWritepos, len);
- c.stdoutWritepos += len;
-
- c.notifyAll();
- }
- }
-
- public void msgChannelWindowAdjust(byte[] msg, int msglen) throws IOException
- {
- if (msglen != 9)
- throw new IOException("SSH_MSG_CHANNEL_WINDOW_ADJUST message has wrong size (" + msglen + ")");
-
- int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);
- int windowChange = ((msg[5] & 0xff) << 24) | ((msg[6] & 0xff) << 16) | ((msg[7] & 0xff) << 8) | (msg[8] & 0xff);
-
- Channel c = getChannel(id);
-
- if (c == null)
- throw new IOException("Unexpected SSH_MSG_CHANNEL_WINDOW_ADJUST message for non-existent channel " + id);
-
- synchronized (c)
- {
- final long huge = 0xFFFFffffL; /* 2^32 - 1 */
-
- c.remoteWindow += (windowChange & huge); /* avoid sign extension */
-
- /* TODO - is this a good heuristic? */
-
- if ((c.remoteWindow > huge))
- c.remoteWindow = huge;
-
- c.notifyAll();
- }
-
- if (log.isEnabled())
- log.log(80, "Got SSH_MSG_CHANNEL_WINDOW_ADJUST (channel " + id + ", " + windowChange + ")");
- }
-
- public void msgChannelOpen(byte[] msg, int msglen) throws IOException
- {
- TypesReader tr = new TypesReader(msg, 0, msglen);
-
- tr.readByte(); // skip packet type
- String channelType = tr.readString();
- int remoteID = tr.readUINT32(); /* sender channel */
- int remoteWindow = tr.readUINT32(); /* initial window size */
- int remoteMaxPacketSize = tr.readUINT32(); /* maximum packet size */
-
- if ("x11".equals(channelType))
- {
- synchronized (x11_magic_cookies)
- {
- /* If we did not request X11 forwarding, then simply ignore this bogus request. */
-
- if (x11_magic_cookies.size() == 0)
- {
- PacketChannelOpenFailure pcof = new PacketChannelOpenFailure(remoteID,
- Packets.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED, "X11 forwarding not activated", "");
-
- tm.sendAsynchronousMessage(pcof.getPayload());
-
- if (log.isEnabled())
- log.log(20, "Unexpected X11 request, denying it!");
-
- return;
- }
- }
-
- String remoteOriginatorAddress = tr.readString();
- int remoteOriginatorPort = tr.readUINT32();
-
- Channel c = new Channel(this);
-
- synchronized (c)
- {
- c.remoteID = remoteID;
- c.remoteWindow = remoteWindow & 0xFFFFffffL; /* properly convert UINT32 to long */
- c.remoteMaxPacketSize = remoteMaxPacketSize;
- c.localID = addChannel(c);
- }
-
- /*
- * The open confirmation message will be sent from another thread
- */
-
- RemoteX11AcceptThread rxat = new RemoteX11AcceptThread(c, remoteOriginatorAddress, remoteOriginatorPort);
- rxat.setDaemon(true);
- rxat.start();
-
- return;
- }
-
- if ("forwarded-tcpip".equals(channelType))
- {
- String remoteConnectedAddress = tr.readString(); /* address that was connected */
- int remoteConnectedPort = tr.readUINT32(); /* port that was connected */
- String remoteOriginatorAddress = tr.readString(); /* originator IP address */
- int remoteOriginatorPort = tr.readUINT32(); /* originator port */
-
- RemoteForwardingData rfd = null;
-
- synchronized (remoteForwardings)
- {
- rfd = remoteForwardings.get(Integer.valueOf(remoteConnectedPort));
- }
-
- if (rfd == null)
- {
- PacketChannelOpenFailure pcof = new PacketChannelOpenFailure(remoteID,
- Packets.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED,
- "No thanks, unknown port in forwarded-tcpip request", "");
-
- /* Always try to be polite. */
-
- tm.sendAsynchronousMessage(pcof.getPayload());
-
- if (log.isEnabled())
- log.log(20, "Unexpected forwarded-tcpip request, denying it!");
-
- return;
- }
-
- Channel c = new Channel(this);
-
- synchronized (c)
- {
- c.remoteID = remoteID;
- c.remoteWindow = remoteWindow & 0xFFFFffffL; /* convert UINT32 to long */
- c.remoteMaxPacketSize = remoteMaxPacketSize;
- c.localID = addChannel(c);
- }
-
- /*
- * The open confirmation message will be sent from another thread.
- */
-
- RemoteAcceptThread rat = new RemoteAcceptThread(c, remoteConnectedAddress, remoteConnectedPort,
- remoteOriginatorAddress, remoteOriginatorPort, rfd.targetAddress, rfd.targetPort);
-
- rat.setDaemon(true);
- rat.start();
-
- return;
- }
-
- if ("auth-agent@openssh.com".equals(channelType)) {
- Channel c = new Channel(this);
-
- synchronized (c)
- {
- c.remoteID = remoteID;
- c.remoteWindow = remoteWindow & 0xFFFFffffL; /* properly convert UINT32 to long */
- c.remoteMaxPacketSize = remoteMaxPacketSize;
- c.localID = addChannel(c);
- }
-
- AuthAgentForwardThread aat = new AuthAgentForwardThread(c, authAgent);
-
- aat.setDaemon(true);
- aat.start();
-
- return;
- }
-
- /* Tell the server that we have no idea what it is talking about */
-
- PacketChannelOpenFailure pcof = new PacketChannelOpenFailure(remoteID, Packets.SSH_OPEN_UNKNOWN_CHANNEL_TYPE,
- "Unknown channel type", "");
-
- tm.sendAsynchronousMessage(pcof.getPayload());
-
- if (log.isEnabled())
- log.log(20, "The peer tried to open an unsupported channel type (" + channelType + ")");
- }
-
- public void msgChannelRequest(byte[] msg, int msglen) throws IOException
- {
- TypesReader tr = new TypesReader(msg, 0, msglen);
-
- tr.readByte(); // skip packet type
- int id = tr.readUINT32();
-
- Channel c = getChannel(id);
-
- if (c == null)
- throw new IOException("Unexpected SSH_MSG_CHANNEL_REQUEST message for non-existent channel " + id);
-
- String type = tr.readString("US-ASCII");
- boolean wantReply = tr.readBoolean();
-
- if (log.isEnabled())
- log.log(80, "Got SSH_MSG_CHANNEL_REQUEST (channel " + id + ", '" + type + "')");
-
- if (type.equals("exit-status"))
- {
- if (wantReply != false)
- throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message, 'want reply' is true");
-
- int exit_status = tr.readUINT32();
-
- if (tr.remain() != 0)
- throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message");
-
- synchronized (c)
- {
- c.exit_status = Integer.valueOf(exit_status);
- c.notifyAll();
- }
-
- if (log.isEnabled())
- log.log(50, "Got EXIT STATUS (channel " + id + ", status " + exit_status + ")");
-
- return;
- }
-
- if (type.equals("exit-signal"))
- {
- if (wantReply != false)
- throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message, 'want reply' is true");
-
- String signame = tr.readString("US-ASCII");
- tr.readBoolean();
- tr.readString();
- tr.readString();
-
- if (tr.remain() != 0)
- throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message");
-
- synchronized (c)
- {
- c.exit_signal = signame;
- c.notifyAll();
- }
-
- if (log.isEnabled())
- log.log(50, "Got EXIT SIGNAL (channel " + id + ", signal " + signame + ")");
-
- return;
- }
-
- /* We simply ignore unknown channel requests, however, if the server wants a reply,
- * then we signal that we have no idea what it is about.
- */
-
- if (wantReply)
- {
- byte[] reply = new byte[5];
-
- reply[0] = Packets.SSH_MSG_CHANNEL_FAILURE;
- reply[1] = (byte) (c.remoteID >> 24);
- reply[2] = (byte) (c.remoteID >> 16);
- reply[3] = (byte) (c.remoteID >> 8);
- reply[4] = (byte) (c.remoteID);
-
- tm.sendAsynchronousMessage(reply);
- }
-
- if (log.isEnabled())
- log.log(50, "Channel request '" + type + "' is not known, ignoring it");
- }
-
- public void msgChannelEOF(byte[] msg, int msglen) throws IOException
- {
- if (msglen != 5)
- throw new IOException("SSH_MSG_CHANNEL_EOF message has wrong size (" + msglen + ")");
-
- int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);
-
- Channel c = getChannel(id);
-
- if (c == null)
- throw new IOException("Unexpected SSH_MSG_CHANNEL_EOF message for non-existent channel " + id);
-
- synchronized (c)
- {
- c.EOF = true;
- c.notifyAll();
- }
-
- if (log.isEnabled())
- log.log(50, "Got SSH_MSG_CHANNEL_EOF (channel " + id + ")");
- }
-
- public void msgChannelClose(byte[] msg, int msglen) throws IOException
- {
- if (msglen != 5)
- throw new IOException("SSH_MSG_CHANNEL_CLOSE message has wrong size (" + msglen + ")");
-
- int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);
-
- Channel c = getChannel(id);
-
- if (c == null)
- throw new IOException("Unexpected SSH_MSG_CHANNEL_CLOSE message for non-existent channel " + id);
-
- synchronized (c)
- {
- c.EOF = true;
- c.state = Channel.STATE_CLOSED;
- c.setReasonClosed("Close requested by remote");
- c.closeMessageRecv = true;
-
- removeChannel(c.localID);
-
- c.notifyAll();
- }
-
- if (log.isEnabled())
- log.log(50, "Got SSH_MSG_CHANNEL_CLOSE (channel " + id + ")");
- }
-
- public void msgChannelSuccess(byte[] msg, int msglen) throws IOException
- {
- if (msglen != 5)
- throw new IOException("SSH_MSG_CHANNEL_SUCCESS message has wrong size (" + msglen + ")");
-
- int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);
-
- Channel c = getChannel(id);
-
- if (c == null)
- throw new IOException("Unexpected SSH_MSG_CHANNEL_SUCCESS message for non-existent channel " + id);
-
- synchronized (c)
- {
- c.successCounter++;
- c.notifyAll();
- }
-
- if (log.isEnabled())
- log.log(80, "Got SSH_MSG_CHANNEL_SUCCESS (channel " + id + ")");
- }
-
- public void msgChannelFailure(byte[] msg, int msglen) throws IOException
- {
- if (msglen != 5)
- throw new IOException("SSH_MSG_CHANNEL_FAILURE message has wrong size (" + msglen + ")");
-
- int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff);
-
- Channel c = getChannel(id);
-
- if (c == null)
- throw new IOException("Unexpected SSH_MSG_CHANNEL_FAILURE message for non-existent channel " + id);
-
- synchronized (c)
- {
- c.failedCounter++;
- c.notifyAll();
- }
-
- if (log.isEnabled())
- log.log(50, "Got SSH_MSG_CHANNEL_FAILURE (channel " + id + ")");
- }
-
- public void msgChannelOpenConfirmation(byte[] msg, int msglen) throws IOException
- {
- PacketChannelOpenConfirmation sm = new PacketChannelOpenConfirmation(msg, 0, msglen);
-
- Channel c = getChannel(sm.recipientChannelID);
-
- if (c == null)
- throw new IOException("Unexpected SSH_MSG_CHANNEL_OPEN_CONFIRMATION message for non-existent channel "
- + sm.recipientChannelID);
-
- synchronized (c)
- {
- if (c.state != Channel.STATE_OPENING)
- throw new IOException("Unexpected SSH_MSG_CHANNEL_OPEN_CONFIRMATION message for channel "
- + sm.recipientChannelID);
-
- c.remoteID = sm.senderChannelID;
- c.remoteWindow = sm.initialWindowSize & 0xFFFFffffL; /* convert UINT32 to long */
- c.remoteMaxPacketSize = sm.maxPacketSize;
- c.state = Channel.STATE_OPEN;
- c.notifyAll();
- }
-
- if (log.isEnabled())
- log.log(50, "Got SSH_MSG_CHANNEL_OPEN_CONFIRMATION (channel " + sm.recipientChannelID + " / remote: "
- + sm.senderChannelID + ")");
- }
-
- public void msgChannelOpenFailure(byte[] msg, int msglen) throws IOException
- {
- if (msglen < 5)
- throw new IOException("SSH_MSG_CHANNEL_OPEN_FAILURE message has wrong size (" + msglen + ")");
-
- TypesReader tr = new TypesReader(msg, 0, msglen);
-
- tr.readByte(); // skip packet type
- int id = tr.readUINT32(); /* sender channel */
-
- Channel c = getChannel(id);
-
- if (c == null)
- throw new IOException("Unexpected SSH_MSG_CHANNEL_OPEN_FAILURE message for non-existent channel " + id);
-
- int reasonCode = tr.readUINT32();
- String description = tr.readString("UTF-8");
-
- String reasonCodeSymbolicName = null;
-
- switch (reasonCode)
- {
- case 1:
- reasonCodeSymbolicName = "SSH_OPEN_ADMINISTRATIVELY_PROHIBITED";
- break;
- case 2:
- reasonCodeSymbolicName = "SSH_OPEN_CONNECT_FAILED";
- break;
- case 3:
- reasonCodeSymbolicName = "SSH_OPEN_UNKNOWN_CHANNEL_TYPE";
- break;
- case 4:
- reasonCodeSymbolicName = "SSH_OPEN_RESOURCE_SHORTAGE";
- break;
- default:
- reasonCodeSymbolicName = "UNKNOWN REASON CODE (" + reasonCode + ")";
- }
-
- StringBuffer descriptionBuffer = new StringBuffer();
- descriptionBuffer.append(description);
-
- for (int i = 0; i < descriptionBuffer.length(); i++)
- {
- char cc = descriptionBuffer.charAt(i);
-
- if ((cc >= 32) && (cc <= 126))
- continue;
- descriptionBuffer.setCharAt(i, '\uFFFD');
- }
-
- synchronized (c)
- {
- c.EOF = true;
- c.state = Channel.STATE_CLOSED;
- c.setReasonClosed("The server refused to open the channel (" + reasonCodeSymbolicName + ", '"
- + descriptionBuffer.toString() + "')");
- c.notifyAll();
- }
-
- if (log.isEnabled())
- log.log(50, "Got SSH_MSG_CHANNEL_OPEN_FAILURE (channel " + id + ")");
- }
-
- public void msgGlobalRequest(byte[] msg, int msglen) throws IOException
- {
- /* Currently we do not support any kind of global request */
-
- TypesReader tr = new TypesReader(msg, 0, msglen);
-
- tr.readByte(); // skip packet type
- String requestName = tr.readString();
- boolean wantReply = tr.readBoolean();
-
- if (wantReply)
- {
- byte[] reply_failure = new byte[1];
- reply_failure[0] = Packets.SSH_MSG_REQUEST_FAILURE;
-
- tm.sendAsynchronousMessage(reply_failure);
- }
-
- /* We do not clean up the requestName String - that is OK for debug */
-
- if (log.isEnabled())
- log.log(80, "Got SSH_MSG_GLOBAL_REQUEST (" + requestName + ")");
- }
-
- public void msgGlobalSuccess() throws IOException
- {
- synchronized (channels)
- {
- globalSuccessCounter++;
- channels.notifyAll();
- }
-
- if (log.isEnabled())
- log.log(80, "Got SSH_MSG_REQUEST_SUCCESS");
- }
-
- public void msgGlobalFailure() throws IOException
- {
- synchronized (channels)
- {
- globalFailedCounter++;
- channels.notifyAll();
- }
-
- if (log.isEnabled())
- log.log(80, "Got SSH_MSG_REQUEST_FAILURE");
- }
-
- public void handleMessage(byte[] msg, int msglen) throws IOException
- {
- if (msg == null)
- {
- if (log.isEnabled())
- log.log(50, "HandleMessage: got shutdown");
-
- synchronized (listenerThreads)
- {
- for (int i = 0; i < listenerThreads.size(); i++)
- {
- IChannelWorkerThread lat = listenerThreads.elementAt(i);
- lat.stopWorking();
- }
- listenerThreadsAllowed = false;
- }
-
- synchronized (channels)
- {
- shutdown = true;
-
- for (int i = 0; i < channels.size(); i++)
- {
- Channel c = channels.elementAt(i);
- synchronized (c)
- {
- c.EOF = true;
- c.state = Channel.STATE_CLOSED;
- c.setReasonClosed("The connection is being shutdown");
- c.closeMessageRecv = true; /*
- * You never know, perhaps
- * we are waiting for a
- * pending close message
- * from the server...
- */
- c.notifyAll();
- }
- }
- /* Works with J2ME */
- channels.setSize(0);
- channels.trimToSize();
- channels.notifyAll(); /* Notify global response waiters */
- return;
- }
- }
-
- switch (msg[0])
- {
- case Packets.SSH_MSG_CHANNEL_OPEN_CONFIRMATION:
- msgChannelOpenConfirmation(msg, msglen);
- break;
- case Packets.SSH_MSG_CHANNEL_WINDOW_ADJUST:
- msgChannelWindowAdjust(msg, msglen);
- break;
- case Packets.SSH_MSG_CHANNEL_DATA:
- msgChannelData(msg, msglen);
- break;
- case Packets.SSH_MSG_CHANNEL_EXTENDED_DATA:
- msgChannelExtendedData(msg, msglen);
- break;
- case Packets.SSH_MSG_CHANNEL_REQUEST:
- msgChannelRequest(msg, msglen);
- break;
- case Packets.SSH_MSG_CHANNEL_EOF:
- msgChannelEOF(msg, msglen);
- break;
- case Packets.SSH_MSG_CHANNEL_OPEN:
- msgChannelOpen(msg, msglen);
- break;
- case Packets.SSH_MSG_CHANNEL_CLOSE:
- msgChannelClose(msg, msglen);
- break;
- case Packets.SSH_MSG_CHANNEL_SUCCESS:
- msgChannelSuccess(msg, msglen);
- break;
- case Packets.SSH_MSG_CHANNEL_FAILURE:
- msgChannelFailure(msg, msglen);
- break;
- case Packets.SSH_MSG_CHANNEL_OPEN_FAILURE:
- msgChannelOpenFailure(msg, msglen);
- break;
- case Packets.SSH_MSG_GLOBAL_REQUEST:
- msgGlobalRequest(msg, msglen);
- break;
- case Packets.SSH_MSG_REQUEST_SUCCESS:
- msgGlobalSuccess();
- break;
- case Packets.SSH_MSG_REQUEST_FAILURE:
- msgGlobalFailure();
- break;
- default:
- throw new IOException("Cannot handle unknown channel message " + (msg[0] & 0xff));
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/channel/ChannelOutputStream.java b/app/src/main/java/com/trilead/ssh2/channel/ChannelOutputStream.java
deleted file mode 100644
index c1d56e8..0000000
--- a/app/src/main/java/com/trilead/ssh2/channel/ChannelOutputStream.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.trilead.ssh2.channel;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * ChannelOutputStream.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: ChannelOutputStream.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public final class ChannelOutputStream extends OutputStream
-{
- Channel c;
-
- private byte[] writeBuffer;
-
- boolean isClosed = false;
-
- ChannelOutputStream(Channel c)
- {
- this.c = c;
- writeBuffer = new byte[1];
- }
-
- public void write(int b) throws IOException
- {
- writeBuffer[0] = (byte) b;
-
- write(writeBuffer, 0, 1);
- }
-
- public void close() throws IOException
- {
- if (isClosed == false)
- {
- isClosed = true;
- c.cm.sendEOF(c);
- }
- }
-
- public void flush() throws IOException
- {
- if (isClosed)
- throw new IOException("This OutputStream is closed.");
-
- /* This is a no-op, since this stream is unbuffered */
- }
-
- public void write(byte[] b, int off, int len) throws IOException
- {
- if (isClosed)
- throw new IOException("This OutputStream is closed.");
-
- if (b == null)
- throw new NullPointerException();
-
- if ((off < 0) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0) || (off > b.length))
- throw new IndexOutOfBoundsException();
-
- if (len == 0)
- return;
-
- c.cm.sendData(c, b, off, len);
- }
-
- public void write(byte[] b) throws IOException
- {
- write(b, 0, b.length);
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/channel/DynamicAcceptThread.java b/app/src/main/java/com/trilead/ssh2/channel/DynamicAcceptThread.java
deleted file mode 100644
index ef3a3d0..0000000
--- a/app/src/main/java/com/trilead/ssh2/channel/DynamicAcceptThread.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * ConnectBot: simple, powerful, open-source SSH client for Android
- * Copyright 2007 Kenny Root, Jeffrey Sharkey
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.trilead.ssh2.channel;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InterruptedIOException;
-import java.io.OutputStream;
-import java.io.PushbackInputStream;
-import java.net.ConnectException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.NoRouteToHostException;
-import java.net.ServerSocket;
-import java.net.Socket;
-
-import net.sourceforge.jsocks.Proxy;
-import net.sourceforge.jsocks.ProxyMessage;
-import net.sourceforge.jsocks.Socks4Message;
-import net.sourceforge.jsocks.Socks5Message;
-import net.sourceforge.jsocks.SocksException;
-import net.sourceforge.jsocks.server.ServerAuthenticator;
-import net.sourceforge.jsocks.server.ServerAuthenticatorNone;
-
-/**
- * DynamicAcceptThread.
- *
- * @author Kenny Root
- * @version $Id$
- */
-public class DynamicAcceptThread extends Thread implements IChannelWorkerThread {
- private ChannelManager cm;
- private ServerSocket ss;
-
- class DynamicAcceptRunnable implements Runnable {
- private static final int idleTimeout = 180000; //3 minutes
-
- private ServerAuthenticator auth;
- private Socket sock;
- private InputStream in;
- private OutputStream out;
- private ProxyMessage msg;
-
- public DynamicAcceptRunnable(ServerAuthenticator auth, Socket sock) {
- this.auth = auth;
- this.sock = sock;
-
- setName("DynamicAcceptRunnable");
- }
-
- public void run() {
- try {
- startSession();
- } catch (IOException ioe) {
- int error_code = Proxy.SOCKS_FAILURE;
-
- if (ioe instanceof SocksException)
- error_code = ((SocksException) ioe).errCode;
- else if (ioe instanceof NoRouteToHostException)
- error_code = Proxy.SOCKS_HOST_UNREACHABLE;
- else if (ioe instanceof ConnectException)
- error_code = Proxy.SOCKS_CONNECTION_REFUSED;
- else if (ioe instanceof InterruptedIOException)
- error_code = Proxy.SOCKS_TTL_EXPIRE;
-
- if (error_code > Proxy.SOCKS_ADDR_NOT_SUPPORTED
- || error_code < 0) {
- error_code = Proxy.SOCKS_FAILURE;
- }
-
- sendErrorMessage(error_code);
- } finally {
- if (auth != null)
- auth.endSession();
- }
- }
-
- private ProxyMessage readMsg(InputStream in) throws IOException {
- PushbackInputStream push_in;
- if (in instanceof PushbackInputStream)
- push_in = (PushbackInputStream) in;
- else
- push_in = new PushbackInputStream(in);
-
- int version = push_in.read();
- push_in.unread(version);
-
- ProxyMessage msg;
-
- if (version == 5) {
- msg = new Socks5Message(push_in, false);
- } else if (version == 4) {
- msg = new Socks4Message(push_in, false);
- } else {
- throw new SocksException(Proxy.SOCKS_FAILURE);
- }
- return msg;
- }
-
- private void sendErrorMessage(int error_code) {
- ProxyMessage err_msg;
- if (msg instanceof Socks4Message)
- err_msg = new Socks4Message(Socks4Message.REPLY_REJECTED);
- else
- err_msg = new Socks5Message(error_code);
- try {
- err_msg.write(out);
- } catch (IOException ioe) {
- }
- }
-
- private void handleRequest(ProxyMessage msg) throws IOException {
- if (!auth.checkRequest(msg))
- throw new SocksException(Proxy.SOCKS_FAILURE);
-
- switch (msg.command) {
- case Proxy.SOCKS_CMD_CONNECT:
- onConnect(msg);
- break;
- default:
- throw new SocksException(Proxy.SOCKS_CMD_NOT_SUPPORTED);
- }
- }
-
- private void startSession() throws IOException {
- sock.setSoTimeout(idleTimeout);
-
- try {
- auth = auth.startSession(sock);
- } catch (IOException ioe) {
- System.out.println("Could not start SOCKS session");
- ioe.printStackTrace();
- auth = null;
- return;
- }
-
- if (auth == null) { // Authentication failed
- System.out.println("SOCKS auth failed");
- return;
- }
-
- in = auth.getInputStream();
- out = auth.getOutputStream();
-
- msg = readMsg(in);
- handleRequest(msg);
- }
-
- private void onConnect(ProxyMessage msg) throws IOException {
- ProxyMessage response = null;
- Channel cn = null;
- StreamForwarder r2l = null;
- StreamForwarder l2r = null;
-
- if (msg instanceof Socks5Message) {
- response = new Socks5Message(Proxy.SOCKS_SUCCESS, (InetAddress)null, 0);
- } else {
- response = new Socks4Message(Socks4Message.REPLY_OK, (InetAddress)null, 0);
- }
- response.write(out);
-
- String destHost = msg.host;
- if (msg.ip != null)
- destHost = msg.ip.getHostAddress();
-
- try {
- /*
- * This may fail, e.g., if the remote port is closed (in
- * optimistic terms: not open yet)
- */
-
- cn = cm.openDirectTCPIPChannel(destHost, msg.port,
- "127.0.0.1", 0);
-
- } catch (IOException e) {
- /*
- * Simply close the local socket and wait for the next incoming
- * connection
- */
-
- try {
- sock.close();
- } catch (IOException ignore) {
- }
-
- return;
- }
-
- try {
- r2l = new StreamForwarder(cn, null, sock, cn.stdoutStream, out, "RemoteToLocal");
- l2r = new StreamForwarder(cn, r2l, sock, in, cn.stdinStream, "LocalToRemote");
- } catch (IOException e) {
- try {
- /*
- * This message is only visible during debugging, since we
- * discard the channel immediatelly
- */
- cn.cm.closeChannel(cn,
- "Weird error during creation of StreamForwarder ("
- + e.getMessage() + ")", true);
- } catch (IOException ignore) {
- }
-
- return;
- }
-
- r2l.setDaemon(true);
- l2r.setDaemon(true);
- r2l.start();
- l2r.start();
- }
- }
-
- public DynamicAcceptThread(ChannelManager cm, int local_port)
- throws IOException {
- this.cm = cm;
-
- setName("DynamicAcceptThread");
-
- ss = new ServerSocket(local_port);
- }
-
- public DynamicAcceptThread(ChannelManager cm, InetSocketAddress localAddress)
- throws IOException {
- this.cm = cm;
-
- ss = new ServerSocket();
- ss.bind(localAddress);
- }
-
- @Override
- public void run() {
- try {
- cm.registerThread(this);
- } catch (IOException e) {
- stopWorking();
- return;
- }
-
- while (true) {
- Socket sock = null;
-
- try {
- sock = ss.accept();
- } catch (IOException e) {
- stopWorking();
- return;
- }
-
- DynamicAcceptRunnable dar = new DynamicAcceptRunnable(new ServerAuthenticatorNone(), sock);
- Thread t = new Thread(dar);
- t.setDaemon(true);
- t.start();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.trilead.ssh2.channel.IChannelWorkerThread#stopWorking()
- */
- public void stopWorking() {
- try {
- /* This will lead to an IOException in the ss.accept() call */
- ss.close();
- } catch (IOException e) {
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/channel/IChannelWorkerThread.java b/app/src/main/java/com/trilead/ssh2/channel/IChannelWorkerThread.java
deleted file mode 100644
index bce9b1b..0000000
--- a/app/src/main/java/com/trilead/ssh2/channel/IChannelWorkerThread.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-package com.trilead.ssh2.channel;
-
-/**
- * IChannelWorkerThread.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: IChannelWorkerThread.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-interface IChannelWorkerThread
-{
- public void stopWorking();
-}
diff --git a/app/src/main/java/com/trilead/ssh2/channel/LocalAcceptThread.java b/app/src/main/java/com/trilead/ssh2/channel/LocalAcceptThread.java
deleted file mode 100644
index 0d1bb35..0000000
--- a/app/src/main/java/com/trilead/ssh2/channel/LocalAcceptThread.java
+++ /dev/null
@@ -1,135 +0,0 @@
-
-package com.trilead.ssh2.channel;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-
-/**
- * LocalAcceptThread.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: LocalAcceptThread.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public class LocalAcceptThread extends Thread implements IChannelWorkerThread
-{
- ChannelManager cm;
- String host_to_connect;
- int port_to_connect;
-
- final ServerSocket ss;
-
- public LocalAcceptThread(ChannelManager cm, int local_port, String host_to_connect, int port_to_connect)
- throws IOException
- {
- this.cm = cm;
- this.host_to_connect = host_to_connect;
- this.port_to_connect = port_to_connect;
-
- ss = new ServerSocket(local_port);
- }
-
- public LocalAcceptThread(ChannelManager cm, InetSocketAddress localAddress, String host_to_connect,
- int port_to_connect) throws IOException
- {
- this.cm = cm;
- this.host_to_connect = host_to_connect;
- this.port_to_connect = port_to_connect;
-
- ss = new ServerSocket();
- ss.bind(localAddress);
- }
-
- public void run()
- {
- try
- {
- cm.registerThread(this);
- }
- catch (IOException e)
- {
- stopWorking();
- return;
- }
-
- while (true)
- {
- Socket s = null;
-
- try
- {
- s = ss.accept();
- }
- catch (IOException e)
- {
- stopWorking();
- return;
- }
-
- Channel cn = null;
- StreamForwarder r2l = null;
- StreamForwarder l2r = null;
-
- try
- {
- /* This may fail, e.g., if the remote port is closed (in optimistic terms: not open yet) */
-
- cn = cm.openDirectTCPIPChannel(host_to_connect, port_to_connect, s.getInetAddress().getHostAddress(), s
- .getPort());
-
- }
- catch (IOException e)
- {
- /* Simply close the local socket and wait for the next incoming connection */
-
- try
- {
- s.close();
- }
- catch (IOException ignore)
- {
- }
-
- continue;
- }
-
- try
- {
- r2l = new StreamForwarder(cn, null, s, cn.stdoutStream, s.getOutputStream(), "RemoteToLocal");
- l2r = new StreamForwarder(cn, r2l, s, s.getInputStream(), cn.stdinStream, "LocalToRemote");
- }
- catch (IOException e)
- {
- try
- {
- /* This message is only visible during debugging, since we discard the channel immediatelly */
- cn.cm.closeChannel(cn, "Weird error during creation of StreamForwarder (" + e.getMessage() + ")",
- true);
- }
- catch (IOException ignore)
- {
- }
-
- continue;
- }
-
- r2l.setDaemon(true);
- l2r.setDaemon(true);
- r2l.start();
- l2r.start();
- }
- }
-
- public void stopWorking()
- {
- try
- {
- /* This will lead to an IOException in the ss.accept() call */
- ss.close();
- }
- catch (IOException e)
- {
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/channel/RemoteAcceptThread.java b/app/src/main/java/com/trilead/ssh2/channel/RemoteAcceptThread.java
deleted file mode 100644
index 29b02b8..0000000
--- a/app/src/main/java/com/trilead/ssh2/channel/RemoteAcceptThread.java
+++ /dev/null
@@ -1,103 +0,0 @@
-
-package com.trilead.ssh2.channel;
-
-import java.io.IOException;
-import java.net.Socket;
-
-import com.trilead.ssh2.log.Logger;
-
-
-/**
- * RemoteAcceptThread.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: RemoteAcceptThread.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public class RemoteAcceptThread extends Thread
-{
- private static final Logger log = Logger.getLogger(RemoteAcceptThread.class);
-
- Channel c;
-
- String remoteConnectedAddress;
- int remoteConnectedPort;
- String remoteOriginatorAddress;
- int remoteOriginatorPort;
- String targetAddress;
- int targetPort;
-
- Socket s;
-
- public RemoteAcceptThread(Channel c, String remoteConnectedAddress, int remoteConnectedPort,
- String remoteOriginatorAddress, int remoteOriginatorPort, String targetAddress, int targetPort)
- {
- this.c = c;
- this.remoteConnectedAddress = remoteConnectedAddress;
- this.remoteConnectedPort = remoteConnectedPort;
- this.remoteOriginatorAddress = remoteOriginatorAddress;
- this.remoteOriginatorPort = remoteOriginatorPort;
- this.targetAddress = targetAddress;
- this.targetPort = targetPort;
-
- if (log.isEnabled())
- log.log(20, "RemoteAcceptThread: " + remoteConnectedAddress + "/" + remoteConnectedPort + ", R: "
- + remoteOriginatorAddress + "/" + remoteOriginatorPort);
- }
-
- public void run()
- {
- try
- {
- c.cm.sendOpenConfirmation(c);
-
- s = new Socket(targetAddress, targetPort);
-
- StreamForwarder r2l = new StreamForwarder(c, null, s, c.getStdoutStream(), s.getOutputStream(),
- "RemoteToLocal");
- StreamForwarder l2r = new StreamForwarder(c, null, null, s.getInputStream(), c.getStdinStream(),
- "LocalToRemote");
-
- /* No need to start two threads, one can be executed in the current thread */
-
- r2l.setDaemon(true);
- r2l.start();
- l2r.run();
-
- while (r2l.isAlive())
- {
- try
- {
- r2l.join();
- }
- catch (InterruptedException e)
- {
- }
- }
-
- /* If the channel is already closed, then this is a no-op */
-
- c.cm.closeChannel(c, "EOF on both streams reached.", true);
- s.close();
- }
- catch (IOException e)
- {
- log.log(50, "IOException in proxy code: " + e.getMessage());
-
- try
- {
- c.cm.closeChannel(c, "IOException in proxy code (" + e.getMessage() + ")", true);
- }
- catch (IOException e1)
- {
- }
- try
- {
- if (s != null)
- s.close();
- }
- catch (IOException e1)
- {
- }
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/channel/RemoteForwardingData.java b/app/src/main/java/com/trilead/ssh2/channel/RemoteForwardingData.java
deleted file mode 100644
index d05378e..0000000
--- a/app/src/main/java/com/trilead/ssh2/channel/RemoteForwardingData.java
+++ /dev/null
@@ -1,17 +0,0 @@
-
-package com.trilead.ssh2.channel;
-
-/**
- * RemoteForwardingData. Data about a requested remote forwarding.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: RemoteForwardingData.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public class RemoteForwardingData
-{
- public String bindAddress;
- public int bindPort;
-
- String targetAddress;
- int targetPort;
-}
diff --git a/app/src/main/java/com/trilead/ssh2/channel/RemoteX11AcceptThread.java b/app/src/main/java/com/trilead/ssh2/channel/RemoteX11AcceptThread.java
deleted file mode 100644
index 9f99410..0000000
--- a/app/src/main/java/com/trilead/ssh2/channel/RemoteX11AcceptThread.java
+++ /dev/null
@@ -1,240 +0,0 @@
-
-package com.trilead.ssh2.channel;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-
-import com.trilead.ssh2.log.Logger;
-
-
-/**
- * RemoteX11AcceptThread.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: RemoteX11AcceptThread.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
- */
-public class RemoteX11AcceptThread extends Thread
-{
- private static final Logger log = Logger.getLogger(RemoteX11AcceptThread.class);
-
- Channel c;
-
- String remoteOriginatorAddress;
- int remoteOriginatorPort;
-
- Socket s;
-
- public RemoteX11AcceptThread(Channel c, String remoteOriginatorAddress, int remoteOriginatorPort)
- {
- this.c = c;
- this.remoteOriginatorAddress = remoteOriginatorAddress;
- this.remoteOriginatorPort = remoteOriginatorPort;
- }
-
- public void run()
- {
- try
- {
- /* Send Open Confirmation */
-
- c.cm.sendOpenConfirmation(c);
-
- /* Read startup packet from client */
-
- OutputStream remote_os = c.getStdinStream();
- InputStream remote_is = c.getStdoutStream();
-
- /* The following code is based on the protocol description given in:
- * Scheifler/Gettys,
- * X Windows System: Core and Extension Protocols:
- * X Version 11, Releases 6 and 6.1 ISBN 1-55558-148-X
- */
-
- /*
- * Client startup:
- *
- * 1 0X42 MSB first/0x6c lSB first - byteorder
- * 1 - unused
- * 2 card16 - protocol-major-version
- * 2 card16 - protocol-minor-version
- * 2 n - lenght of authorization-protocol-name
- * 2 d - lenght of authorization-protocol-data
- * 2 - unused
- * string8 - authorization-protocol-name
- * p - unused, p=pad(n)
- * string8 - authorization-protocol-data
- * q - unused, q=pad(d)
- *
- * pad(X) = (4 - (X mod 4)) mod 4
- *
- * Server response:
- *
- * 1 (0 failed, 2 authenticate, 1 success)
- * ...
- *
- */
-
- /* Later on we will simply forward the first 6 header bytes to the "real" X11 server */
-
- byte[] header = new byte[6];
-
- if (remote_is.read(header) != 6)
- throw new IOException("Unexpected EOF on X11 startup!");
-
- if ((header[0] != 0x42) && (header[0] != 0x6c)) // 0x42 MSB first, 0x6C LSB first
- throw new IOException("Unknown endian format in X11 message!");
-
- /* Yes, I came up with this myself - shall I file an application for a patent? =) */
-
- int idxMSB = (header[0] == 0x42) ? 0 : 1;
-
- /* Read authorization data header */
-
- byte[] auth_buff = new byte[6];
-
- if (remote_is.read(auth_buff) != 6)
- throw new IOException("Unexpected EOF on X11 startup!");
-
- int authProtocolNameLength = ((auth_buff[idxMSB] & 0xff) << 8) | (auth_buff[1 - idxMSB] & 0xff);
- int authProtocolDataLength = ((auth_buff[2 + idxMSB] & 0xff) << 8) | (auth_buff[3 - idxMSB] & 0xff);
-
- if ((authProtocolNameLength > 256) || (authProtocolDataLength > 256))
- throw new IOException("Buggy X11 authorization data");
-
- int authProtocolNamePadding = ((4 - (authProtocolNameLength % 4)) % 4);
- int authProtocolDataPadding = ((4 - (authProtocolDataLength % 4)) % 4);
-
- byte[] authProtocolName = new byte[authProtocolNameLength];
- byte[] authProtocolData = new byte[authProtocolDataLength];
-
- byte[] paddingBuffer = new byte[4];
-
- if (remote_is.read(authProtocolName) != authProtocolNameLength)
- throw new IOException("Unexpected EOF on X11 startup! (authProtocolName)");
-
- if (remote_is.read(paddingBuffer, 0, authProtocolNamePadding) != authProtocolNamePadding)
- throw new IOException("Unexpected EOF on X11 startup! (authProtocolNamePadding)");
-
- if (remote_is.read(authProtocolData) != authProtocolDataLength)
- throw new IOException("Unexpected EOF on X11 startup! (authProtocolData)");
-
- if (remote_is.read(paddingBuffer, 0, authProtocolDataPadding) != authProtocolDataPadding)
- throw new IOException("Unexpected EOF on X11 startup! (authProtocolDataPadding)");
-
- if ("MIT-MAGIC-COOKIE-1".equals(new String(authProtocolName, "ISO-8859-1")) == false)
- throw new IOException("Unknown X11 authorization protocol!");
-
- if (authProtocolDataLength != 16)
- throw new IOException("Wrong data length for X11 authorization data!");
-
- StringBuffer tmp = new StringBuffer(32);
- for (int i = 0; i < authProtocolData.length; i++)
- {
- String digit2 = Integer.toHexString(authProtocolData[i] & 0xff);
- tmp.append((digit2.length() == 2) ? digit2 : "0" + digit2);
- }
- String hexEncodedFakeCookie = tmp.toString();
-
- /* Order is very important here - it may be that a certain x11 forwarding
- * gets disabled right in the moment when we check and register our connection
- * */
-
- synchronized (c)
- {
- /* Please read the comment in Channel.java */
- c.hexX11FakeCookie = hexEncodedFakeCookie;
- }
-
- /* Now check our fake cookie directory to see if we produced this cookie */
-
- X11ServerData sd = c.cm.checkX11Cookie(hexEncodedFakeCookie);
-
- if (sd == null)
- throw new IOException("Invalid X11 cookie received.");
-
- /* If the session which corresponds to this cookie is closed then we will
- * detect this: the session's close code will close all channels
- * with the session's assigned x11 fake cookie.
- */
-
- s = new Socket(sd.hostname, sd.port);
-
- OutputStream x11_os = s.getOutputStream();
- InputStream x11_is = s.getInputStream();
-
- /* Now we are sending the startup packet to the real X11 server */
-
- x11_os.write(header);
-
- if (sd.x11_magic_cookie == null)
- {
- byte[] emptyAuthData = new byte[6];
- /* empty auth data, hopefully you are connecting to localhost =) */
- x11_os.write(emptyAuthData);
- }
- else
- {
- if (sd.x11_magic_cookie.length != 16)
- throw new IOException("The real X11 cookie has an invalid length!");
-
- /* send X11 cookie specified by client */
- x11_os.write(auth_buff);
- x11_os.write(authProtocolName); /* re-use */
- x11_os.write(paddingBuffer, 0, authProtocolNamePadding);
- x11_os.write(sd.x11_magic_cookie);
- x11_os.write(paddingBuffer, 0, authProtocolDataPadding);
- }
-
- x11_os.flush();
-
- /* Start forwarding traffic */
-
- StreamForwarder r2l = new StreamForwarder(c, null, s, remote_is, x11_os, "RemoteToX11");
- StreamForwarder l2r = new StreamForwarder(c, null, null, x11_is, remote_os, "X11ToRemote");
-
- /* No need to start two threads, one can be executed in the current thread */
-
- r2l.setDaemon(true);
- r2l.start();
- l2r.run();
-
- while (r2l.isAlive())
- {
- try
- {
- r2l.join();
- }
- catch (InterruptedException e)
- {
- }
- }
-
- /* If the channel is already closed, then this is a no-op */
-
- c.cm.closeChannel(c, "EOF on both X11 streams reached.", true);
- s.close();
- }
- catch (IOException e)
- {
- log.log(50, "IOException in X11 proxy code: " + e.getMessage());
-
- try
- {
- c.cm.closeChannel(c, "IOException in X11 proxy code (" + e.getMessage() + ")", true);
- }
- catch (IOException e1)
- {
- }
- try
- {
- if (s != null)
- s.close();
- }
- catch (IOException e1)
- {
- }
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/channel/StreamForwarder.java b/app/src/main/java/com/trilead/ssh2/channel/StreamForwarder.java
deleted file mode 100644
index e1afee8..0000000
--- a/app/src/main/java/com/trilead/ssh2/channel/StreamForwarder.java
+++ /dev/null
@@ -1,113 +0,0 @@
-
-package com.trilead.ssh2.channel;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-
-/**
- * A StreamForwarder forwards data between two given streams.
- * If two StreamForwarder threads are used (one for each direction)
- * then one can be configured to shutdown the underlying channel/socket
- * if both threads have finished forwarding (EOF).
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: StreamForwarder.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public class StreamForwarder extends Thread
-{
- final OutputStream os;
- final InputStream is;
- final byte[] buffer = new byte[Channel.CHANNEL_BUFFER_SIZE];
- final Channel c;
- final StreamForwarder sibling;
- final Socket s;
- final String mode;
-
- StreamForwarder(Channel c, StreamForwarder sibling, Socket s, InputStream is, OutputStream os, String mode)
- throws IOException
- {
- this.is = is;
- this.os = os;
- this.mode = mode;
- this.c = c;
- this.sibling = sibling;
- this.s = s;
- }
-
- public void run()
- {
- try
- {
- while (true)
- {
- int len = is.read(buffer);
- if (len <= 0)
- break;
- os.write(buffer, 0, len);
- os.flush();
- }
- }
- catch (IOException ignore)
- {
- try
- {
- c.cm.closeChannel(c, "Closed due to exception in StreamForwarder (" + mode + "): "
- + ignore.getMessage(), true);
- }
- catch (IOException e)
- {
- }
- }
- finally
- {
- try
- {
- os.close();
- }
- catch (IOException e1)
- {
- }
- try
- {
- is.close();
- }
- catch (IOException e2)
- {
- }
-
- if (sibling != null)
- {
- while (sibling.isAlive())
- {
- try
- {
- sibling.join();
- }
- catch (InterruptedException e)
- {
- }
- }
-
- try
- {
- c.cm.closeChannel(c, "StreamForwarder (" + mode + ") is cleaning up the connection", true);
- }
- catch (IOException e3)
- {
- }
- }
-
- if (s != null) {
- try
- {
- s.close();
- }
- catch (IOException e1)
- {
- }
- }
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/channel/X11ServerData.java b/app/src/main/java/com/trilead/ssh2/channel/X11ServerData.java
deleted file mode 100644
index 041f9cb..0000000
--- a/app/src/main/java/com/trilead/ssh2/channel/X11ServerData.java
+++ /dev/null
@@ -1,16 +0,0 @@
-
-package com.trilead.ssh2.channel;
-
-/**
- * X11ServerData. Data regarding an x11 forwarding target.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: X11ServerData.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- *
- */
-public class X11ServerData
-{
- public String hostname;
- public int port;
- public byte[] x11_magic_cookie; /* not the remote (fake) one, the local (real) one */
-}
diff --git a/app/src/main/java/com/trilead/ssh2/compression/CompressionFactory.java b/app/src/main/java/com/trilead/ssh2/compression/CompressionFactory.java
deleted file mode 100644
index 9f8d7ef..0000000
--- a/app/src/main/java/com/trilead/ssh2/compression/CompressionFactory.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * ConnectBot: simple, powerful, open-source SSH client for Android
- * Copyright 2007 Kenny Root, Jeffrey Sharkey
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.trilead.ssh2.compression;
-
-import java.util.Vector;
-
-/**
- * @author Kenny Root
- *
- */
-public class CompressionFactory {
- static class CompressorEntry
- {
- String type;
- String compressorClass;
-
- public CompressorEntry(String type, String compressorClass)
- {
- this.type = type;
- this.compressorClass = compressorClass;
- }
- }
-
- static Vector<CompressorEntry> compressors = new Vector<CompressorEntry>();
-
- static
- {
- /* Higher Priority First */
-
- compressors.addElement(new CompressorEntry("zlib", "com.trilead.ssh2.compression.Zlib"));
- compressors.addElement(new CompressorEntry("zlib@openssh.com", "com.trilead.ssh2.compression.ZlibOpenSSH"));
- compressors.addElement(new CompressorEntry("none", ""));
- }
-
- public static String[] getDefaultCompressorList()
- {
- String list[] = new String[compressors.size()];
- for (int i = 0; i < compressors.size(); i++)
- {
- CompressorEntry ce = compressors.elementAt(i);
- list[i] = new String(ce.type);
- }
- return list;
- }
-
- public static void checkCompressorList(String[] compressorCandidates)
- {
- for (int i = 0; i < compressorCandidates.length; i++)
- getEntry(compressorCandidates[i]);
- }
-
- public static ICompressor createCompressor(String type)
- {
- try
- {
- CompressorEntry ce = getEntry(type);
- if ("".equals(ce.compressorClass))
- return null;
-
- Class<?> cc = Class.forName(ce.compressorClass);
- ICompressor cmp = (ICompressor) cc.newInstance();
-
- return cmp;
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("Cannot instantiate " + type);
- }
- }
-
- private static CompressorEntry getEntry(String type)
- {
- for (int i = 0; i < compressors.size(); i++)
- {
- CompressorEntry ce = compressors.elementAt(i);
- if (ce.type.equals(type))
- return ce;
- }
- throw new IllegalArgumentException("Unkown algorithm " + type);
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/compression/ICompressor.java b/app/src/main/java/com/trilead/ssh2/compression/ICompressor.java
deleted file mode 100644
index 0b435b9..0000000
--- a/app/src/main/java/com/trilead/ssh2/compression/ICompressor.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * ConnectBot: simple, powerful, open-source SSH client for Android
- * Copyright 2007 Kenny Root, Jeffrey Sharkey
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.trilead.ssh2.compression;
-
-/**
- * @author Kenny Root
- *
- */
-public interface ICompressor {
- int getBufferSize();
-
- int compress(byte[] buf, int start, int len, byte[] output);
-
- byte[] uncompress(byte[] buf, int start, int[] len);
-
- boolean canCompressPreauth();
-}
diff --git a/app/src/main/java/com/trilead/ssh2/compression/Zlib.java b/app/src/main/java/com/trilead/ssh2/compression/Zlib.java
deleted file mode 100644
index c1203a3..0000000
--- a/app/src/main/java/com/trilead/ssh2/compression/Zlib.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * ConnectBot: simple, powerful, open-source SSH client for Android
- * Copyright 2007 Kenny Root, Jeffrey Sharkey
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.trilead.ssh2.compression;
-
-import com.jcraft.jzlib.JZlib;
-import com.jcraft.jzlib.ZStream;
-
-/**
- * @author Kenny Root
- *
- */
-public class Zlib implements ICompressor {
- static private final int DEFAULT_BUF_SIZE = 4096;
- static private final int LEVEL = 5;
-
- private ZStream deflate;
- private byte[] deflate_tmpbuf;
-
- private ZStream inflate;
- private byte[] inflate_tmpbuf;
- private byte[] inflated_buf;
-
- public Zlib() {
- deflate = new ZStream();
- inflate = new ZStream();
-
- deflate.deflateInit(LEVEL);
- inflate.inflateInit();
-
- deflate_tmpbuf = new byte[DEFAULT_BUF_SIZE];
- inflate_tmpbuf = new byte[DEFAULT_BUF_SIZE];
- inflated_buf = new byte[DEFAULT_BUF_SIZE];
- }
-
- public boolean canCompressPreauth() {
- return true;
- }
-
- public int getBufferSize() {
- return DEFAULT_BUF_SIZE;
- }
-
- public int compress(byte[] buf, int start, int len, byte[] output) {
- deflate.next_in = buf;
- deflate.next_in_index = start;
- deflate.avail_in = len - start;
-
- if ((buf.length + 1024) > deflate_tmpbuf.length) {
- deflate_tmpbuf = new byte[buf.length + 1024];
- }
-
- deflate.next_out = deflate_tmpbuf;
- deflate.next_out_index = 0;
- deflate.avail_out = output.length;
-
- if (deflate.deflate(JZlib.Z_PARTIAL_FLUSH) != JZlib.Z_OK) {
- System.err.println("compress: compression failure");
- }
-
- if (deflate.avail_in > 0) {
- System.err.println("compress: deflated data too large");
- }
-
- int outputlen = output.length - deflate.avail_out;
-
- System.arraycopy(deflate_tmpbuf, 0, output, 0, outputlen);
-
- return outputlen;
- }
-
- public byte[] uncompress(byte[] buffer, int start, int[] length) {
- int inflated_end = 0;
-
- inflate.next_in = buffer;
- inflate.next_in_index = start;
- inflate.avail_in = length[0];
-
- while (true) {
- inflate.next_out = inflate_tmpbuf;
- inflate.next_out_index = 0;
- inflate.avail_out = DEFAULT_BUF_SIZE;
- int status = inflate.inflate(JZlib.Z_PARTIAL_FLUSH);
- switch (status) {
- case JZlib.Z_OK:
- if (inflated_buf.length < inflated_end + DEFAULT_BUF_SIZE
- - inflate.avail_out) {
- byte[] foo = new byte[inflated_end + DEFAULT_BUF_SIZE
- - inflate.avail_out];
- System.arraycopy(inflated_buf, 0, foo, 0, inflated_end);
- inflated_buf = foo;
- }
- System.arraycopy(inflate_tmpbuf, 0, inflated_buf, inflated_end,
- DEFAULT_BUF_SIZE - inflate.avail_out);
- inflated_end += (DEFAULT_BUF_SIZE - inflate.avail_out);
- length[0] = inflated_end;
- break;
- case JZlib.Z_BUF_ERROR:
- if (inflated_end > buffer.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:
- System.err.println("uncompress: inflate returnd " + status);
- return null;
- }
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/compression/ZlibOpenSSH.java b/app/src/main/java/com/trilead/ssh2/compression/ZlibOpenSSH.java
deleted file mode 100644
index 266fff9..0000000
--- a/app/src/main/java/com/trilead/ssh2/compression/ZlibOpenSSH.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * ConnectBot: simple, powerful, open-source SSH client for Android
- * Copyright 2007 Kenny Root, Jeffrey Sharkey
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.trilead.ssh2.compression;
-
-/**
- * Defines how zlib@openssh.org compression works.
- * See
- * http://www.openssh.org/txt/draft-miller-secsh-compression-delayed-00.txt
- * compression is disabled until userauth has occurred.
- *
- * @author Matt Johnston
- *
- */
-public class ZlibOpenSSH extends Zlib {
-
- public boolean canCompressPreauth() {
- return false;
- }
-
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/Base64.java b/app/src/main/java/com/trilead/ssh2/crypto/Base64.java
deleted file mode 100644
index 93770ac..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/Base64.java
+++ /dev/null
@@ -1,148 +0,0 @@
-
-package com.trilead.ssh2.crypto;
-
-import java.io.CharArrayWriter;
-import java.io.IOException;
-
-/**
- * Basic Base64 Support.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: Base64.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public class Base64
-{
- static final char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
-
- public static char[] encode(byte[] content)
- {
- CharArrayWriter cw = new CharArrayWriter((4 * content.length) / 3);
-
- int idx = 0;
-
- int x = 0;
-
- for (int i = 0; i < content.length; i++)
- {
- if (idx == 0)
- x = (content[i] & 0xff) << 16;
- else if (idx == 1)
- x = x | ((content[i] & 0xff) << 8);
- else
- x = x | (content[i] & 0xff);
-
- idx++;
-
- if (idx == 3)
- {
- cw.write(alphabet[x >> 18]);
- cw.write(alphabet[(x >> 12) & 0x3f]);
- cw.write(alphabet[(x >> 6) & 0x3f]);
- cw.write(alphabet[x & 0x3f]);
-
- idx = 0;
- }
- }
-
- if (idx == 1)
- {
- cw.write(alphabet[x >> 18]);
- cw.write(alphabet[(x >> 12) & 0x3f]);
- cw.write('=');
- cw.write('=');
- }
-
- if (idx == 2)
- {
- cw.write(alphabet[x >> 18]);
- cw.write(alphabet[(x >> 12) & 0x3f]);
- cw.write(alphabet[(x >> 6) & 0x3f]);
- cw.write('=');
- }
-
- return cw.toCharArray();
- }
-
- public static byte[] decode(char[] message) throws IOException
- {
- byte buff[] = new byte[4];
- byte dest[] = new byte[message.length];
-
- int bpos = 0;
- int destpos = 0;
-
- for (int i = 0; i < message.length; i++)
- {
- int c = message[i];
-
- if ((c == '\n') || (c == '\r') || (c == ' ') || (c == '\t'))
- continue;
-
- if ((c >= 'A') && (c <= 'Z'))
- {
- buff[bpos++] = (byte) (c - 'A');
- }
- else if ((c >= 'a') && (c <= 'z'))
- {
- buff[bpos++] = (byte) ((c - 'a') + 26);
- }
- else if ((c >= '0') && (c <= '9'))
- {
- buff[bpos++] = (byte) ((c - '0') + 52);
- }
- else if (c == '+')
- {
- buff[bpos++] = 62;
- }
- else if (c == '/')
- {
- buff[bpos++] = 63;
- }
- else if (c == '=')
- {
- buff[bpos++] = 64;
- }
- else
- {
- throw new IOException("Illegal char in base64 code.");
- }
-
- if (bpos == 4)
- {
- bpos = 0;
-
- if (buff[0] == 64)
- break;
-
- if (buff[1] == 64)
- throw new IOException("Unexpected '=' in base64 code.");
-
- if (buff[2] == 64)
- {
- int v = (((buff[0] & 0x3f) << 6) | ((buff[1] & 0x3f)));
- dest[destpos++] = (byte) (v >> 4);
- break;
- }
- else if (buff[3] == 64)
- {
- int v = (((buff[0] & 0x3f) << 12) | ((buff[1] & 0x3f) << 6) | ((buff[2] & 0x3f)));
- dest[destpos++] = (byte) (v >> 10);
- dest[destpos++] = (byte) (v >> 2);
- break;
- }
- else
- {
- int v = (((buff[0] & 0x3f) << 18) | ((buff[1] & 0x3f) << 12) | ((buff[2] & 0x3f) << 6) | ((buff[3] & 0x3f)));
- dest[destpos++] = (byte) (v >> 16);
- dest[destpos++] = (byte) (v >> 8);
- dest[destpos++] = (byte) (v);
- }
- }
- }
-
- byte[] res = new byte[destpos];
- System.arraycopy(dest, 0, res, 0, destpos);
-
- return res;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/CryptoWishList.java b/app/src/main/java/com/trilead/ssh2/crypto/CryptoWishList.java
deleted file mode 100644
index 86959e7..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/CryptoWishList.java
+++ /dev/null
@@ -1,26 +0,0 @@
-
-package com.trilead.ssh2.crypto;
-
-import com.trilead.ssh2.compression.CompressionFactory;
-import com.trilead.ssh2.crypto.cipher.BlockCipherFactory;
-import com.trilead.ssh2.crypto.digest.MAC;
-import com.trilead.ssh2.transport.KexManager;
-
-
-/**
- * CryptoWishList.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: CryptoWishList.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public class CryptoWishList
-{
- public String[] kexAlgorithms = KexManager.getDefaultKexAlgorithmList();
- public String[] serverHostKeyAlgorithms = KexManager.getDefaultServerHostkeyAlgorithmList();
- public String[] c2s_enc_algos = BlockCipherFactory.getDefaultCipherList();
- public String[] s2c_enc_algos = BlockCipherFactory.getDefaultCipherList();
- public String[] c2s_mac_algos = MAC.getMacList();
- public String[] s2c_mac_algos = MAC.getMacList();
- public String[] c2s_comp_algos = CompressionFactory.getDefaultCompressorList();
- public String[] s2c_comp_algos = CompressionFactory.getDefaultCompressorList();
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/KeyMaterial.java b/app/src/main/java/com/trilead/ssh2/crypto/KeyMaterial.java
deleted file mode 100644
index 1dbd6c7..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/KeyMaterial.java
+++ /dev/null
@@ -1,91 +0,0 @@
-
-package com.trilead.ssh2.crypto;
-
-
-import java.math.BigInteger;
-
-import com.trilead.ssh2.crypto.digest.HashForSSH2Types;
-
-/**
- * Establishes key material for iv/key/mac (both directions).
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: KeyMaterial.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public class KeyMaterial
-{
- public byte[] initial_iv_client_to_server;
- public byte[] initial_iv_server_to_client;
- public byte[] enc_key_client_to_server;
- public byte[] enc_key_server_to_client;
- public byte[] integrity_key_client_to_server;
- public byte[] integrity_key_server_to_client;
-
- private static byte[] calculateKey(HashForSSH2Types sh, BigInteger K, byte[] H, byte type, byte[] SessionID,
- int keyLength)
- {
- byte[] res = new byte[keyLength];
-
- int dglen = sh.getDigestLength();
- int numRounds = (keyLength + dglen - 1) / dglen;
-
- byte[][] tmp = new byte[numRounds][];
-
- sh.reset();
- sh.updateBigInt(K);
- sh.updateBytes(H);
- sh.updateByte(type);
- sh.updateBytes(SessionID);
-
- tmp[0] = sh.getDigest();
-
- int off = 0;
- int produced = Math.min(dglen, keyLength);
-
- System.arraycopy(tmp[0], 0, res, off, produced);
-
- keyLength -= produced;
- off += produced;
-
- for (int i = 1; i < numRounds; i++)
- {
- sh.updateBigInt(K);
- sh.updateBytes(H);
-
- for (int j = 0; j < i; j++)
- sh.updateBytes(tmp[j]);
-
- tmp[i] = sh.getDigest();
-
- produced = Math.min(dglen, keyLength);
- System.arraycopy(tmp[i], 0, res, off, produced);
- keyLength -= produced;
- off += produced;
- }
-
- return res;
- }
-
- public static KeyMaterial create(String hashAlgo, byte[] H, BigInteger K, byte[] SessionID, int keyLengthCS,
- int blockSizeCS, int macLengthCS, int keyLengthSC, int blockSizeSC, int macLengthSC)
- throws IllegalArgumentException
- {
- KeyMaterial km = new KeyMaterial();
-
- HashForSSH2Types sh = new HashForSSH2Types(hashAlgo);
-
- km.initial_iv_client_to_server = calculateKey(sh, K, H, (byte) 'A', SessionID, blockSizeCS);
-
- km.initial_iv_server_to_client = calculateKey(sh, K, H, (byte) 'B', SessionID, blockSizeSC);
-
- km.enc_key_client_to_server = calculateKey(sh, K, H, (byte) 'C', SessionID, keyLengthCS);
-
- km.enc_key_server_to_client = calculateKey(sh, K, H, (byte) 'D', SessionID, keyLengthSC);
-
- km.integrity_key_client_to_server = calculateKey(sh, K, H, (byte) 'E', SessionID, macLengthCS);
-
- km.integrity_key_server_to_client = calculateKey(sh, K, H, (byte) 'F', SessionID, macLengthSC);
-
- return km;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/PEMDecoder.java b/app/src/main/java/com/trilead/ssh2/crypto/PEMDecoder.java
deleted file mode 100644
index 5c0c2fd..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/PEMDecoder.java
+++ /dev/null
@@ -1,494 +0,0 @@
-
-package com.trilead.ssh2.crypto;
-
-import java.io.BufferedReader;
-import java.io.CharArrayReader;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.DigestException;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.spec.DSAPrivateKeySpec;
-import java.security.spec.DSAPublicKeySpec;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
-import java.security.spec.ECPrivateKeySpec;
-import java.security.spec.ECPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import java.security.spec.RSAPrivateCrtKeySpec;
-import java.security.spec.RSAPrivateKeySpec;
-import java.security.spec.RSAPublicKeySpec;
-
-import com.trilead.ssh2.crypto.cipher.AES;
-import com.trilead.ssh2.crypto.cipher.BlockCipher;
-import com.trilead.ssh2.crypto.cipher.CBCMode;
-import com.trilead.ssh2.crypto.cipher.DES;
-import com.trilead.ssh2.crypto.cipher.DESede;
-import com.trilead.ssh2.signature.ECDSASHA2Verify;
-
-/**
- * PEM Support.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PEMDecoder.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
- */
-public class PEMDecoder
-{
- public static final int PEM_RSA_PRIVATE_KEY = 1;
- public static final int PEM_DSA_PRIVATE_KEY = 2;
- public static final int PEM_EC_PRIVATE_KEY = 3;
-
- private static final int hexToInt(char c)
- {
- if ((c >= 'a') && (c <= 'f'))
- {
- return (c - 'a') + 10;
- }
-
- if ((c >= 'A') && (c <= 'F'))
- {
- return (c - 'A') + 10;
- }
-
- if ((c >= '0') && (c <= '9'))
- {
- return (c - '0');
- }
-
- throw new IllegalArgumentException("Need hex char");
- }
-
- private static byte[] hexToByteArray(String hex)
- {
- if (hex == null)
- throw new IllegalArgumentException("null argument");
-
- if ((hex.length() % 2) != 0)
- throw new IllegalArgumentException("Uneven string length in hex encoding.");
-
- byte decoded[] = new byte[hex.length() / 2];
-
- for (int i = 0; i < decoded.length; i++)
- {
- int hi = hexToInt(hex.charAt(i * 2));
- int lo = hexToInt(hex.charAt((i * 2) + 1));
-
- decoded[i] = (byte) (hi * 16 + lo);
- }
-
- return decoded;
- }
-
- private static byte[] generateKeyFromPasswordSaltWithMD5(byte[] password, byte[] salt, int keyLen)
- throws IOException
- {
- if (salt.length < 8)
- throw new IllegalArgumentException("Salt needs to be at least 8 bytes for key generation.");
-
- MessageDigest md5;
- try {
- md5 = MessageDigest.getInstance("MD5");
- } catch (NoSuchAlgorithmException e) {
- throw new IllegalArgumentException("VM does not support MD5", e);
- }
-
- byte[] key = new byte[keyLen];
- byte[] tmp = new byte[md5.getDigestLength()];
-
- while (true)
- {
- md5.update(password, 0, password.length);
- md5.update(salt, 0, 8); // ARGH we only use the first 8 bytes of the
- // salt in this step.
- // This took me two hours until I got AES-xxx running.
-
- int copy = (keyLen < tmp.length) ? keyLen : tmp.length;
-
- try {
- md5.digest(tmp, 0, tmp.length);
- } catch (DigestException e) {
- IOException ex = new IOException("could not digest password");
- ex.initCause(e);
- throw ex;
- }
-
- System.arraycopy(tmp, 0, key, key.length - keyLen, copy);
-
- keyLen -= copy;
-
- if (keyLen == 0)
- return key;
-
- md5.update(tmp, 0, tmp.length);
- }
- }
-
- private static byte[] removePadding(byte[] buff, int blockSize) throws IOException
- {
- /* Removes RFC 1423/PKCS #7 padding */
-
- int rfc_1423_padding = buff[buff.length - 1] & 0xff;
-
- if ((rfc_1423_padding < 1) || (rfc_1423_padding > blockSize))
- throw new IOException("Decrypted PEM has wrong padding, did you specify the correct password?");
-
- for (int i = 2; i <= rfc_1423_padding; i++)
- {
- if (buff[buff.length - i] != rfc_1423_padding)
- throw new IOException("Decrypted PEM has wrong padding, did you specify the correct password?");
- }
-
- byte[] tmp = new byte[buff.length - rfc_1423_padding];
- System.arraycopy(buff, 0, tmp, 0, buff.length - rfc_1423_padding);
- return tmp;
- }
-
- public static final PEMStructure parsePEM(char[] pem) throws IOException
- {
- PEMStructure ps = new PEMStructure();
-
- String line = null;
-
- BufferedReader br = new BufferedReader(new CharArrayReader(pem));
-
- String endLine = null;
-
- while (true)
- {
- line = br.readLine();
-
- if (line == null)
- throw new IOException("Invalid PEM structure, '-----BEGIN...' missing");
-
- line = line.trim();
-
- if (line.startsWith("-----BEGIN DSA PRIVATE KEY-----"))
- {
- endLine = "-----END DSA PRIVATE KEY-----";
- ps.pemType = PEM_DSA_PRIVATE_KEY;
- break;
- }
-
- if (line.startsWith("-----BEGIN RSA PRIVATE KEY-----"))
- {
- endLine = "-----END RSA PRIVATE KEY-----";
- ps.pemType = PEM_RSA_PRIVATE_KEY;
- break;
- }
-
- if (line.startsWith("-----BEGIN EC PRIVATE KEY-----")) {
- endLine = "-----END EC PRIVATE KEY-----";
- ps.pemType = PEM_EC_PRIVATE_KEY;
- break;
- }
- }
-
- while (true)
- {
- line = br.readLine();
-
- if (line == null)
- throw new IOException("Invalid PEM structure, " + endLine + " missing");
-
- line = line.trim();
-
- int sem_idx = line.indexOf(':');
-
- if (sem_idx == -1)
- break;
-
- String name = line.substring(0, sem_idx + 1);
- String value = line.substring(sem_idx + 1);
-
- String values[] = value.split(",");
-
- for (int i = 0; i < values.length; i++)
- values[i] = values[i].trim();
-
- // Proc-Type: 4,ENCRYPTED
- // DEK-Info: DES-EDE3-CBC,579B6BE3E5C60483
-
- if ("Proc-Type:".equals(name))
- {
- ps.procType = values;
- continue;
- }
-
- if ("DEK-Info:".equals(name))
- {
- ps.dekInfo = values;
- continue;
- }
- /* Ignore line */
- }
-
- StringBuffer keyData = new StringBuffer();
-
- while (true)
- {
- if (line == null)
- throw new IOException("Invalid PEM structure, " + endLine + " missing");
-
- line = line.trim();
-
- if (line.startsWith(endLine))
- break;
-
- keyData.append(line);
-
- line = br.readLine();
- }
-
- char[] pem_chars = new char[keyData.length()];
- keyData.getChars(0, pem_chars.length, pem_chars, 0);
-
- ps.data = Base64.decode(pem_chars);
-
- if (ps.data.length == 0)
- throw new IOException("Invalid PEM structure, no data available");
-
- return ps;
- }
-
- private static final void decryptPEM(PEMStructure ps, byte[] pw) throws IOException
- {
- if (ps.dekInfo == null)
- throw new IOException("Broken PEM, no mode and salt given, but encryption enabled");
-
- if (ps.dekInfo.length != 2)
- throw new IOException("Broken PEM, DEK-Info is incomplete!");
-
- String algo = ps.dekInfo[0];
- byte[] salt = hexToByteArray(ps.dekInfo[1]);
-
- BlockCipher bc = null;
-
- if (algo.equals("DES-EDE3-CBC"))
- {
- DESede des3 = new DESede();
- des3.init(false, generateKeyFromPasswordSaltWithMD5(pw, salt, 24));
- bc = new CBCMode(des3, salt, false);
- }
- else if (algo.equals("DES-CBC"))
- {
- DES des = new DES();
- des.init(false, generateKeyFromPasswordSaltWithMD5(pw, salt, 8));
- bc = new CBCMode(des, salt, false);
- }
- else if (algo.equals("AES-128-CBC"))
- {
- AES aes = new AES();
- aes.init(false, generateKeyFromPasswordSaltWithMD5(pw, salt, 16));
- bc = new CBCMode(aes, salt, false);
- }
- else if (algo.equals("AES-192-CBC"))
- {
- AES aes = new AES();
- aes.init(false, generateKeyFromPasswordSaltWithMD5(pw, salt, 24));
- bc = new CBCMode(aes, salt, false);
- }
- else if (algo.equals("AES-256-CBC"))
- {
- AES aes = new AES();
- aes.init(false, generateKeyFromPasswordSaltWithMD5(pw, salt, 32));
- bc = new CBCMode(aes, salt, false);
- }
- else
- {
- throw new IOException("Cannot decrypt PEM structure, unknown cipher " + algo);
- }
-
- if ((ps.data.length % bc.getBlockSize()) != 0)
- throw new IOException("Invalid PEM structure, size of encrypted block is not a multiple of "
- + bc.getBlockSize());
-
- /* Now decrypt the content */
-
- byte[] dz = new byte[ps.data.length];
-
- for (int i = 0; i < ps.data.length / bc.getBlockSize(); i++)
- {
- bc.transformBlock(ps.data, i * bc.getBlockSize(), dz, i * bc.getBlockSize());
- }
-
- /* Now check and remove RFC 1423/PKCS #7 padding */
-
- dz = removePadding(dz, bc.getBlockSize());
-
- ps.data = dz;
- ps.dekInfo = null;
- ps.procType = null;
- }
-
- public static final boolean isPEMEncrypted(PEMStructure ps) throws IOException
- {
- if (ps.procType == null)
- return false;
-
- if (ps.procType.length != 2)
- throw new IOException("Unknown Proc-Type field.");
-
- if ("4".equals(ps.procType[0]) == false)
- throw new IOException("Unknown Proc-Type field (" + ps.procType[0] + ")");
-
- if ("ENCRYPTED".equals(ps.procType[1]))
- return true;
-
- return false;
- }
-
- public static KeyPair decode(char[] pem, String password) throws IOException
- {
- PEMStructure ps = parsePEM(pem);
- return decode(ps, password);
- }
-
- public static KeyPair decode(PEMStructure ps, String password) throws IOException
- {
- if (isPEMEncrypted(ps))
- {
- if (password == null)
- throw new IOException("PEM is encrypted, but no password was specified");
-
- decryptPEM(ps, password.getBytes("ISO-8859-1"));
- }
-
- if (ps.pemType == PEM_DSA_PRIVATE_KEY)
- {
- SimpleDERReader dr = new SimpleDERReader(ps.data);
-
- byte[] seq = dr.readSequenceAsByteArray();
-
- if (dr.available() != 0)
- throw new IOException("Padding in DSA PRIVATE KEY DER stream.");
-
- dr.resetInput(seq);
-
- BigInteger version = dr.readInt();
-
- if (version.compareTo(BigInteger.ZERO) != 0)
- throw new IOException("Wrong version (" + version + ") in DSA PRIVATE KEY DER stream.");
-
- BigInteger p = dr.readInt();
- BigInteger q = dr.readInt();
- BigInteger g = dr.readInt();
- BigInteger y = dr.readInt();
- BigInteger x = dr.readInt();
-
- if (dr.available() != 0)
- throw new IOException("Padding in DSA PRIVATE KEY DER stream.");
-
- DSAPrivateKeySpec privSpec = new DSAPrivateKeySpec(x, p, q, g);
- DSAPublicKeySpec pubSpec = new DSAPublicKeySpec(y, p, q, g);
-
- return generateKeyPair("DSA", privSpec, pubSpec);
- }
-
- if (ps.pemType == PEM_RSA_PRIVATE_KEY)
- {
- SimpleDERReader dr = new SimpleDERReader(ps.data);
-
- byte[] seq = dr.readSequenceAsByteArray();
-
- if (dr.available() != 0)
- throw new IOException("Padding in RSA PRIVATE KEY DER stream.");
-
- dr.resetInput(seq);
-
- BigInteger version = dr.readInt();
-
- if ((version.compareTo(BigInteger.ZERO) != 0) && (version.compareTo(BigInteger.ONE) != 0))
- throw new IOException("Wrong version (" + version + ") in RSA PRIVATE KEY DER stream.");
-
- BigInteger n = dr.readInt();
- BigInteger e = dr.readInt();
- BigInteger d = dr.readInt();
- // TODO: is this right?
- BigInteger primeP = dr.readInt();
- BigInteger primeQ = dr.readInt();
- BigInteger expP = dr.readInt();
- BigInteger expQ = dr.readInt();
- BigInteger coeff = dr.readInt();
-
- RSAPrivateKeySpec privSpec = new RSAPrivateCrtKeySpec(n, e, d, primeP, primeQ, expP, expQ, coeff);
- RSAPublicKeySpec pubSpec = new RSAPublicKeySpec(n, e);
-
- return generateKeyPair("RSA", privSpec, pubSpec);
- }
-
- if (ps.pemType == PEM_EC_PRIVATE_KEY) {
- SimpleDERReader dr = new SimpleDERReader(ps.data);
-
- byte[] seq = dr.readSequenceAsByteArray();
-
- if (dr.available() != 0)
- throw new IOException("Padding in EC PRIVATE KEY DER stream.");
-
- dr.resetInput(seq);
-
- BigInteger version = dr.readInt();
-
- if ((version.compareTo(BigInteger.ONE) != 0))
- throw new IOException("Wrong version (" + version + ") in EC PRIVATE KEY DER stream.");
-
- byte[] privateBytes = dr.readOctetString();
-
- String curveOid = null;
- byte[] publicBytes = null;
- while (dr.available() > 0) {
- int type = dr.readConstructedType();
- SimpleDERReader cr = dr.readConstructed();
- switch (type) {
- case 0:
- curveOid = cr.readOid();
- break;
- case 1:
- publicBytes = cr.readOctetString();
- break;
- }
- }
-
- ECParameterSpec params = ECDSASHA2Verify.getCurveForOID(curveOid);
- if (params == null)
- throw new IOException("invalid OID");
-
- BigInteger s = new BigInteger(privateBytes);
- byte[] publicBytesSlice = new byte[publicBytes.length - 1];
- System.arraycopy(publicBytes, 1, publicBytesSlice, 0, publicBytesSlice.length);
- ECPoint w = ECDSASHA2Verify.decodeECPoint(publicBytesSlice, params.getCurve());
-
- ECPrivateKeySpec privSpec = new ECPrivateKeySpec(s, params);
- ECPublicKeySpec pubSpec = new ECPublicKeySpec(w, params);
-
- return generateKeyPair("EC", privSpec, pubSpec);
- }
-
- throw new IOException("PEM problem: it is of unknown type");
- }
-
- /**
- * Generate a {@code KeyPair} given an {@code algorithm} and {@code KeySpec}.
- */
- private static KeyPair generateKeyPair(String algorithm, KeySpec privSpec, KeySpec pubSpec)
- throws IOException {
- try {
- final KeyFactory kf = KeyFactory.getInstance(algorithm);
- final PublicKey pubKey = kf.generatePublic(pubSpec);
- final PrivateKey privKey = kf.generatePrivate(privSpec);
- return new KeyPair(pubKey, privKey);
- } catch (NoSuchAlgorithmException ex) {
- IOException ioex = new IOException();
- ioex.initCause(ex);
- throw ioex;
- } catch (InvalidKeySpecException ex) {
- IOException ioex = new IOException("invalid keyspec");
- ioex.initCause(ex);
- throw ioex;
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/PEMStructure.java b/app/src/main/java/com/trilead/ssh2/crypto/PEMStructure.java
deleted file mode 100644
index 83fb799..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/PEMStructure.java
+++ /dev/null
@@ -1,17 +0,0 @@
-
-package com.trilead.ssh2.crypto;
-
-/**
- * Parsed PEM structure.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PEMStructure.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-
-public class PEMStructure
-{
- public int pemType;
- String dekInfo[];
- String procType[];
- public byte[] data;
-} \ No newline at end of file
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/SimpleDERReader.java b/app/src/main/java/com/trilead/ssh2/crypto/SimpleDERReader.java
deleted file mode 100644
index ff8112a..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/SimpleDERReader.java
+++ /dev/null
@@ -1,229 +0,0 @@
-package com.trilead.ssh2.crypto;
-
-import java.io.IOException;
-
-import java.math.BigInteger;
-
-/**
- * SimpleDERReader.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: SimpleDERReader.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public class SimpleDERReader
-{
- private static final int CONSTRUCTED = 0x20;
-
- byte[] buffer;
- int pos;
- int count;
-
- public SimpleDERReader(byte[] b)
- {
- resetInput(b);
- }
-
- public SimpleDERReader(byte[] b, int off, int len)
- {
- resetInput(b, off, len);
- }
-
- public void resetInput(byte[] b)
- {
- resetInput(b, 0, b.length);
- }
-
- public void resetInput(byte[] b, int off, int len)
- {
- buffer = b;
- pos = off;
- count = len;
- }
-
- private byte readByte() throws IOException
- {
- if (count <= 0)
- throw new IOException("DER byte array: out of data");
- count--;
- return buffer[pos++];
- }
-
- private byte[] readBytes(int len) throws IOException
- {
- if (len > count)
- throw new IOException("DER byte array: out of data");
-
- byte[] b = new byte[len];
-
- System.arraycopy(buffer, pos, b, 0, len);
-
- pos += len;
- count -= len;
-
- return b;
- }
-
- public int available()
- {
- return count;
- }
-
- private int readLength() throws IOException
- {
- int len = readByte() & 0xff;
-
- if ((len & 0x80) == 0)
- return len;
-
- int remain = len & 0x7F;
-
- if (remain == 0)
- return -1;
-
- len = 0;
-
- while (remain > 0)
- {
- len = len << 8;
- len = len | (readByte() & 0xff);
- remain--;
- }
-
- return len;
- }
-
- public int ignoreNextObject() throws IOException
- {
- int type = readByte() & 0xff;
-
- int len = readLength();
-
- if ((len < 0) || len > available())
- throw new IOException("Illegal len in DER object (" + len + ")");
-
- readBytes(len);
-
- return type;
- }
-
- public BigInteger readInt() throws IOException
- {
- int type = readByte() & 0xff;
-
- if (type != 0x02)
- throw new IOException("Expected DER Integer, but found type " + type);
-
- int len = readLength();
-
- if ((len < 0) || len > available())
- throw new IOException("Illegal len in DER object (" + len + ")");
-
- byte[] b = readBytes(len);
-
- BigInteger bi = new BigInteger(b);
-
- return bi;
- }
-
- public int readConstructedType() throws IOException {
- int type = readByte() & 0xff;
-
- if ((type & CONSTRUCTED) != CONSTRUCTED)
- throw new IOException("Expected constructed type, but was " + type);
-
- return type & 0x1f;
- }
-
- public SimpleDERReader readConstructed() throws IOException
- {
- int len = readLength();
-
- if ((len < 0) || len > available())
- throw new IOException("Illegal len in DER object (" + len + ")");
-
- SimpleDERReader cr = new SimpleDERReader(buffer, pos, len);
-
- pos += len;
- count -= len;
-
- return cr;
- }
-
- public byte[] readSequenceAsByteArray() throws IOException
- {
- int type = readByte() & 0xff;
-
- if (type != 0x30)
- throw new IOException("Expected DER Sequence, but found type " + type);
-
- int len = readLength();
-
- if ((len < 0) || len > available())
- throw new IOException("Illegal len in DER object (" + len + ")");
-
- byte[] b = readBytes(len);
-
- return b;
- }
-
- public String readOid() throws IOException
- {
- int type = readByte() & 0xff;
-
- if (type != 0x06)
- throw new IOException("Expected DER OID, but found type " + type);
-
- int len = readLength();
-
- if ((len < 1) || len > available())
- throw new IOException("Illegal len in DER object (" + len + ")");
-
- byte[] b = readBytes(len);
-
- long value = 0;
-
- StringBuilder sb = new StringBuilder(64);
- switch(b[0] / 40) {
- case 0:
- sb.append('0');
- break;
- case 1:
- sb.append('1');
- b[0] -= 40;
- break;
- default:
- sb.append('2');
- b[0] -= 80;
- break;
- }
-
- for (int i = 0; i < len; i++) {
- value = (value << 7) + (b[i] & 0x7F);
- if ((b[i] & 0x80) == 0) {
- sb.append('.');
- sb.append(value);
- value = 0;
- }
- }
-
- return sb.toString();
- }
-
- public byte[] readOctetString() throws IOException
- {
- int type = readByte() & 0xff;
-
- if (type != 0x04 && type != 0x03)
- throw new IOException("Expected DER Octetstring, but found type " + type);
-
- int len = readLength();
-
- if ((len < 0) || len > available())
- throw new IOException("Illegal len in DER object (" + len + ")");
-
- byte[] b = readBytes(len);
-
- return b;
- }
-
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/cipher/AES.java b/app/src/main/java/com/trilead/ssh2/crypto/cipher/AES.java
deleted file mode 100644
index e89e4a6..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/cipher/AES.java
+++ /dev/null
@@ -1,698 +0,0 @@
-
-package com.trilead.ssh2.crypto.cipher;
-
-/*
- This file was shamelessly taken from the Bouncy Castle Crypto package.
- Their licence file states the following:
-
- Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
- (http://www.bouncycastle.org)
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- */
-
-/**
- * An implementation of the AES (Rijndael), from FIPS-197.
- * <p>
- * For further details see: <a
- * href="http://csrc.nist.gov/encryption/aes/">http://csrc.nist.gov/encryption/aes/
- * </a>.
- *
- * This implementation is based on optimizations from Dr. Brian Gladman's paper
- * and C code at <a
- * href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">http://fp.gladman.plus.com/cryptography_technology/rijndael/
- * </a>
- *
- * There are three levels of tradeoff of speed vs memory Because java has no
- * preprocessor, they are written as three separate classes from which to choose
- *
- * The fastest uses 8Kbytes of static tables to precompute round calculations, 4
- * 256 word tables for encryption and 4 for decryption.
- *
- * The middle performance version uses only one 256 word table for each, for a
- * total of 2Kbytes, adding 12 rotate operations per round to compute the values
- * contained in the other tables from the contents of the first
- *
- * The slowest version uses no static tables at all and computes the values in
- * each round
- * <p>
- * This file contains the fast version with 8Kbytes of static tables for round
- * precomputation
- *
- * @author See comments in the source file
- * @version $Id: AES.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class AES implements BlockCipher
-{
- // The S box
- private static final byte[] S = { (byte) 99, (byte) 124, (byte) 119, (byte) 123, (byte) 242, (byte) 107,
- (byte) 111, (byte) 197, (byte) 48, (byte) 1, (byte) 103, (byte) 43, (byte) 254, (byte) 215, (byte) 171,
- (byte) 118, (byte) 202, (byte) 130, (byte) 201, (byte) 125, (byte) 250, (byte) 89, (byte) 71, (byte) 240,
- (byte) 173, (byte) 212, (byte) 162, (byte) 175, (byte) 156, (byte) 164, (byte) 114, (byte) 192, (byte) 183,
- (byte) 253, (byte) 147, (byte) 38, (byte) 54, (byte) 63, (byte) 247, (byte) 204, (byte) 52, (byte) 165,
- (byte) 229, (byte) 241, (byte) 113, (byte) 216, (byte) 49, (byte) 21, (byte) 4, (byte) 199, (byte) 35,
- (byte) 195, (byte) 24, (byte) 150, (byte) 5, (byte) 154, (byte) 7, (byte) 18, (byte) 128, (byte) 226,
- (byte) 235, (byte) 39, (byte) 178, (byte) 117, (byte) 9, (byte) 131, (byte) 44, (byte) 26, (byte) 27,
- (byte) 110, (byte) 90, (byte) 160, (byte) 82, (byte) 59, (byte) 214, (byte) 179, (byte) 41, (byte) 227,
- (byte) 47, (byte) 132, (byte) 83, (byte) 209, (byte) 0, (byte) 237, (byte) 32, (byte) 252, (byte) 177,
- (byte) 91, (byte) 106, (byte) 203, (byte) 190, (byte) 57, (byte) 74, (byte) 76, (byte) 88, (byte) 207,
- (byte) 208, (byte) 239, (byte) 170, (byte) 251, (byte) 67, (byte) 77, (byte) 51, (byte) 133, (byte) 69,
- (byte) 249, (byte) 2, (byte) 127, (byte) 80, (byte) 60, (byte) 159, (byte) 168, (byte) 81, (byte) 163,
- (byte) 64, (byte) 143, (byte) 146, (byte) 157, (byte) 56, (byte) 245, (byte) 188, (byte) 182, (byte) 218,
- (byte) 33, (byte) 16, (byte) 255, (byte) 243, (byte) 210, (byte) 205, (byte) 12, (byte) 19, (byte) 236,
- (byte) 95, (byte) 151, (byte) 68, (byte) 23, (byte) 196, (byte) 167, (byte) 126, (byte) 61, (byte) 100,
- (byte) 93, (byte) 25, (byte) 115, (byte) 96, (byte) 129, (byte) 79, (byte) 220, (byte) 34, (byte) 42,
- (byte) 144, (byte) 136, (byte) 70, (byte) 238, (byte) 184, (byte) 20, (byte) 222, (byte) 94, (byte) 11,
- (byte) 219, (byte) 224, (byte) 50, (byte) 58, (byte) 10, (byte) 73, (byte) 6, (byte) 36, (byte) 92,
- (byte) 194, (byte) 211, (byte) 172, (byte) 98, (byte) 145, (byte) 149, (byte) 228, (byte) 121, (byte) 231,
- (byte) 200, (byte) 55, (byte) 109, (byte) 141, (byte) 213, (byte) 78, (byte) 169, (byte) 108, (byte) 86,
- (byte) 244, (byte) 234, (byte) 101, (byte) 122, (byte) 174, (byte) 8, (byte) 186, (byte) 120, (byte) 37,
- (byte) 46, (byte) 28, (byte) 166, (byte) 180, (byte) 198, (byte) 232, (byte) 221, (byte) 116, (byte) 31,
- (byte) 75, (byte) 189, (byte) 139, (byte) 138, (byte) 112, (byte) 62, (byte) 181, (byte) 102, (byte) 72,
- (byte) 3, (byte) 246, (byte) 14, (byte) 97, (byte) 53, (byte) 87, (byte) 185, (byte) 134, (byte) 193,
- (byte) 29, (byte) 158, (byte) 225, (byte) 248, (byte) 152, (byte) 17, (byte) 105, (byte) 217, (byte) 142,
- (byte) 148, (byte) 155, (byte) 30, (byte) 135, (byte) 233, (byte) 206, (byte) 85, (byte) 40, (byte) 223,
- (byte) 140, (byte) 161, (byte) 137, (byte) 13, (byte) 191, (byte) 230, (byte) 66, (byte) 104, (byte) 65,
- (byte) 153, (byte) 45, (byte) 15, (byte) 176, (byte) 84, (byte) 187, (byte) 22, };
-
- // The inverse S-box
- private static final byte[] Si = { (byte) 82, (byte) 9, (byte) 106, (byte) 213, (byte) 48, (byte) 54, (byte) 165,
- (byte) 56, (byte) 191, (byte) 64, (byte) 163, (byte) 158, (byte) 129, (byte) 243, (byte) 215, (byte) 251,
- (byte) 124, (byte) 227, (byte) 57, (byte) 130, (byte) 155, (byte) 47, (byte) 255, (byte) 135, (byte) 52,
- (byte) 142, (byte) 67, (byte) 68, (byte) 196, (byte) 222, (byte) 233, (byte) 203, (byte) 84, (byte) 123,
- (byte) 148, (byte) 50, (byte) 166, (byte) 194, (byte) 35, (byte) 61, (byte) 238, (byte) 76, (byte) 149,
- (byte) 11, (byte) 66, (byte) 250, (byte) 195, (byte) 78, (byte) 8, (byte) 46, (byte) 161, (byte) 102,
- (byte) 40, (byte) 217, (byte) 36, (byte) 178, (byte) 118, (byte) 91, (byte) 162, (byte) 73, (byte) 109,
- (byte) 139, (byte) 209, (byte) 37, (byte) 114, (byte) 248, (byte) 246, (byte) 100, (byte) 134, (byte) 104,
- (byte) 152, (byte) 22, (byte) 212, (byte) 164, (byte) 92, (byte) 204, (byte) 93, (byte) 101, (byte) 182,
- (byte) 146, (byte) 108, (byte) 112, (byte) 72, (byte) 80, (byte) 253, (byte) 237, (byte) 185, (byte) 218,
- (byte) 94, (byte) 21, (byte) 70, (byte) 87, (byte) 167, (byte) 141, (byte) 157, (byte) 132, (byte) 144,
- (byte) 216, (byte) 171, (byte) 0, (byte) 140, (byte) 188, (byte) 211, (byte) 10, (byte) 247, (byte) 228,
- (byte) 88, (byte) 5, (byte) 184, (byte) 179, (byte) 69, (byte) 6, (byte) 208, (byte) 44, (byte) 30,
- (byte) 143, (byte) 202, (byte) 63, (byte) 15, (byte) 2, (byte) 193, (byte) 175, (byte) 189, (byte) 3,
- (byte) 1, (byte) 19, (byte) 138, (byte) 107, (byte) 58, (byte) 145, (byte) 17, (byte) 65, (byte) 79,
- (byte) 103, (byte) 220, (byte) 234, (byte) 151, (byte) 242, (byte) 207, (byte) 206, (byte) 240, (byte) 180,
- (byte) 230, (byte) 115, (byte) 150, (byte) 172, (byte) 116, (byte) 34, (byte) 231, (byte) 173, (byte) 53,
- (byte) 133, (byte) 226, (byte) 249, (byte) 55, (byte) 232, (byte) 28, (byte) 117, (byte) 223, (byte) 110,
- (byte) 71, (byte) 241, (byte) 26, (byte) 113, (byte) 29, (byte) 41, (byte) 197, (byte) 137, (byte) 111,
- (byte) 183, (byte) 98, (byte) 14, (byte) 170, (byte) 24, (byte) 190, (byte) 27, (byte) 252, (byte) 86,
- (byte) 62, (byte) 75, (byte) 198, (byte) 210, (byte) 121, (byte) 32, (byte) 154, (byte) 219, (byte) 192,
- (byte) 254, (byte) 120, (byte) 205, (byte) 90, (byte) 244, (byte) 31, (byte) 221, (byte) 168, (byte) 51,
- (byte) 136, (byte) 7, (byte) 199, (byte) 49, (byte) 177, (byte) 18, (byte) 16, (byte) 89, (byte) 39,
- (byte) 128, (byte) 236, (byte) 95, (byte) 96, (byte) 81, (byte) 127, (byte) 169, (byte) 25, (byte) 181,
- (byte) 74, (byte) 13, (byte) 45, (byte) 229, (byte) 122, (byte) 159, (byte) 147, (byte) 201, (byte) 156,
- (byte) 239, (byte) 160, (byte) 224, (byte) 59, (byte) 77, (byte) 174, (byte) 42, (byte) 245, (byte) 176,
- (byte) 200, (byte) 235, (byte) 187, (byte) 60, (byte) 131, (byte) 83, (byte) 153, (byte) 97, (byte) 23,
- (byte) 43, (byte) 4, (byte) 126, (byte) 186, (byte) 119, (byte) 214, (byte) 38, (byte) 225, (byte) 105,
- (byte) 20, (byte) 99, (byte) 85, (byte) 33, (byte) 12, (byte) 125, };
-
- // vector used in calculating key schedule (powers of x in GF(256))
- private static final int[] rcon = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab,
- 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 };
-
- // precomputation tables of calculations for rounds
- private static final int[] T0 = { 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6,
- 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d,
- 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb,
- 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, 0xc2b7b775,
- 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, 0x5c343468, 0xf4a5a551,
- 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, 0x0c040408, 0x52c7c795, 0x65232346,
- 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df,
- 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36,
- 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd,
- 0x712f2f5e, 0x97848413, 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179,
- 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85,
- 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a,
- 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d,
- 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf,
- 0x63212142, 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3,
- 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8,
- 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54,
- 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16,
- 0x76dbdbad, 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,
- 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, 0x32e7e7d5,
- 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, 0xfa5656ac,
- 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a,
- 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e,
- 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890,
- 0x05030306, 0x01f6f6f7, 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199,
- 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07,
- 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
- 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182,
- 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c };
-
- private static final int[] T1 = { 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, 0x6b6bd6bd,
- 0x6f6fdeb1, 0xc5c59154, 0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d, 0xfefee719, 0xd7d7b562, 0xabab4de6,
- 0x7676ec9a, 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b,
- 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, 0xb7b775c2,
- 0xfdfde11c, 0x93933dae, 0x26264c6a, 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, 0x3434685c, 0xa5a551f4,
- 0xe5e5d134, 0xf1f1f908, 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, 0x0404080c, 0xc7c79552, 0x23234665,
- 0xc3c39d5e, 0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5, 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d,
- 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, 0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, 0x1b1b362d,
- 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, 0x2929527b, 0xe3e3dd3e,
- 0x2f2f5e71, 0x84841397, 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, 0x20204060, 0xfcfce31f, 0xb1b179c8,
- 0x5b5bb6ed, 0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a,
- 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, 0x45458acf,
- 0xf9f9e910, 0x02020406, 0x7f7ffe81, 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, 0x5151a2f3, 0xa3a35dfe,
- 0x404080c0, 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, 0xbcbc63df, 0xb6b677c1, 0xdadaaf75,
- 0x21214263, 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, 0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f,
- 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, 0x6464c8ac,
- 0x5d5dbae7, 0x1919322b, 0x7373e695, 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e,
- 0x90903bab, 0x88880b83, 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, 0xdedea779, 0x5e5ebce2, 0x0b0b161d,
- 0xdbdbad76, 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4,
- 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, 0xe7e7d532,
- 0xc8c88b43, 0x37376e59, 0x6d6ddab7, 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, 0x6c6cd8b4, 0x5656acfa,
- 0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018, 0xbaba6fd5, 0x7878f088, 0x25254a6f,
- 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21,
- 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, 0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, 0x484890d8,
- 0x03030605, 0xf6f6f701, 0x0e0e1c12, 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, 0x86861791, 0xc1c19958,
- 0x1d1d3a27, 0x9e9e27b9, 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, 0x6969d2bb, 0xd9d9a970, 0x8e8e0789,
- 0x949433a7, 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a,
- 0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, 0x414182c3,
- 0x999929b0, 0x2d2d5a77, 0x0f0f1e11, 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a };
-
- private static final int[] T2 = { 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, 0x6bd6bd6b,
- 0x6fdeb16f, 0xc59154c5, 0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b, 0xfee719fe, 0xd7b562d7, 0xab4de6ab,
- 0x76ec9a76, 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0,
- 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, 0xb775c2b7,
- 0xfde11cfd, 0x933dae93, 0x264c6a26, 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, 0x34685c34, 0xa551f4a5,
- 0xe5d134e5, 0xf1f908f1, 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, 0x04080c04, 0xc79552c7, 0x23466523,
- 0xc39d5ec3, 0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a, 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2,
- 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, 0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, 0x1b362d1b,
- 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, 0x29527b29, 0xe3dd3ee3,
- 0x2f5e712f, 0x84139784, 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, 0x20406020, 0xfce31ffc, 0xb179c8b1,
- 0x5bb6ed5b, 0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf,
- 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, 0x458acf45,
- 0xf9e910f9, 0x02040602, 0x7ffe817f, 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, 0x51a2f351, 0xa35dfea3,
- 0x4080c040, 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da,
- 0x21426321, 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, 0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec,
- 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, 0x64c8ac64,
- 0x5dbae75d, 0x19322b19, 0x73e69573, 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a,
- 0x903bab90, 0x880b8388, 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, 0xdea779de, 0x5ebce25e, 0x0b161d0b,
- 0xdbad76db, 0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c,
- 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, 0xe7d532e7,
- 0xc88b43c8, 0x376e5937, 0x6ddab76d, 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, 0x6cd8b46c, 0x56acfa56,
- 0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808, 0xba6fd5ba, 0x78f08878, 0x254a6f25,
- 0x2e5c722e, 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f,
- 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, 0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, 0x4890d848,
- 0x03060503, 0xf6f701f6, 0x0e1c120e, 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, 0x86179186, 0xc19958c1,
- 0x1d3a271d, 0x9e27b99e, 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, 0x69d2bb69, 0xd9a970d9, 0x8e07898e,
- 0x9433a794, 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf,
- 0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, 0x4182c341,
- 0x9929b099, 0x2d5a772d, 0x0f1e110f, 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16 };
-
- private static final int[] T3 = { 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, 0xd6bd6b6b,
- 0xdeb16f6f, 0x9154c5c5, 0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b, 0xe719fefe, 0xb562d7d7, 0x4de6abab,
- 0xec9a7676, 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0,
- 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, 0x75c2b7b7,
- 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, 0x685c3434, 0x51f4a5a5,
- 0xd134e5e5, 0xf908f1f1, 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, 0x080c0404, 0x9552c7c7, 0x46652323,
- 0x9d5ec3c3, 0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a, 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2,
- 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, 0x362d1b1b,
- 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3,
- 0x5e712f2f, 0x13978484, 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, 0x40602020, 0xe31ffcfc, 0x79c8b1b1,
- 0xb6ed5b5b, 0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf,
- 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, 0x8acf4545,
- 0xe910f9f9, 0x04060202, 0xfe817f7f, 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, 0xa2f35151, 0x5dfea3a3,
- 0x80c04040, 0x058a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada,
- 0x42632121, 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec,
- 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, 0xc8ac6464,
- 0xbae75d5d, 0x322b1919, 0xe6957373, 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a,
- 0x3bab9090, 0x0b838888, 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, 0xa779dede, 0xbce25e5e, 0x161d0b0b,
- 0xad76dbdb, 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c,
- 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, 0xd532e7e7,
- 0x8b43c8c8, 0x6e593737, 0xdab76d6d, 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, 0xd8b46c6c, 0xacfa5656,
- 0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, 0x6fd5baba, 0xf0887878, 0x4a6f2525,
- 0x5c722e2e, 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f,
- 0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, 0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, 0x90d84848,
- 0x06050303, 0xf701f6f6, 0x1c120e0e, 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, 0x17918686, 0x9958c1c1,
- 0x3a271d1d, 0x27b99e9e, 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, 0xd2bb6969, 0xa970d9d9, 0x07898e8e,
- 0x33a79494, 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf,
- 0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, 0x82c34141,
- 0x29b09999, 0x5a772d2d, 0x1e110f0f, 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616 };
-
- private static final int[] Tinv0 = { 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, 0xf1459d1f,
- 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526,
- 0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b,
- 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e, 0x6a89c275,
- 0x78798ef4, 0x6b3e5899, 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, 0x184adf63, 0x82311ae5,
- 0x60335197, 0x457f5362, 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f, 0x876cde94,
- 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3,
- 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65,
- 0xd5be0506, 0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 0x39ec830b, 0xaaef6040,
- 0x069f715e, 0x51106ebd, 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, 0x055dc471, 0x6fd40604,
- 0xff155060, 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879,
- 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd,
- 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0x0fe75793,
- 0xd296eeb4, 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, 0x0aba93e2, 0xe52aa0c0, 0x43e0223c,
- 0x1d171b12, 0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3,
- 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, 0xcadc31d7,
- 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc,
- 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56,
- 0xef903322, 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f,
- 0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, 0xbe805d9f,
- 0x7c93d069, 0xa92dd56f, 0xb31225cf, 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x097826cd, 0xf418596e,
- 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea,
- 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733,
- 0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, 0xe3b5d19e,
- 0x1b886a4c, 0xb81f2cc1, 0x7f516546, 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, 0x5a1d67b3, 0x52d2db92,
- 0x335610e9, 0x1347d66d, 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, 0xede51ce1,
- 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478,
- 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839,
- 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0 };
-
- private static final int[] Tinv1 = { 0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, 0x6bab3bcb, 0x459d1ff1,
- 0x58faacab, 0x03e34b93, 0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525, 0xd7e54ffc, 0xcb2ac5d7, 0x44352680,
- 0xa362b58f, 0x5ab1de49, 0x1bba2567, 0x0eea4598, 0xc0fe5de1, 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6,
- 0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da, 0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44, 0x89c2756a,
- 0x798ef478, 0x3e58996b, 0x71b927dd, 0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4, 0x4adf6318, 0x311ae582,
- 0x33519760, 0x7f536245, 0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994, 0x68487058, 0xfd458f19, 0x6cde9487,
- 0xf87b52b7, 0xd373ab23, 0x024b72e2, 0x8f1fe357, 0xab55662a, 0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x0837d3a5,
- 0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, 0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1, 0xf4da65cd,
- 0xbe0506d5, 0x6234d11f, 0xfea6c48a, 0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475, 0xec830b39, 0xef6040aa,
- 0x9f715e06, 0x106ebd51, 0x8a213ef9, 0x06dd963d, 0x053eddae, 0xbde64d46, 0x8d5491b5, 0x5dc47105, 0xd406046f,
- 0x155060ff, 0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777, 0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db,
- 0x0a7ca147, 0x0f427ce9, 0x1e84f8c9, 0x00000000, 0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e, 0xff0efdfb,
- 0x38850f56, 0xd5ae3d1e, 0x392d3627, 0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a, 0x670a0cb1, 0xe757930f,
- 0x96eeb4d2, 0x919b1b9e, 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16, 0xba93e20a, 0x2aa0c0e5, 0xe0223c43,
- 0x171b121d, 0x0d090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8, 0x19f15785, 0x0775af4c, 0xdd99eebb, 0x607fa3fd,
- 0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34, 0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863, 0xdc31d7ca,
- 0x85634210, 0x22971340, 0x11c68420, 0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, 0x2f9e1d4b, 0x30b2dcf3,
- 0x52860dec, 0xe3c177d0, 0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722, 0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8,
- 0x903322ef, 0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0x0bd49836, 0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4,
- 0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462, 0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5, 0x805d9fbe,
- 0x93d0697c, 0x2dd56fa9, 0x1225cfb3, 0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, 0x7826cd09, 0x18596ef4,
- 0xb79aec01, 0x9a4f83a8, 0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6, 0x9be7bad9, 0x366f4ace, 0x099fead4,
- 0x7cb029d6, 0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0, 0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315,
- 0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f, 0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x0496e4df, 0xb5d19ee3,
- 0x886a4c1b, 0x1f2cc1b8, 0x5165467f, 0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, 0x1d67b35a, 0xd2db9252,
- 0x5610e933, 0x47d66d13, 0x61d79a8c, 0x0ca1377a, 0x14f8598e, 0x3c13eb89, 0x27a9ceee, 0xc961b735, 0xe51ce1ed,
- 0xb1477a3c, 0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf, 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886,
- 0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, 0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41, 0x01a83971,
- 0xb30c08de, 0xe4b4d89c, 0xc1566490, 0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042 };
-
- private static final int[] Tinv2 = { 0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, 0xab3bcb6b, 0x9d1ff145,
- 0xfaacab58, 0xe34b9303, 0x302055fa, 0x76adf66d, 0xcc889176, 0x02f5254c, 0xe54ffcd7, 0x2ac5d7cb, 0x35268044,
- 0x62b58fa3, 0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0, 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9,
- 0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59, 0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8, 0xc2756a89,
- 0x8ef47879, 0x58996b3e, 0xb927dd71, 0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a, 0xdf63184a, 0x1ae58231,
- 0x51976033, 0x5362457f, 0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x08f9942b, 0x48705868, 0x458f19fd, 0xde94876c,
- 0x7b52b7f8, 0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab, 0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508,
- 0x2830f287, 0xbf23b2a5, 0x0302ba6a, 0x16ed5c82, 0xcf8a2b1c, 0x79a792b4, 0x07f3f0f2, 0x694ea1e2, 0xda65cdf4,
- 0x0506d5be, 0x34d11f62, 0xa6c48afe, 0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb, 0x830b39ec, 0x6040aaef,
- 0x715e069f, 0x6ebd5110, 0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, 0x5491b58d, 0xc471055d, 0x06046fd4,
- 0x5060ff15, 0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e, 0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee,
- 0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x00000000, 0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72, 0x0efdfbff,
- 0x850f5638, 0xae3d1ed5, 0x2d362739, 0x0f0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e, 0x0a0cb167, 0x57930fe7,
- 0xeeb4d296, 0x9b1b9e91, 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a, 0x93e20aba, 0xa0c0e52a, 0x223c43e0,
- 0x1b121d17, 0x090e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9, 0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60,
- 0x01f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e, 0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1, 0x31d7cadc,
- 0x63421085, 0x97134022, 0xc6842011, 0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, 0x9e1d4b2f, 0xb2dcf330,
- 0x860dec52, 0xc177d0e3, 0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264, 0xfca8c48c, 0xf0a01a3f, 0x7d56d82c,
- 0x3322ef90, 0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, 0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf,
- 0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246, 0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af, 0x5d9fbe80,
- 0xd0697c93, 0xd56fa92d, 0x25cfb312, 0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, 0x26cd0978, 0x596ef418,
- 0x9aec01b7, 0x4f83a89a, 0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8, 0xe7bad99b, 0x6f4ace36, 0x9fead409,
- 0xb029d67c, 0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066, 0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8,
- 0x04f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6, 0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04, 0xd19ee3b5,
- 0x6a4c1b88, 0x2cc1b81f, 0x65467f51, 0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0x0bfb2e41, 0x67b35a1d, 0xdb9252d2,
- 0x10e93356, 0xd66d1347, 0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c, 0xa9ceee27, 0x61b735c9, 0x1ce1ede5,
- 0x477a3cb1, 0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37, 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db,
- 0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, 0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0x0dff4195, 0xa8397101,
- 0x0c08deb3, 0xb4d89ce4, 0x566490c1, 0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257 };
-
- private static final int[] Tinv3 = { 0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, 0x3bcb6bab, 0x1ff1459d,
- 0xacab58fa, 0x4b9303e3, 0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02, 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435,
- 0xb58fa362, 0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe, 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3,
- 0x03e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, 0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9, 0x756a89c2,
- 0xf478798e, 0x996b3e58, 0x27dd71b9, 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, 0x63184adf, 0xe582311a,
- 0x97603351, 0x62457f53, 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08, 0x70586848, 0x8f19fd45, 0x94876cde,
- 0x52b7f87b, 0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55, 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837,
- 0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216, 0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269, 0x65cdf4da,
- 0x06d5be05, 0xd11f6234, 0xc48afea6, 0x349d532e, 0xa2a055f3, 0x0532e18a, 0xa475ebf6, 0x0b39ec83, 0x40aaef60,
- 0x5e069f71, 0xbd51106e, 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, 0x91b58d54, 0x71055dc4, 0x046fd406,
- 0x60ff1550, 0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9, 0xb0bd42e8, 0x07888b89, 0xe7385b19, 0x79dbeec8,
- 0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000, 0x09838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a, 0xfdfbff0e,
- 0x0f563885, 0x3d1ed5ae, 0x3627392d, 0x0a64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, 0x0cb1670a, 0x930fe757,
- 0xb4d296ee, 0x1b9e919b, 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12, 0xe20aba93, 0xc0e52aa0, 0x3c43e022,
- 0x121d171b, 0x0e0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e, 0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f,
- 0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, 0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4, 0xd7cadc31,
- 0x42108563, 0x13402297, 0x842011c6, 0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, 0x1d4b2f9e, 0xdcf330b2,
- 0x0dec5286, 0x77d0e3c1, 0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9, 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d,
- 0x22ef9033, 0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad,
- 0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, 0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3, 0x9fbe805d,
- 0x697c93d0, 0x6fa92dd5, 0xcfb31225, 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, 0xcd097826, 0x6ef41859,
- 0xec01b79a, 0x83a89a4f, 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815, 0xbad99be7, 0x4ace366f, 0xead4099f,
- 0x29d67cb0, 0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2, 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7,
- 0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, 0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496, 0x9ee3b5d1,
- 0x4c1b886a, 0xc1b81f2c, 0x467f5165, 0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b, 0xb35a1d67, 0x9252d2db,
- 0xe9335610, 0x6d1347d6, 0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13, 0xceee27a9, 0xb735c961, 0xe1ede51c,
- 0x7a3cb147, 0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7, 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44,
- 0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, 0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d, 0x397101a8,
- 0x08deb30c, 0xd89ce4b4, 0x6490c156, 0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8 };
-
- private final int shift(int r, int shift)
- {
- return (((r >>> shift) | (r << (32 - shift))));
- }
-
- /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
-
- private static final int m1 = 0x80808080;
- private static final int m2 = 0x7f7f7f7f;
- private static final int m3 = 0x0000001b;
-
- private final int FFmulX(int x)
- {
- return (((x & m2) << 1) ^ (((x & m1) >>> 7) * m3));
- }
-
- /*
- * The following defines provide alternative definitions of FFmulX that
- * might give improved performance if a fast 32-bit multiply is not
- * available.
- *
- * private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x &
- * m2) < < 1) ^ ((u >>> 3) | (u >>> 6)); } private static final int m4 =
- * 0x1b1b1b1b; private int FFmulX(int x) { int u = x & m1; return ((x & m2) < <
- * 1) ^ ((u - (u >>> 7)) & m4); }
- *
- */
-
- private final int inv_mcol(int x)
- {
- int f2 = FFmulX(x);
- int f4 = FFmulX(f2);
- int f8 = FFmulX(f4);
- int f9 = x ^ f8;
-
- return f2 ^ f4 ^ f8 ^ shift(f2 ^ f9, 8) ^ shift(f4 ^ f9, 16) ^ shift(f9, 24);
- }
-
- private final int subWord(int x)
- {
- return (S[x & 255] & 255 | ((S[(x >> 8) & 255] & 255) << 8) | ((S[(x >> 16) & 255] & 255) << 16) | S[(x >> 24) & 255] << 24);
- }
-
- /**
- * Calculate the necessary round keys The number of calculations depends on
- * key size and block size AES specified a fixed block size of 128 bits and
- * key sizes 128/192/256 bits This code is written assuming those are the
- * only possible values
- */
- private final int[][] generateWorkingKey(byte[] key, boolean forEncryption)
- {
- int KC = key.length / 4; // key length in words
- int t;
-
- if (((KC != 4) && (KC != 6) && (KC != 8)) || ((KC * 4) != key.length))
- {
- throw new IllegalArgumentException("Key length not 128/192/256 bits.");
- }
-
- ROUNDS = KC + 6; // This is not always true for the generalized
- // Rijndael that allows larger block sizes
- int[][] W = new int[ROUNDS + 1][4]; // 4 words in a block
-
- //
- // copy the key into the round key array
- //
-
- t = 0;
- for (int i = 0; i < key.length; t++)
- {
- W[t >> 2][t & 3] = (key[i] & 0xff) | ((key[i + 1] & 0xff) << 8) | ((key[i + 2] & 0xff) << 16)
- | (key[i + 3] << 24);
- i += 4;
- }
-
- //
- // while not enough round key material calculated
- // calculate new values
- //
- int k = (ROUNDS + 1) << 2;
- for (int i = KC; (i < k); i++)
- {
- int temp = W[(i - 1) >> 2][(i - 1) & 3];
- if ((i % KC) == 0)
- {
- temp = subWord(shift(temp, 8)) ^ rcon[(i / KC) - 1];
- }
- else if ((KC > 6) && ((i % KC) == 4))
- {
- temp = subWord(temp);
- }
-
- W[i >> 2][i & 3] = W[(i - KC) >> 2][(i - KC) & 3] ^ temp;
- }
-
- if (!forEncryption)
- {
- for (int j = 1; j < ROUNDS; j++)
- {
- for (int i = 0; i < 4; i++)
- {
- W[j][i] = inv_mcol(W[j][i]);
- }
- }
- }
-
- return W;
- }
-
- private int ROUNDS;
- private int[][] WorkingKey = null;
- private int C0, C1, C2, C3;
- private boolean doEncrypt;
-
- private static final int BLOCK_SIZE = 16;
-
- /**
- * default constructor - 128 bit block size.
- */
- public AES()
- {
- }
-
- /**
- * initialise an AES cipher.
- *
- * @param forEncryption
- * whether or not we are for encryption.
- * @param key
- * the key required to set up the cipher.
- * @exception IllegalArgumentException
- * if the params argument is inappropriate.
- */
-
- public final void init(boolean forEncryption, byte[] key)
- {
- WorkingKey = generateWorkingKey(key, forEncryption);
- this.doEncrypt = forEncryption;
- }
-
- public final String getAlgorithmName()
- {
- return "AES";
- }
-
- public final int getBlockSize()
- {
- return BLOCK_SIZE;
- }
-
- public final int processBlock(byte[] in, int inOff, byte[] out, int outOff)
- {
- if (WorkingKey == null)
- {
- throw new IllegalStateException("AES engine not initialised");
- }
-
- if ((inOff + (32 / 2)) > in.length)
- {
- throw new IllegalArgumentException("input buffer too short");
- }
-
- if ((outOff + (32 / 2)) > out.length)
- {
- throw new IllegalArgumentException("output buffer too short");
- }
-
- if (doEncrypt)
- {
- unpackBlock(in, inOff);
- encryptBlock(WorkingKey);
- packBlock(out, outOff);
- }
- else
- {
- unpackBlock(in, inOff);
- decryptBlock(WorkingKey);
- packBlock(out, outOff);
- }
-
- return BLOCK_SIZE;
- }
-
- public final void reset()
- {
- }
-
- private final void unpackBlock(byte[] bytes, int off)
- {
- int index = off;
-
- C0 = (bytes[index++] & 0xff);
- C0 |= (bytes[index++] & 0xff) << 8;
- C0 |= (bytes[index++] & 0xff) << 16;
- C0 |= bytes[index++] << 24;
-
- C1 = (bytes[index++] & 0xff);
- C1 |= (bytes[index++] & 0xff) << 8;
- C1 |= (bytes[index++] & 0xff) << 16;
- C1 |= bytes[index++] << 24;
-
- C2 = (bytes[index++] & 0xff);
- C2 |= (bytes[index++] & 0xff) << 8;
- C2 |= (bytes[index++] & 0xff) << 16;
- C2 |= bytes[index++] << 24;
-
- C3 = (bytes[index++] & 0xff);
- C3 |= (bytes[index++] & 0xff) << 8;
- C3 |= (bytes[index++] & 0xff) << 16;
- C3 |= bytes[index++] << 24;
- }
-
- private final void packBlock(byte[] bytes, int off)
- {
- int index = off;
-
- bytes[index++] = (byte) C0;
- bytes[index++] = (byte) (C0 >> 8);
- bytes[index++] = (byte) (C0 >> 16);
- bytes[index++] = (byte) (C0 >> 24);
-
- bytes[index++] = (byte) C1;
- bytes[index++] = (byte) (C1 >> 8);
- bytes[index++] = (byte) (C1 >> 16);
- bytes[index++] = (byte) (C1 >> 24);
-
- bytes[index++] = (byte) C2;
- bytes[index++] = (byte) (C2 >> 8);
- bytes[index++] = (byte) (C2 >> 16);
- bytes[index++] = (byte) (C2 >> 24);
-
- bytes[index++] = (byte) C3;
- bytes[index++] = (byte) (C3 >> 8);
- bytes[index++] = (byte) (C3 >> 16);
- bytes[index++] = (byte) (C3 >> 24);
- }
-
- private final void encryptBlock(int[][] KW)
- {
- int r, r0, r1, r2, r3;
-
- C0 ^= KW[0][0];
- C1 ^= KW[0][1];
- C2 ^= KW[0][2];
- C3 ^= KW[0][3];
-
- for (r = 1; r < ROUNDS - 1;)
- {
- r0 = T0[C0 & 255] ^ T1[(C1 >> 8) & 255] ^ T2[(C2 >> 16) & 255] ^ T3[(C3 >> 24) & 255] ^ KW[r][0];
- r1 = T0[C1 & 255] ^ T1[(C2 >> 8) & 255] ^ T2[(C3 >> 16) & 255] ^ T3[(C0 >> 24) & 255] ^ KW[r][1];
- r2 = T0[C2 & 255] ^ T1[(C3 >> 8) & 255] ^ T2[(C0 >> 16) & 255] ^ T3[(C1 >> 24) & 255] ^ KW[r][2];
- r3 = T0[C3 & 255] ^ T1[(C0 >> 8) & 255] ^ T2[(C1 >> 16) & 255] ^ T3[(C2 >> 24) & 255] ^ KW[r++][3];
- C0 = T0[r0 & 255] ^ T1[(r1 >> 8) & 255] ^ T2[(r2 >> 16) & 255] ^ T3[(r3 >> 24) & 255] ^ KW[r][0];
- C1 = T0[r1 & 255] ^ T1[(r2 >> 8) & 255] ^ T2[(r3 >> 16) & 255] ^ T3[(r0 >> 24) & 255] ^ KW[r][1];
- C2 = T0[r2 & 255] ^ T1[(r3 >> 8) & 255] ^ T2[(r0 >> 16) & 255] ^ T3[(r1 >> 24) & 255] ^ KW[r][2];
- C3 = T0[r3 & 255] ^ T1[(r0 >> 8) & 255] ^ T2[(r1 >> 16) & 255] ^ T3[(r2 >> 24) & 255] ^ KW[r++][3];
- }
-
- r0 = T0[C0 & 255] ^ T1[(C1 >> 8) & 255] ^ T2[(C2 >> 16) & 255] ^ T3[(C3 >> 24) & 255] ^ KW[r][0];
- r1 = T0[C1 & 255] ^ T1[(C2 >> 8) & 255] ^ T2[(C3 >> 16) & 255] ^ T3[(C0 >> 24) & 255] ^ KW[r][1];
- r2 = T0[C2 & 255] ^ T1[(C3 >> 8) & 255] ^ T2[(C0 >> 16) & 255] ^ T3[(C1 >> 24) & 255] ^ KW[r][2];
- r3 = T0[C3 & 255] ^ T1[(C0 >> 8) & 255] ^ T2[(C1 >> 16) & 255] ^ T3[(C2 >> 24) & 255] ^ KW[r++][3];
-
- // the final round's table is a simple function of S so we don't use a
- // whole other four tables for it
-
- C0 = (S[r0 & 255] & 255) ^ ((S[(r1 >> 8) & 255] & 255) << 8) ^ ((S[(r2 >> 16) & 255] & 255) << 16)
- ^ (S[(r3 >> 24) & 255] << 24) ^ KW[r][0];
- C1 = (S[r1 & 255] & 255) ^ ((S[(r2 >> 8) & 255] & 255) << 8) ^ ((S[(r3 >> 16) & 255] & 255) << 16)
- ^ (S[(r0 >> 24) & 255] << 24) ^ KW[r][1];
- C2 = (S[r2 & 255] & 255) ^ ((S[(r3 >> 8) & 255] & 255) << 8) ^ ((S[(r0 >> 16) & 255] & 255) << 16)
- ^ (S[(r1 >> 24) & 255] << 24) ^ KW[r][2];
- C3 = (S[r3 & 255] & 255) ^ ((S[(r0 >> 8) & 255] & 255) << 8) ^ ((S[(r1 >> 16) & 255] & 255) << 16)
- ^ (S[(r2 >> 24) & 255] << 24) ^ KW[r][3];
-
- }
-
- private final void decryptBlock(int[][] KW)
- {
- int r, r0, r1, r2, r3;
-
- C0 ^= KW[ROUNDS][0];
- C1 ^= KW[ROUNDS][1];
- C2 ^= KW[ROUNDS][2];
- C3 ^= KW[ROUNDS][3];
-
- for (r = ROUNDS - 1; r > 1;)
- {
- r0 = Tinv0[C0 & 255] ^ Tinv1[(C3 >> 8) & 255] ^ Tinv2[(C2 >> 16) & 255] ^ Tinv3[(C1 >> 24) & 255]
- ^ KW[r][0];
- r1 = Tinv0[C1 & 255] ^ Tinv1[(C0 >> 8) & 255] ^ Tinv2[(C3 >> 16) & 255] ^ Tinv3[(C2 >> 24) & 255]
- ^ KW[r][1];
- r2 = Tinv0[C2 & 255] ^ Tinv1[(C1 >> 8) & 255] ^ Tinv2[(C0 >> 16) & 255] ^ Tinv3[(C3 >> 24) & 255]
- ^ KW[r][2];
- r3 = Tinv0[C3 & 255] ^ Tinv1[(C2 >> 8) & 255] ^ Tinv2[(C1 >> 16) & 255] ^ Tinv3[(C0 >> 24) & 255]
- ^ KW[r--][3];
- C0 = Tinv0[r0 & 255] ^ Tinv1[(r3 >> 8) & 255] ^ Tinv2[(r2 >> 16) & 255] ^ Tinv3[(r1 >> 24) & 255]
- ^ KW[r][0];
- C1 = Tinv0[r1 & 255] ^ Tinv1[(r0 >> 8) & 255] ^ Tinv2[(r3 >> 16) & 255] ^ Tinv3[(r2 >> 24) & 255]
- ^ KW[r][1];
- C2 = Tinv0[r2 & 255] ^ Tinv1[(r1 >> 8) & 255] ^ Tinv2[(r0 >> 16) & 255] ^ Tinv3[(r3 >> 24) & 255]
- ^ KW[r][2];
- C3 = Tinv0[r3 & 255] ^ Tinv1[(r2 >> 8) & 255] ^ Tinv2[(r1 >> 16) & 255] ^ Tinv3[(r0 >> 24) & 255]
- ^ KW[r--][3];
- }
-
- r0 = Tinv0[C0 & 255] ^ Tinv1[(C3 >> 8) & 255] ^ Tinv2[(C2 >> 16) & 255] ^ Tinv3[(C1 >> 24) & 255] ^ KW[r][0];
- r1 = Tinv0[C1 & 255] ^ Tinv1[(C0 >> 8) & 255] ^ Tinv2[(C3 >> 16) & 255] ^ Tinv3[(C2 >> 24) & 255] ^ KW[r][1];
- r2 = Tinv0[C2 & 255] ^ Tinv1[(C1 >> 8) & 255] ^ Tinv2[(C0 >> 16) & 255] ^ Tinv3[(C3 >> 24) & 255] ^ KW[r][2];
- r3 = Tinv0[C3 & 255] ^ Tinv1[(C2 >> 8) & 255] ^ Tinv2[(C1 >> 16) & 255] ^ Tinv3[(C0 >> 24) & 255] ^ KW[r--][3];
-
- // the final round's table is a simple function of Si so we don't use a
- // whole other four tables for it
-
- C0 = (Si[r0 & 255] & 255) ^ ((Si[(r3 >> 8) & 255] & 255) << 8) ^ ((Si[(r2 >> 16) & 255] & 255) << 16)
- ^ (Si[(r1 >> 24) & 255] << 24) ^ KW[0][0];
- C1 = (Si[r1 & 255] & 255) ^ ((Si[(r0 >> 8) & 255] & 255) << 8) ^ ((Si[(r3 >> 16) & 255] & 255) << 16)
- ^ (Si[(r2 >> 24) & 255] << 24) ^ KW[0][1];
- C2 = (Si[r2 & 255] & 255) ^ ((Si[(r1 >> 8) & 255] & 255) << 8) ^ ((Si[(r0 >> 16) & 255] & 255) << 16)
- ^ (Si[(r3 >> 24) & 255] << 24) ^ KW[0][2];
- C3 = (Si[r3 & 255] & 255) ^ ((Si[(r2 >> 8) & 255] & 255) << 8) ^ ((Si[(r1 >> 16) & 255] & 255) << 16)
- ^ (Si[(r0 >> 24) & 255] << 24) ^ KW[0][3];
- }
-
- public void transformBlock(byte[] src, int srcoff, byte[] dst, int dstoff)
- {
- processBlock(src, srcoff, dst, dstoff);
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/cipher/BlockCipher.java b/app/src/main/java/com/trilead/ssh2/crypto/cipher/BlockCipher.java
deleted file mode 100644
index 4cc28ab..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/cipher/BlockCipher.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.trilead.ssh2.crypto.cipher;
-
-/**
- * BlockCipher.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: BlockCipher.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public interface BlockCipher
-{
- public void init(boolean forEncryption, byte[] key);
-
- public int getBlockSize();
-
- public void transformBlock(byte[] src, int srcoff, byte[] dst, int dstoff);
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/cipher/BlockCipherFactory.java b/app/src/main/java/com/trilead/ssh2/crypto/cipher/BlockCipherFactory.java
deleted file mode 100644
index 6e386a5..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/cipher/BlockCipherFactory.java
+++ /dev/null
@@ -1,115 +0,0 @@
-
-package com.trilead.ssh2.crypto.cipher;
-
-import java.util.Vector;
-
-/**
- * BlockCipherFactory.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: BlockCipherFactory.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
- */
-public class BlockCipherFactory
-{
- static class CipherEntry
- {
- String type;
- int blocksize;
- int keysize;
- String cipherClass;
-
- public CipherEntry(String type, int blockSize, int keySize, String cipherClass)
- {
- this.type = type;
- this.blocksize = blockSize;
- this.keysize = keySize;
- this.cipherClass = cipherClass;
- }
- }
-
- static Vector<CipherEntry> ciphers = new Vector<CipherEntry>();
-
- static
- {
- /* Higher Priority First */
-
- ciphers.addElement(new CipherEntry("aes256-ctr", 16, 32, "com.trilead.ssh2.crypto.cipher.AES"));
- ciphers.addElement(new CipherEntry("aes192-ctr", 16, 24, "com.trilead.ssh2.crypto.cipher.AES"));
- ciphers.addElement(new CipherEntry("aes128-ctr", 16, 16, "com.trilead.ssh2.crypto.cipher.AES"));
- ciphers.addElement(new CipherEntry("blowfish-ctr", 8, 16, "com.trilead.ssh2.crypto.cipher.BlowFish"));
-
- ciphers.addElement(new CipherEntry("aes256-cbc", 16, 32, "com.trilead.ssh2.crypto.cipher.AES"));
- ciphers.addElement(new CipherEntry("aes192-cbc", 16, 24, "com.trilead.ssh2.crypto.cipher.AES"));
- ciphers.addElement(new CipherEntry("aes128-cbc", 16, 16, "com.trilead.ssh2.crypto.cipher.AES"));
- ciphers.addElement(new CipherEntry("blowfish-cbc", 8, 16, "com.trilead.ssh2.crypto.cipher.BlowFish"));
-
- ciphers.addElement(new CipherEntry("3des-ctr", 8, 24, "com.trilead.ssh2.crypto.cipher.DESede"));
- ciphers.addElement(new CipherEntry("3des-cbc", 8, 24, "com.trilead.ssh2.crypto.cipher.DESede"));
- }
-
- public static String[] getDefaultCipherList()
- {
- String list[] = new String[ciphers.size()];
- for (int i = 0; i < ciphers.size(); i++)
- {
- CipherEntry ce = ciphers.elementAt(i);
- list[i] = new String(ce.type);
- }
- return list;
- }
-
- public static void checkCipherList(String[] cipherCandidates)
- {
- for (int i = 0; i < cipherCandidates.length; i++)
- getEntry(cipherCandidates[i]);
- }
-
- public static BlockCipher createCipher(String type, boolean encrypt, byte[] key, byte[] iv)
- {
- try
- {
- CipherEntry ce = getEntry(type);
- Class cc = Class.forName(ce.cipherClass);
- BlockCipher bc = (BlockCipher) cc.newInstance();
-
- if (type.endsWith("-cbc"))
- {
- bc.init(encrypt, key);
- return new CBCMode(bc, iv, encrypt);
- }
- else if (type.endsWith("-ctr"))
- {
- bc.init(true, key);
- return new CTRMode(bc, iv, encrypt);
- }
- throw new IllegalArgumentException("Cannot instantiate " + type);
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException("Cannot instantiate " + type);
- }
- }
-
- private static CipherEntry getEntry(String type)
- {
- for (int i = 0; i < ciphers.size(); i++)
- {
- CipherEntry ce = ciphers.elementAt(i);
- if (ce.type.equals(type))
- return ce;
- }
- throw new IllegalArgumentException("Unkown algorithm " + type);
- }
-
- public static int getBlockSize(String type)
- {
- CipherEntry ce = getEntry(type);
- return ce.blocksize;
- }
-
- public static int getKeySize(String type)
- {
- CipherEntry ce = getEntry(type);
- return ce.keysize;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/cipher/BlowFish.java b/app/src/main/java/com/trilead/ssh2/crypto/cipher/BlowFish.java
deleted file mode 100644
index 0b2f295..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/cipher/BlowFish.java
+++ /dev/null
@@ -1,403 +0,0 @@
-
-package com.trilead.ssh2.crypto.cipher;
-
-/*
- This file was shamelessly taken from the Bouncy Castle Crypto package.
- Their licence file states the following:
-
- Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
- (http://www.bouncycastle.org)
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- */
-
-/**
- * A class that provides Blowfish key encryption operations, such as encoding
- * data and generating keys. All the algorithms herein are from Applied
- * Cryptography and implement a simplified cryptography interface.
- *
- * @author See comments in the source file
- * @version $Id: BlowFish.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class BlowFish implements BlockCipher
-{
-
- private final static int[] KP = { 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0,
- 0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5,
- 0xB5470917, 0x9216D5D9, 0x8979FB1B },
-
- KS0 = { 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 },
-
- KS1 = { 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 },
-
- KS2 = { 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 },
-
- KS3 = { 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 };
-
- // ====================================
- // Useful constants
- // ====================================
-
- private static final int ROUNDS = 16;
- private static final int BLOCK_SIZE = 8; // bytes = 64 bits
- private static final int SBOX_SK = 256;
- private static final int P_SZ = ROUNDS + 2;
-
- private final int[] S0, S1, S2, S3; // the s-boxes
- private final int[] P; // the p-array
-
- private boolean doEncrypt = false;
-
- private byte[] workingKey = null;
-
- public BlowFish()
- {
- S0 = new int[SBOX_SK];
- S1 = new int[SBOX_SK];
- S2 = new int[SBOX_SK];
- S3 = new int[SBOX_SK];
- P = new int[P_SZ];
- }
-
- /**
- * initialise a Blowfish cipher.
- *
- * @param encrypting
- * whether or not we are for encryption.
- * @param key
- * the key required to set up the cipher.
- * @exception IllegalArgumentException
- * if the params argument is inappropriate.
- */
- public void init(boolean encrypting, byte[] key)
- {
- this.doEncrypt = encrypting;
- this.workingKey = key;
- setKey(this.workingKey);
- }
-
- public String getAlgorithmName()
- {
- return "Blowfish";
- }
-
- public final void transformBlock(byte[] in, int inOff, byte[] out, int outOff)
- {
- if (workingKey == null)
- {
- throw new IllegalStateException("Blowfish not initialised");
- }
-
- if (doEncrypt)
- {
- encryptBlock(in, inOff, out, outOff);
- }
- else
- {
- decryptBlock(in, inOff, out, outOff);
- }
- }
-
- public void reset()
- {
- }
-
- public int getBlockSize()
- {
- return BLOCK_SIZE;
- }
-
- // ==================================
- // Private Implementation
- // ==================================
-
- private int F(int x)
- {
- return (((S0[(x >>> 24)] + S1[(x >>> 16) & 0xff]) ^ S2[(x >>> 8) & 0xff]) + S3[x & 0xff]);
- }
-
- /**
- * apply the encryption cycle to each value pair in the table.
- */
- private void processTable(int xl, int xr, int[] table)
- {
- int size = table.length;
-
- for (int s = 0; s < size; s += 2)
- {
- xl ^= P[0];
-
- for (int i = 1; i < ROUNDS; i += 2)
- {
- xr ^= F(xl) ^ P[i];
- xl ^= F(xr) ^ P[i + 1];
- }
-
- xr ^= P[ROUNDS + 1];
-
- table[s] = xr;
- table[s + 1] = xl;
-
- xr = xl; // end of cycle swap
- xl = table[s];
- }
- }
-
- private void setKey(byte[] key)
- {
- /*
- * - comments are from _Applied Crypto_, Schneier, p338 please be
- * careful comparing the two, AC numbers the arrays from 1, the enclosed
- * code from 0.
- *
- * (1) Initialise the S-boxes and the P-array, with a fixed string This
- * string contains the hexadecimal digits of pi (3.141...)
- */
- System.arraycopy(KS0, 0, S0, 0, SBOX_SK);
- System.arraycopy(KS1, 0, S1, 0, SBOX_SK);
- System.arraycopy(KS2, 0, S2, 0, SBOX_SK);
- System.arraycopy(KS3, 0, S3, 0, SBOX_SK);
-
- System.arraycopy(KP, 0, P, 0, P_SZ);
-
- /*
- * (2) Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with
- * the second 32-bits of the key, and so on for all bits of the key (up
- * to P[17]). Repeatedly cycle through the key bits until the entire
- * P-array has been XOR-ed with the key bits
- */
- int keyLength = key.length;
- int keyIndex = 0;
-
- for (int i = 0; i < P_SZ; i++)
- {
- // get the 32 bits of the key, in 4 * 8 bit chunks
- int data = 0x0000000;
- for (int j = 0; j < 4; j++)
- {
- // create a 32 bit block
- data = (data << 8) | (key[keyIndex++] & 0xff);
-
- // wrap when we get to the end of the key
- if (keyIndex >= keyLength)
- {
- keyIndex = 0;
- }
- }
- // XOR the newly created 32 bit chunk onto the P-array
- P[i] ^= data;
- }
-
- /*
- * (3) Encrypt the all-zero string with the Blowfish algorithm, using
- * the subkeys described in (1) and (2)
- *
- * (4) Replace P1 and P2 with the output of step (3)
- *
- * (5) Encrypt the output of step(3) using the Blowfish algorithm, with
- * the modified subkeys.
- *
- * (6) Replace P3 and P4 with the output of step (5)
- *
- * (7) Continue the process, replacing all elements of the P-array and
- * then all four S-boxes in order, with the output of the continuously
- * changing Blowfish algorithm
- */
-
- processTable(0, 0, P);
- processTable(P[P_SZ - 2], P[P_SZ - 1], S0);
- processTable(S0[SBOX_SK - 2], S0[SBOX_SK - 1], S1);
- processTable(S1[SBOX_SK - 2], S1[SBOX_SK - 1], S2);
- processTable(S2[SBOX_SK - 2], S2[SBOX_SK - 1], S3);
- }
-
- /**
- * Encrypt the given input starting at the given offset and place the result
- * in the provided buffer starting at the given offset. The input will be an
- * exact multiple of our blocksize.
- */
- private void encryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
- {
- int xl = BytesTo32bits(src, srcIndex);
- int xr = BytesTo32bits(src, srcIndex + 4);
-
- xl ^= P[0];
-
- for (int i = 1; i < ROUNDS; i += 2)
- {
- xr ^= F(xl) ^ P[i];
- xl ^= F(xr) ^ P[i + 1];
- }
-
- xr ^= P[ROUNDS + 1];
-
- Bits32ToBytes(xr, dst, dstIndex);
- Bits32ToBytes(xl, dst, dstIndex + 4);
- }
-
- /**
- * Decrypt the given input starting at the given offset and place the result
- * in the provided buffer starting at the given offset. The input will be an
- * exact multiple of our blocksize.
- */
- private void decryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
- {
- int xl = BytesTo32bits(src, srcIndex);
- int xr = BytesTo32bits(src, srcIndex + 4);
-
- xl ^= P[ROUNDS + 1];
-
- for (int i = ROUNDS; i > 0; i -= 2)
- {
- xr ^= F(xl) ^ P[i];
- xl ^= F(xr) ^ P[i - 1];
- }
-
- xr ^= P[0];
-
- Bits32ToBytes(xr, dst, dstIndex);
- Bits32ToBytes(xl, dst, dstIndex + 4);
- }
-
- private int BytesTo32bits(byte[] b, int i)
- {
- return ((b[i] & 0xff) << 24) | ((b[i + 1] & 0xff) << 16) | ((b[i + 2] & 0xff) << 8) | ((b[i + 3] & 0xff));
- }
-
- private void Bits32ToBytes(int in, byte[] b, int offset)
- {
- b[offset + 3] = (byte) in;
- b[offset + 2] = (byte) (in >> 8);
- b[offset + 1] = (byte) (in >> 16);
- b[offset] = (byte) (in >> 24);
- }
-
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/cipher/CBCMode.java b/app/src/main/java/com/trilead/ssh2/crypto/cipher/CBCMode.java
deleted file mode 100644
index 0ae51b3..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/cipher/CBCMode.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package com.trilead.ssh2.crypto.cipher;
-
-/**
- * CBCMode.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: CBCMode.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class CBCMode implements BlockCipher
-{
- BlockCipher tc;
- int blockSize;
- boolean doEncrypt;
-
- byte[] cbc_vector;
- byte[] tmp_vector;
-
- public void init(boolean forEncryption, byte[] key)
- {
- }
-
- public CBCMode(BlockCipher tc, byte[] iv, boolean doEncrypt)
- throws IllegalArgumentException
- {
- this.tc = tc;
- this.blockSize = tc.getBlockSize();
- this.doEncrypt = doEncrypt;
-
- if (this.blockSize != iv.length)
- throw new IllegalArgumentException("IV must be " + blockSize
- + " bytes long! (currently " + iv.length + ")");
-
- this.cbc_vector = new byte[blockSize];
- this.tmp_vector = new byte[blockSize];
- System.arraycopy(iv, 0, cbc_vector, 0, blockSize);
- }
-
- public int getBlockSize()
- {
- return blockSize;
- }
-
- private void encryptBlock(byte[] src, int srcoff, byte[] dst, int dstoff)
- {
- for (int i = 0; i < blockSize; i++)
- cbc_vector[i] ^= src[srcoff + i];
-
- tc.transformBlock(cbc_vector, 0, dst, dstoff);
-
- System.arraycopy(dst, dstoff, cbc_vector, 0, blockSize);
- }
-
- private void decryptBlock(byte[] src, int srcoff, byte[] dst, int dstoff)
- {
- /* Assume the worst, src and dst are overlapping... */
-
- System.arraycopy(src, srcoff, tmp_vector, 0, blockSize);
-
- tc.transformBlock(src, srcoff, dst, dstoff);
-
- for (int i = 0; i < blockSize; i++)
- dst[dstoff + i] ^= cbc_vector[i];
-
- /* ...that is why we need a tmp buffer. */
-
- byte[] swap = cbc_vector;
- cbc_vector = tmp_vector;
- tmp_vector = swap;
- }
-
- public void transformBlock(byte[] src, int srcoff, byte[] dst, int dstoff)
- {
- if (doEncrypt)
- encryptBlock(src, srcoff, dst, dstoff);
- else
- decryptBlock(src, srcoff, dst, dstoff);
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/cipher/CTRMode.java b/app/src/main/java/com/trilead/ssh2/crypto/cipher/CTRMode.java
deleted file mode 100644
index 8541c8d..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/cipher/CTRMode.java
+++ /dev/null
@@ -1,62 +0,0 @@
-
-package com.trilead.ssh2.crypto.cipher;
-
-/**
- * This is CTR mode as described in draft-ietf-secsh-newmodes-XY.txt
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: CTRMode.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class CTRMode implements BlockCipher
-{
- byte[] X;
- byte[] Xenc;
-
- BlockCipher bc;
- int blockSize;
- boolean doEncrypt;
-
- int count = 0;
-
- public void init(boolean forEncryption, byte[] key)
- {
- }
-
- public CTRMode(BlockCipher tc, byte[] iv, boolean doEnc) throws IllegalArgumentException
- {
- bc = tc;
- blockSize = bc.getBlockSize();
- doEncrypt = doEnc;
-
- if (blockSize != iv.length)
- throw new IllegalArgumentException("IV must be " + blockSize + " bytes long! (currently " + iv.length + ")");
-
- X = new byte[blockSize];
- Xenc = new byte[blockSize];
-
- System.arraycopy(iv, 0, X, 0, blockSize);
- }
-
- public final int getBlockSize()
- {
- return blockSize;
- }
-
- public final void transformBlock(byte[] src, int srcoff, byte[] dst, int dstoff)
- {
- bc.transformBlock(X, 0, Xenc, 0);
-
- for (int i = 0; i < blockSize; i++)
- {
- dst[dstoff + i] = (byte) (src[srcoff + i] ^ Xenc[i]);
- }
-
- for (int i = (blockSize - 1); i >= 0; i--)
- {
- X[i]++;
- if (X[i] != 0)
- break;
-
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/cipher/CipherInputStream.java b/app/src/main/java/com/trilead/ssh2/crypto/cipher/CipherInputStream.java
deleted file mode 100644
index c9055ab..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/cipher/CipherInputStream.java
+++ /dev/null
@@ -1,144 +0,0 @@
-
-package com.trilead.ssh2.crypto.cipher;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * CipherInputStream.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: CipherInputStream.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class CipherInputStream
-{
- BlockCipher currentCipher;
- InputStream bi;
- byte[] buffer;
- byte[] enc;
- int blockSize;
- int pos;
-
- /*
- * We cannot use java.io.BufferedInputStream, since that is not available in
- * J2ME. Everything could be improved alot here.
- */
-
- final int BUFF_SIZE = 2048;
- byte[] input_buffer = new byte[BUFF_SIZE];
- int input_buffer_pos = 0;
- int input_buffer_size = 0;
-
- public CipherInputStream(BlockCipher tc, InputStream bi)
- {
- this.bi = bi;
- changeCipher(tc);
- }
-
- private int fill_buffer() throws IOException
- {
- input_buffer_pos = 0;
- input_buffer_size = bi.read(input_buffer, 0, BUFF_SIZE);
- return input_buffer_size;
- }
-
- private int internal_read(byte[] b, int off, int len) throws IOException
- {
- if (input_buffer_size < 0)
- return -1;
-
- if (input_buffer_pos >= input_buffer_size)
- {
- if (fill_buffer() <= 0)
- return -1;
- }
-
- int avail = input_buffer_size - input_buffer_pos;
- int thiscopy = (len > avail) ? avail : len;
-
- System.arraycopy(input_buffer, input_buffer_pos, b, off, thiscopy);
- input_buffer_pos += thiscopy;
-
- return thiscopy;
- }
-
- public void changeCipher(BlockCipher bc)
- {
- this.currentCipher = bc;
- blockSize = bc.getBlockSize();
- buffer = new byte[blockSize];
- enc = new byte[blockSize];
- pos = blockSize;
- }
-
- private void getBlock() throws IOException
- {
- int n = 0;
- while (n < blockSize)
- {
- int len = internal_read(enc, n, blockSize - n);
- if (len < 0)
- throw new IOException("Cannot read full block, EOF reached.");
- n += len;
- }
-
- try
- {
- currentCipher.transformBlock(enc, 0, buffer, 0);
- }
- catch (Exception e)
- {
- throw new IOException("Error while decrypting block.");
- }
- pos = 0;
- }
-
- public int read(byte[] dst) throws IOException
- {
- return read(dst, 0, dst.length);
- }
-
- public int read(byte[] dst, int off, int len) throws IOException
- {
- int count = 0;
-
- while (len > 0)
- {
- if (pos >= blockSize)
- getBlock();
-
- int avail = blockSize - pos;
- int copy = Math.min(avail, len);
- System.arraycopy(buffer, pos, dst, off, copy);
- pos += copy;
- off += copy;
- len -= copy;
- count += copy;
- }
- return count;
- }
-
- public int read() throws IOException
- {
- if (pos >= blockSize)
- {
- getBlock();
- }
- return buffer[pos++] & 0xff;
- }
-
- public int readPlain(byte[] b, int off, int len) throws IOException
- {
- if (pos != blockSize)
- throw new IOException("Cannot read plain since crypto buffer is not aligned.");
- int n = 0;
- while (n < len)
- {
- int cnt = internal_read(b, off + n, len - n);
- if (cnt < 0)
- throw new IOException("Cannot fill buffer, EOF reached.");
- n += cnt;
- }
- return n;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/cipher/CipherOutputStream.java b/app/src/main/java/com/trilead/ssh2/crypto/cipher/CipherOutputStream.java
deleted file mode 100644
index cf0db4a..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/cipher/CipherOutputStream.java
+++ /dev/null
@@ -1,142 +0,0 @@
-
-package com.trilead.ssh2.crypto.cipher;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * CipherOutputStream.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: CipherOutputStream.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class CipherOutputStream
-{
- BlockCipher currentCipher;
- OutputStream bo;
- byte[] buffer;
- byte[] enc;
- int blockSize;
- int pos;
-
- /*
- * We cannot use java.io.BufferedOutputStream, since that is not available
- * in J2ME. Everything could be improved here alot.
- */
-
- final int BUFF_SIZE = 2048;
- byte[] out_buffer = new byte[BUFF_SIZE];
- int out_buffer_pos = 0;
-
- public CipherOutputStream(BlockCipher tc, OutputStream bo)
- {
- this.bo = bo;
- changeCipher(tc);
- }
-
- private void internal_write(byte[] src, int off, int len) throws IOException
- {
- while (len > 0)
- {
- int space = BUFF_SIZE - out_buffer_pos;
- int copy = (len > space) ? space : len;
-
- System.arraycopy(src, off, out_buffer, out_buffer_pos, copy);
-
- off += copy;
- out_buffer_pos += copy;
- len -= copy;
-
- if (out_buffer_pos >= BUFF_SIZE)
- {
- bo.write(out_buffer, 0, BUFF_SIZE);
- out_buffer_pos = 0;
- }
- }
- }
-
- private void internal_write(int b) throws IOException
- {
- out_buffer[out_buffer_pos++] = (byte) b;
- if (out_buffer_pos >= BUFF_SIZE)
- {
- bo.write(out_buffer, 0, BUFF_SIZE);
- out_buffer_pos = 0;
- }
- }
-
- public void flush() throws IOException
- {
- if (pos != 0)
- throw new IOException("FATAL: cannot flush since crypto buffer is not aligned.");
-
- if (out_buffer_pos > 0)
- {
- bo.write(out_buffer, 0, out_buffer_pos);
- out_buffer_pos = 0;
- }
- bo.flush();
- }
-
- public void changeCipher(BlockCipher bc)
- {
- this.currentCipher = bc;
- blockSize = bc.getBlockSize();
- buffer = new byte[blockSize];
- enc = new byte[blockSize];
- pos = 0;
- }
-
- private void writeBlock() throws IOException
- {
- try
- {
- currentCipher.transformBlock(buffer, 0, enc, 0);
- }
- catch (Exception e)
- {
- throw (IOException) new IOException("Error while decrypting block.").initCause(e);
- }
-
- internal_write(enc, 0, blockSize);
- pos = 0;
- }
-
- public void write(byte[] src, int off, int len) throws IOException
- {
- while (len > 0)
- {
- int avail = blockSize - pos;
- int copy = Math.min(avail, len);
-
- System.arraycopy(src, off, buffer, pos, copy);
- pos += copy;
- off += copy;
- len -= copy;
-
- if (pos >= blockSize)
- writeBlock();
- }
- }
-
- public void write(int b) throws IOException
- {
- buffer[pos++] = (byte) b;
- if (pos >= blockSize)
- writeBlock();
- }
-
- public void writePlain(int b) throws IOException
- {
- if (pos != 0)
- throw new IOException("Cannot write plain since crypto buffer is not aligned.");
- internal_write(b);
- }
-
- public void writePlain(byte[] b, int off, int len) throws IOException
- {
- if (pos != 0)
- throw new IOException("Cannot write plain since crypto buffer is not aligned.");
- internal_write(b, off, len);
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/cipher/DES.java b/app/src/main/java/com/trilead/ssh2/crypto/cipher/DES.java
deleted file mode 100644
index 6588459..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/cipher/DES.java
+++ /dev/null
@@ -1,373 +0,0 @@
-
-package com.trilead.ssh2.crypto.cipher;
-
-/*
- This file is based on the 3DES implementation from the Bouncy Castle Crypto package.
- Their licence file states the following:
-
- Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
- (http://www.bouncycastle.org)
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- */
-
-/**
- * DES.
- *
- * @author See comments in the source file
- * @version $Id: DES.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- *
- */
-public class DES implements BlockCipher
-{
- private int[] workingKey = null;
-
- /**
- * standard constructor.
- */
- public DES()
- {
- }
-
- /**
- * initialise a DES cipher.
- *
- * @param encrypting
- * whether or not we are for encryption.
- * @param key
- * the parameters required to set up the cipher.
- * @exception IllegalArgumentException
- * if the params argument is inappropriate.
- */
- public void init(boolean encrypting, byte[] key)
- {
- this.workingKey = generateWorkingKey(encrypting, key, 0);
- }
-
- public String getAlgorithmName()
- {
- return "DES";
- }
-
- public int getBlockSize()
- {
- return 8;
- }
-
- public void transformBlock(byte[] in, int inOff, byte[] out, int outOff)
- {
- if (workingKey == null)
- {
- throw new IllegalStateException("DES engine not initialised!");
- }
-
- desFunc(workingKey, in, inOff, out, outOff);
- }
-
- public void reset()
- {
- }
-
- /**
- * what follows is mainly taken from "Applied Cryptography", by Bruce
- * Schneier, however it also bears great resemblance to Richard
- * Outerbridge's D3DES...
- */
-
- static short[] Df_Key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32,
- 0x10, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67 };
-
- static short[] bytebit = { 0200, 0100, 040, 020, 010, 04, 02, 01 };
-
- static int[] bigbyte = { 0x800000, 0x400000, 0x200000, 0x100000, 0x80000, 0x40000, 0x20000, 0x10000, 0x8000,
- 0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 };
-
- /*
- * Use the key schedule specified in the Standard (ANSI X3.92-1981).
- */
-
- static byte[] pc1 = { 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2,
- 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12,
- 4, 27, 19, 11, 3 };
-
- static byte[] totrot = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 };
-
- static byte[] pc2 = { 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40,
- 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
-
- static int[] SP1 = { 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004,
- 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
- 0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, 0x00010004,
- 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000, 0x01010404,
- 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400,
- 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, 0x01010404, 0x00010004, 0x01010000, 0x01000404,
- 0x01000004, 0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004,
- 0x00010400, 0x00000000, 0x01010004 };
-
- static int[] SP2 = { 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020,
- 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
- 0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, 0x00100020,
- 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000, 0x00108020,
- 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020,
- 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, 0x00008020, 0x80108000, 0x00100000, 0x80000020,
- 0x00100020, 0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000,
- 0x80100020, 0x80108020, 0x00108000 };
-
- static int[] SP3 = { 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208,
- 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
- 0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, 0x08000208,
- 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200, 0x08000000,
- 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208,
- 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, 0x08000208, 0x00020000, 0x08000000, 0x08020208,
- 0x00000008, 0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208,
- 0x00000008, 0x08020008, 0x00020200 };
-
- static int[] SP4 = { 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001,
- 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
- 0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, 0x00800081,
- 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080, 0x00800001,
- 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081,
- 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802081, 0x00000081, 0x00000001, 0x00002000,
- 0x00800001, 0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080,
- 0x00800000, 0x00002000, 0x00802080 };
-
- static int[] SP5 = { 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000,
- 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
- 0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, 0x42080000,
- 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100, 0x00080000, 0x42000100,
- 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, 0x42080000,
- 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, 0x42080100, 0x00080100, 0x42000000, 0x42080100,
- 0x02080000, 0x00000000, 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000,
- 0x40080000, 0x02080100, 0x40000100 };
-
- static int[] SP6 = { 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010,
- 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
- 0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, 0x20400010,
- 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000, 0x00000010,
- 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000,
- 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, 0x00404010, 0x20404000, 0x00000000, 0x20400010,
- 0x00000010, 0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000,
- 0x20000000, 0x00400010, 0x20004010 };
-
- static int[] SP7 = { 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802,
- 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
- 0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, 0x04200000,
- 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000, 0x00200800,
- 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800,
- 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, 0x00000802, 0x04000002, 0x04200802, 0x04200000,
- 0x00200800, 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002,
- 0x04000800, 0x00000800, 0x00200002 };
-
- static int[] SP8 = { 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040,
- 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
- 0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, 0x00001040,
- 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040, 0x00040000,
- 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040,
- 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, 0x00000000, 0x10041040, 0x00040040, 0x10000040,
- 0x10040000, 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040,
- 0x00040040, 0x10000000, 0x10041000 };
-
- /**
- * generate an integer based working key based on our secret key and what we
- * processing we are planning to do.
- *
- * Acknowledgements for this routine go to James Gillogly & Phil Karn.
- * (whoever, and wherever they are!).
- */
- protected int[] generateWorkingKey(boolean encrypting, byte[] key, int off)
- {
- int[] newKey = new int[32];
- boolean[] pc1m = new boolean[56], pcr = new boolean[56];
-
- for (int j = 0; j < 56; j++)
- {
- int l = pc1[j];
-
- pc1m[j] = ((key[off + (l >>> 3)] & bytebit[l & 07]) != 0);
- }
-
- for (int i = 0; i < 16; i++)
- {
- int l, m, n;
-
- if (encrypting)
- {
- m = i << 1;
- }
- else
- {
- m = (15 - i) << 1;
- }
-
- n = m + 1;
- newKey[m] = newKey[n] = 0;
-
- for (int j = 0; j < 28; j++)
- {
- l = j + totrot[i];
- if (l < 28)
- {
- pcr[j] = pc1m[l];
- }
- else
- {
- pcr[j] = pc1m[l - 28];
- }
- }
-
- for (int j = 28; j < 56; j++)
- {
- l = j + totrot[i];
- if (l < 56)
- {
- pcr[j] = pc1m[l];
- }
- else
- {
- pcr[j] = pc1m[l - 28];
- }
- }
-
- for (int j = 0; j < 24; j++)
- {
- if (pcr[pc2[j]])
- {
- newKey[m] |= bigbyte[j];
- }
-
- if (pcr[pc2[j + 24]])
- {
- newKey[n] |= bigbyte[j];
- }
- }
- }
-
- //
- // store the processed key
- //
- for (int i = 0; i != 32; i += 2)
- {
- int i1, i2;
-
- i1 = newKey[i];
- i2 = newKey[i + 1];
-
- newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10) | ((i2 & 0x00fc0000) >>> 10)
- | ((i2 & 0x00000fc0) >>> 6);
-
- newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16) | ((i2 & 0x0003f000) >>> 4)
- | (i2 & 0x0000003f);
- }
-
- return newKey;
- }
-
- /**
- * the DES engine.
- */
- protected void desFunc(int[] wKey, byte[] in, int inOff, byte[] out, int outOff)
- {
- int work, right, left;
-
- left = (in[inOff + 0] & 0xff) << 24;
- left |= (in[inOff + 1] & 0xff) << 16;
- left |= (in[inOff + 2] & 0xff) << 8;
- left |= (in[inOff + 3] & 0xff);
-
- right = (in[inOff + 4] & 0xff) << 24;
- right |= (in[inOff + 5] & 0xff) << 16;
- right |= (in[inOff + 6] & 0xff) << 8;
- right |= (in[inOff + 7] & 0xff);
-
- work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
- right ^= work;
- left ^= (work << 4);
- work = ((left >>> 16) ^ right) & 0x0000ffff;
- right ^= work;
- left ^= (work << 16);
- work = ((right >>> 2) ^ left) & 0x33333333;
- left ^= work;
- right ^= (work << 2);
- work = ((right >>> 8) ^ left) & 0x00ff00ff;
- left ^= work;
- right ^= (work << 8);
- right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff;
- work = (left ^ right) & 0xaaaaaaaa;
- left ^= work;
- right ^= work;
- left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff;
-
- for (int round = 0; round < 8; round++)
- {
- int fval;
-
- work = (right << 28) | (right >>> 4);
- work ^= wKey[round * 4 + 0];
- fval = SP7[work & 0x3f];
- fval |= SP5[(work >>> 8) & 0x3f];
- fval |= SP3[(work >>> 16) & 0x3f];
- fval |= SP1[(work >>> 24) & 0x3f];
- work = right ^ wKey[round * 4 + 1];
- fval |= SP8[work & 0x3f];
- fval |= SP6[(work >>> 8) & 0x3f];
- fval |= SP4[(work >>> 16) & 0x3f];
- fval |= SP2[(work >>> 24) & 0x3f];
- left ^= fval;
- work = (left << 28) | (left >>> 4);
- work ^= wKey[round * 4 + 2];
- fval = SP7[work & 0x3f];
- fval |= SP5[(work >>> 8) & 0x3f];
- fval |= SP3[(work >>> 16) & 0x3f];
- fval |= SP1[(work >>> 24) & 0x3f];
- work = left ^ wKey[round * 4 + 3];
- fval |= SP8[work & 0x3f];
- fval |= SP6[(work >>> 8) & 0x3f];
- fval |= SP4[(work >>> 16) & 0x3f];
- fval |= SP2[(work >>> 24) & 0x3f];
- right ^= fval;
- }
-
- right = (right << 31) | (right >>> 1);
- work = (left ^ right) & 0xaaaaaaaa;
- left ^= work;
- right ^= work;
- left = (left << 31) | (left >>> 1);
- work = ((left >>> 8) ^ right) & 0x00ff00ff;
- right ^= work;
- left ^= (work << 8);
- work = ((left >>> 2) ^ right) & 0x33333333;
- right ^= work;
- left ^= (work << 2);
- work = ((right >>> 16) ^ left) & 0x0000ffff;
- left ^= work;
- right ^= (work << 16);
- work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
- left ^= work;
- right ^= (work << 4);
-
- out[outOff + 0] = (byte) ((right >>> 24) & 0xff);
- out[outOff + 1] = (byte) ((right >>> 16) & 0xff);
- out[outOff + 2] = (byte) ((right >>> 8) & 0xff);
- out[outOff + 3] = (byte) (right & 0xff);
- out[outOff + 4] = (byte) ((left >>> 24) & 0xff);
- out[outOff + 5] = (byte) ((left >>> 16) & 0xff);
- out[outOff + 6] = (byte) ((left >>> 8) & 0xff);
- out[outOff + 7] = (byte) (left & 0xff);
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/cipher/DESede.java b/app/src/main/java/com/trilead/ssh2/crypto/cipher/DESede.java
deleted file mode 100644
index f47a636..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/cipher/DESede.java
+++ /dev/null
@@ -1,105 +0,0 @@
-
-package com.trilead.ssh2.crypto.cipher;
-
-/*
- This file was shamelessly taken (and modified) from the Bouncy Castle Crypto package.
- Their licence file states the following:
-
- Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
- (http://www.bouncycastle.org)
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- */
-
-/**
- * DESede.
- *
- * @author See comments in the source file
- * @version $Id: DESede.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- *
- */
-public class DESede extends DES
-{
- private int[] key1 = null;
- private int[] key2 = null;
- private int[] key3 = null;
-
- private boolean encrypt;
-
- /**
- * standard constructor.
- */
- public DESede()
- {
- }
-
- /**
- * initialise a DES cipher.
- *
- * @param encrypting
- * whether or not we are for encryption.
- * @param key
- * the parameters required to set up the cipher.
- * @exception IllegalArgumentException
- * if the params argument is inappropriate.
- */
- public void init(boolean encrypting, byte[] key)
- {
- key1 = generateWorkingKey(encrypting, key, 0);
- key2 = generateWorkingKey(!encrypting, key, 8);
- key3 = generateWorkingKey(encrypting, key, 16);
-
- encrypt = encrypting;
- }
-
- public String getAlgorithmName()
- {
- return "DESede";
- }
-
- public int getBlockSize()
- {
- return 8;
- }
-
- public void transformBlock(byte[] in, int inOff, byte[] out, int outOff)
- {
- if (key1 == null)
- {
- throw new IllegalStateException("DESede engine not initialised!");
- }
-
- if (encrypt)
- {
- desFunc(key1, in, inOff, out, outOff);
- desFunc(key2, out, outOff, out, outOff);
- desFunc(key3, out, outOff, out, outOff);
- }
- else
- {
- desFunc(key3, in, inOff, out, outOff);
- desFunc(key2, out, outOff, out, outOff);
- desFunc(key1, out, outOff, out, outOff);
- }
- }
-
- public void reset()
- {
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/cipher/NullCipher.java b/app/src/main/java/com/trilead/ssh2/crypto/cipher/NullCipher.java
deleted file mode 100644
index 38f8215..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/cipher/NullCipher.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.trilead.ssh2.crypto.cipher;
-
-/**
- * NullCipher.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: NullCipher.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class NullCipher implements BlockCipher
-{
- private int blockSize = 8;
-
- public NullCipher()
- {
- }
-
- public NullCipher(int blockSize)
- {
- this.blockSize = blockSize;
- }
-
- public void init(boolean forEncryption, byte[] key)
- {
- }
-
- public int getBlockSize()
- {
- return blockSize;
- }
-
- public void transformBlock(byte[] src, int srcoff, byte[] dst, int dstoff)
- {
- System.arraycopy(src, srcoff, dst, dstoff, blockSize);
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/dh/DhExchange.java b/app/src/main/java/com/trilead/ssh2/crypto/dh/DhExchange.java
deleted file mode 100644
index 3acde25..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/dh/DhExchange.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- *
- */
-package com.trilead.ssh2.crypto.dh;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.spec.InvalidKeySpecException;
-
-import javax.crypto.KeyAgreement;
-import javax.crypto.interfaces.DHPrivateKey;
-import javax.crypto.interfaces.DHPublicKey;
-import javax.crypto.spec.DHParameterSpec;
-import javax.crypto.spec.DHPublicKeySpec;
-
-/**
- * @author kenny
- *
- */
-public class DhExchange extends GenericDhExchange {
-
- /* Given by the standard */
-
- private static final BigInteger P1 = new BigInteger(
- "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
- + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
- + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
- + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
- + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
- + "FFFFFFFFFFFFFFFF", 16);
-
- private static final BigInteger P14 = new BigInteger(
- "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
- + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
- + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
- + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
- + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
- + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
- + "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
- + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
- + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
- + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
- + "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 16);
-
- private static final BigInteger G = BigInteger.valueOf(2);
-
- /* Client public and private */
-
- private DHPrivateKey clientPrivate;
- private DHPublicKey clientPublic;
-
- /* Server public */
-
- private DHPublicKey serverPublic;
-
- @Override
- public void init(String name) throws IOException {
- final DHParameterSpec spec;
- if ("diffie-hellman-group1-sha1".equals(name)) {
- spec = new DHParameterSpec(P1, G);
- } else if ("diffie-hellman-group14-sha1".equals(name)) {
- spec = new DHParameterSpec(P14, G);
- } else {
- throw new IllegalArgumentException("Unknown DH group " + name);
- }
-
- try {
- KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH");
- kpg.initialize(spec);
- KeyPair pair = kpg.generateKeyPair();
- clientPrivate = (DHPrivateKey) pair.getPrivate();
- clientPublic = (DHPublicKey) pair.getPublic();
- } catch (NoSuchAlgorithmException e) {
- throw (IOException) new IOException("No DH keypair generator").initCause(e);
- } catch (InvalidAlgorithmParameterException e) {
- throw (IOException) new IOException("Invalid DH parameters").initCause(e);
- }
- }
-
- @Override
- public byte[] getE() {
- if (clientPublic == null)
- throw new IllegalStateException("DhExchange not initialized!");
-
- return clientPublic.getY().toByteArray();
- }
-
- @Override
- protected byte[] getServerE() {
- if (serverPublic == null)
- throw new IllegalStateException("DhExchange not initialized!");
-
- return serverPublic.getY().toByteArray();
- }
-
- @Override
- public void setF(byte[] f) throws IOException {
- if (clientPublic == null)
- throw new IllegalStateException("DhExchange not initialized!");
-
- final KeyAgreement ka;
- try {
- KeyFactory kf = KeyFactory.getInstance("DH");
- DHParameterSpec params = clientPublic.getParams();
- this.serverPublic = (DHPublicKey) kf.generatePublic(new DHPublicKeySpec(
- new BigInteger(f), params.getP(), params.getG()));
-
- ka = KeyAgreement.getInstance("DH");
- ka.init(clientPrivate);
- ka.doPhase(serverPublic, true);
- } catch (NoSuchAlgorithmException e) {
- throw (IOException) new IOException("No DH key agreement method").initCause(e);
- } catch (InvalidKeyException e) {
- throw (IOException) new IOException("Invalid DH key").initCause(e);
- } catch (InvalidKeySpecException e) {
- throw (IOException) new IOException("Invalid DH key").initCause(e);
- }
-
- sharedSecret = new BigInteger(ka.generateSecret());
- }
-
- @Override
- public String getHashAlgo() {
- return "SHA1";
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/dh/DhGroupExchange.java b/app/src/main/java/com/trilead/ssh2/crypto/dh/DhGroupExchange.java
deleted file mode 100644
index a888950..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/dh/DhGroupExchange.java
+++ /dev/null
@@ -1,113 +0,0 @@
-
-package com.trilead.ssh2.crypto.dh;
-
-import java.math.BigInteger;
-import java.security.SecureRandom;
-
-import com.trilead.ssh2.DHGexParameters;
-import com.trilead.ssh2.crypto.digest.HashForSSH2Types;
-
-
-/**
- * DhGroupExchange.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: DhGroupExchange.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
- */
-public class DhGroupExchange
-{
- /* Given by the standard */
-
- private BigInteger p;
- private BigInteger g;
-
- /* Client public and private */
-
- private BigInteger e;
- private BigInteger x;
-
- /* Server public */
-
- private BigInteger f;
-
- /* Shared secret */
-
- private BigInteger k;
-
- public DhGroupExchange(BigInteger p, BigInteger g)
- {
- this.p = p;
- this.g = g;
- }
-
- public void init(SecureRandom rnd)
- {
- k = null;
-
- x = new BigInteger(p.bitLength() - 1, rnd);
- e = g.modPow(x, p);
- }
-
- /**
- * @return Returns the e.
- */
- public BigInteger getE()
- {
- if (e == null)
- throw new IllegalStateException("Not initialized!");
-
- return e;
- }
-
- /**
- * @return Returns the shared secret k.
- */
- public BigInteger getK()
- {
- if (k == null)
- throw new IllegalStateException("Shared secret not yet known, need f first!");
-
- return k;
- }
-
- /**
- * Sets f and calculates the shared secret.
- */
- public void setF(BigInteger f)
- {
- if (e == null)
- throw new IllegalStateException("Not initialized!");
-
- BigInteger zero = BigInteger.valueOf(0);
-
- if (zero.compareTo(f) >= 0 || p.compareTo(f) <= 0)
- throw new IllegalArgumentException("Invalid f specified!");
-
- this.f = f;
- this.k = f.modPow(x, p);
- }
-
- public byte[] calculateH(String hashAlgo, byte[] clientversion, byte[] serverversion,
- byte[] clientKexPayload, byte[] serverKexPayload, byte[] hostKey, DHGexParameters para)
- {
- HashForSSH2Types hash = new HashForSSH2Types(hashAlgo);
-
- hash.updateByteString(clientversion);
- hash.updateByteString(serverversion);
- hash.updateByteString(clientKexPayload);
- hash.updateByteString(serverKexPayload);
- hash.updateByteString(hostKey);
- if (para.getMin_group_len() > 0)
- hash.updateUINT32(para.getMin_group_len());
- hash.updateUINT32(para.getPref_group_len());
- if (para.getMax_group_len() > 0)
- hash.updateUINT32(para.getMax_group_len());
- hash.updateBigInt(p);
- hash.updateBigInt(g);
- hash.updateBigInt(e);
- hash.updateBigInt(f);
- hash.updateBigInt(k);
-
- return hash.getDigest();
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/dh/EcDhExchange.java b/app/src/main/java/com/trilead/ssh2/crypto/dh/EcDhExchange.java
deleted file mode 100644
index 870a3b4..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/dh/EcDhExchange.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- *
- */
-package com.trilead.ssh2.crypto.dh;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
-import java.security.spec.ECPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-
-import javax.crypto.KeyAgreement;
-
-import com.trilead.ssh2.signature.ECDSASHA2Verify;
-
-/**
- * @author kenny
- *
- */
-public class EcDhExchange extends GenericDhExchange {
- private ECPrivateKey clientPrivate;
- private ECPublicKey clientPublic;
- private ECPublicKey serverPublic;
-
- @Override
- public void init(String name) throws IOException {
- final ECParameterSpec spec;
-
- if ("ecdh-sha2-nistp256".equals(name)) {
- spec = ECDSASHA2Verify.EllipticCurves.nistp256;
- } else if ("ecdh-sha2-nistp384".equals(name)) {
- spec = ECDSASHA2Verify.EllipticCurves.nistp384;
- } else if ("ecdh-sha2-nistp521".equals(name)) {
- spec = ECDSASHA2Verify.EllipticCurves.nistp521;
- } else {
- throw new IllegalArgumentException("Unknown EC curve " + name);
- }
-
- KeyPairGenerator kpg;
- try {
- kpg = KeyPairGenerator.getInstance("EC");
- kpg.initialize(spec);
- KeyPair pair = kpg.generateKeyPair();
- clientPrivate = (ECPrivateKey) pair.getPrivate();
- clientPublic = (ECPublicKey) pair.getPublic();
- } catch (NoSuchAlgorithmException e) {
- throw (IOException) new IOException("No DH keypair generator").initCause(e);
- } catch (InvalidAlgorithmParameterException e) {
- throw (IOException) new IOException("Invalid DH parameters").initCause(e);
- }
- }
-
- @Override
- public byte[] getE() {
- return ECDSASHA2Verify.encodeECPoint(clientPublic.getW(), clientPublic.getParams()
- .getCurve());
- }
-
- @Override
- protected byte[] getServerE() {
- return ECDSASHA2Verify.encodeECPoint(serverPublic.getW(), serverPublic.getParams()
- .getCurve());
- }
-
- @Override
- public void setF(byte[] f) throws IOException {
-
- if (clientPublic == null)
- throw new IllegalStateException("DhDsaExchange not initialized!");
-
- final KeyAgreement ka;
- try {
- KeyFactory kf = KeyFactory.getInstance("EC");
- ECParameterSpec params = clientPublic.getParams();
- ECPoint serverPoint = ECDSASHA2Verify.decodeECPoint(f, params.getCurve());
- this.serverPublic = (ECPublicKey) kf.generatePublic(new ECPublicKeySpec(serverPoint,
- params));
-
- ka = KeyAgreement.getInstance("ECDH");
- ka.init(clientPrivate);
- ka.doPhase(serverPublic, true);
- } catch (NoSuchAlgorithmException e) {
- throw (IOException) new IOException("No ECDH key agreement method").initCause(e);
- } catch (InvalidKeyException e) {
- throw (IOException) new IOException("Invalid ECDH key").initCause(e);
- } catch (InvalidKeySpecException e) {
- throw (IOException) new IOException("Invalid ECDH key").initCause(e);
- }
-
- sharedSecret = new BigInteger(1, ka.generateSecret());
- }
-
- @Override
- public String getHashAlgo() {
- return ECDSASHA2Verify.getDigestAlgorithmForParams(clientPublic.getParams());
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/dh/GenericDhExchange.java b/app/src/main/java/com/trilead/ssh2/crypto/dh/GenericDhExchange.java
deleted file mode 100644
index 039ff75..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/dh/GenericDhExchange.java
+++ /dev/null
@@ -1,93 +0,0 @@
-
-package com.trilead.ssh2.crypto.dh;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.math.BigInteger;
-
-import com.trilead.ssh2.crypto.digest.HashForSSH2Types;
-import com.trilead.ssh2.log.Logger;
-
-
-/**
- * DhExchange.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: DhExchange.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
- */
-public abstract class GenericDhExchange
-{
- private static final Logger log = Logger.getLogger(GenericDhExchange.class);
-
- /* Shared secret */
-
- BigInteger sharedSecret;
-
- protected GenericDhExchange()
- {
- }
-
- public static GenericDhExchange getInstance(String algo) {
- if (algo.startsWith("ecdh-sha2-")) {
- return new EcDhExchange();
- } else {
- return new DhExchange();
- }
- }
-
- public abstract void init(String name) throws IOException;
-
- /**
- * @return Returns the e (public value)
- * @throws IllegalStateException
- */
- public abstract byte[] getE();
-
- /**
- * @return Returns the server's e (public value)
- * @throws IllegalStateException
- */
- protected abstract byte[] getServerE();
-
- /**
- * @return Returns the shared secret k.
- * @throws IllegalStateException
- */
- public BigInteger getK()
- {
- if (sharedSecret == null)
- throw new IllegalStateException("Shared secret not yet known, need f first!");
-
- return sharedSecret;
- }
-
- /**
- * @param f
- */
- public abstract void setF(byte[] f) throws IOException;
-
- public byte[] calculateH(byte[] clientversion, byte[] serverversion, byte[] clientKexPayload,
- byte[] serverKexPayload, byte[] hostKey) throws UnsupportedEncodingException
- {
- HashForSSH2Types hash = new HashForSSH2Types(getHashAlgo());
-
- if (log.isEnabled())
- {
- log.log(90, "Client: '" + new String(clientversion, "ISO-8859-1") + "'");
- log.log(90, "Server: '" + new String(serverversion, "ISO-8859-1") + "'");
- }
-
- hash.updateByteString(clientversion);
- hash.updateByteString(serverversion);
- hash.updateByteString(clientKexPayload);
- hash.updateByteString(serverKexPayload);
- hash.updateByteString(hostKey);
- hash.updateByteString(getE());
- hash.updateByteString(getServerE());
- hash.updateBigInt(sharedSecret);
-
- return hash.getDigest();
- }
-
- public abstract String getHashAlgo();
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/digest/HashForSSH2Types.java b/app/src/main/java/com/trilead/ssh2/crypto/digest/HashForSSH2Types.java
deleted file mode 100644
index 6b0d6e3..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/digest/HashForSSH2Types.java
+++ /dev/null
@@ -1,91 +0,0 @@
-
-package com.trilead.ssh2.crypto.digest;
-
-import java.math.BigInteger;
-import java.security.DigestException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-/**
- * HashForSSH2Types.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: HashForSSH2Types.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
- */
-public class HashForSSH2Types
-{
- MessageDigest md;
-
- public HashForSSH2Types(String type)
- {
- try {
- md = MessageDigest.getInstance(type);
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException("Unsupported algorithm " + type);
- }
- }
-
- public void updateByte(byte b)
- {
- /* HACK - to test it with J2ME */
- byte[] tmp = new byte[1];
- tmp[0] = b;
- md.update(tmp);
- }
-
- public void updateBytes(byte[] b)
- {
- md.update(b);
- }
-
- public void updateUINT32(int v)
- {
- md.update((byte) (v >> 24));
- md.update((byte) (v >> 16));
- md.update((byte) (v >> 8));
- md.update((byte) (v));
- }
-
- public void updateByteString(byte[] b)
- {
- updateUINT32(b.length);
- updateBytes(b);
- }
-
- public void updateBigInt(BigInteger b)
- {
- updateByteString(b.toByteArray());
- }
-
- public void reset()
- {
- md.reset();
- }
-
- public int getDigestLength()
- {
- return md.getDigestLength();
- }
-
- public byte[] getDigest()
- {
- byte[] tmp = new byte[md.getDigestLength()];
- getDigest(tmp);
- return tmp;
- }
-
- public void getDigest(byte[] out)
- {
- getDigest(out, 0);
- }
-
- public void getDigest(byte[] out, int off)
- {
- try {
- md.digest(out, off, out.length - off);
- } catch (DigestException e) {
- // TODO is this right?!
- throw new RuntimeException("Unable to digest", e);
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/crypto/digest/MAC.java b/app/src/main/java/com/trilead/ssh2/crypto/digest/MAC.java
deleted file mode 100644
index 561599c..0000000
--- a/app/src/main/java/com/trilead/ssh2/crypto/digest/MAC.java
+++ /dev/null
@@ -1,157 +0,0 @@
-
-package com.trilead.ssh2.crypto.digest;
-
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-
-import javax.crypto.Mac;
-import javax.crypto.ShortBufferException;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * MAC.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: MAC.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
- */
-public final class MAC
-{
- /**
- * From http://tools.ietf.org/html/rfc4253
- */
- private static final String HMAC_MD5 = "hmac-md5";
-
- /**
- * From http://tools.ietf.org/html/rfc4253
- */
- private static final String HMAC_MD5_96 = "hmac-md5-96";
-
- /**
- * From http://tools.ietf.org/html/rfc4253
- */
- private static final String HMAC_SHA1 = "hmac-sha1";
-
- /**
- * From http://tools.ietf.org/html/rfc4253
- */
- private static final String HMAC_SHA1_96 = "hmac-sha1-96";
-
- /**
- * From http://tools.ietf.org/html/rfc6668
- */
- private static final String HMAC_SHA2_256 = "hmac-sha2-256";
-
- /**
- * From http://tools.ietf.org/html/rfc6668
- */
- private static final String HMAC_SHA2_512 = "hmac-sha2-512";
-
- Mac mac;
- int outSize;
- int macSize;
- byte[] buffer;
-
- /* Higher Priority First */
- private static final String[] MAC_LIST = {
- HMAC_SHA2_256, HMAC_SHA2_512,
- HMAC_SHA1_96, HMAC_SHA1, HMAC_MD5_96, HMAC_MD5
- };
-
- public final static String[] getMacList()
- {
- return MAC_LIST;
- }
-
- public final static void checkMacList(String[] macs)
- {
- for (int i = 0; i < macs.length; i++)
- getKeyLen(macs[i]);
- }
-
- public final static int getKeyLen(String type)
- {
- if (HMAC_SHA1.equals(type) || HMAC_SHA1_96.equals(type))
- return 20;
- if (HMAC_MD5.equals(type) || HMAC_MD5_96.equals(type))
- return 16;
- if (HMAC_SHA2_256.equals(type))
- return 32;
- if (HMAC_SHA2_512.equals(type))
- return 64;
- throw new IllegalArgumentException("Unkown algorithm " + type);
- }
-
- public MAC(String type, byte[] key)
- {
- try {
- if (HMAC_SHA1.equals(type) || HMAC_SHA1_96.equals(type))
- {
- mac = Mac.getInstance("HmacSHA1");
- }
- else if (HMAC_MD5.equals(type) || HMAC_MD5_96.equals(type))
- {
- mac = Mac.getInstance("HmacMD5");
- }
- else if (HMAC_SHA2_256.equals(type))
- {
- mac = Mac.getInstance("HmacSHA256");
- }
- else if (HMAC_SHA2_512.equals(type))
- {
- mac = Mac.getInstance("HmacSHA512");
- }
- else
- throw new IllegalArgumentException("Unkown algorithm " + type);
- } catch (NoSuchAlgorithmException e) {
- throw new IllegalArgumentException("Unknown algorithm " + type, e);
- }
-
- macSize = mac.getMacLength();
- if (type.endsWith("-96")) {
- outSize = 12;
- buffer = new byte[macSize];
- } else {
- outSize = macSize;
- buffer = null;
- }
-
- try {
- mac.init(new SecretKeySpec(key, type));
- } catch (InvalidKeyException e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- public final void initMac(int seq)
- {
- mac.reset();
- mac.update((byte) (seq >> 24));
- mac.update((byte) (seq >> 16));
- mac.update((byte) (seq >> 8));
- mac.update((byte) (seq));
- }
-
- public final void update(byte[] packetdata, int off, int len)
- {
- mac.update(packetdata, off, len);
- }
-
- public final void getMac(byte[] out, int off)
- {
- try {
- if (buffer != null) {
- mac.doFinal(buffer, 0);
- System.arraycopy(buffer, 0, out, off, out.length - off);
- } else {
- mac.doFinal(out, off);
- }
- } catch (ShortBufferException e) {
- throw new IllegalStateException(e);
- }
- }
-
- public final int size()
- {
- return outSize;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/log/Logger.java b/app/src/main/java/com/trilead/ssh2/log/Logger.java
deleted file mode 100644
index 20ab397..0000000
--- a/app/src/main/java/com/trilead/ssh2/log/Logger.java
+++ /dev/null
@@ -1,54 +0,0 @@
-
-package com.trilead.ssh2.log;
-
-import com.trilead.ssh2.DebugLogger;
-
-/**
- * Logger - a very simple logger, mainly used during development.
- * Is not based on log4j (to reduce external dependencies).
- * However, if needed, something like log4j could easily be
- * hooked in.
- * <p>
- * For speed reasons, the static variables are not protected
- * with semaphores. In other words, if you dynamicaly change the
- * logging settings, then some threads may still use the old setting.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: Logger.java,v 1.2 2008/03/03 07:01:36 cplattne Exp $
- */
-
-public class Logger
-{
- public static boolean enabled = false;
- public static DebugLogger logger = null;
-
- private String className;
-
- public final static Logger getLogger(Class x)
- {
- return new Logger(x);
- }
-
- public Logger(Class x)
- {
- this.className = x.getName();
- }
-
- public final boolean isEnabled()
- {
- return enabled;
- }
-
- public final void log(int level, String message)
- {
- if (!enabled)
- return;
-
- DebugLogger target = logger;
-
- if (target == null)
- return;
-
- target.log(level, className, message);
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketChannelAuthAgentReq.java b/app/src/main/java/com/trilead/ssh2/packets/PacketChannelAuthAgentReq.java
deleted file mode 100644
index 95fa396..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketChannelAuthAgentReq.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.trilead.ssh2.packets;
-
-/**
- * PacketGlobalAuthAgent.
- *
- * @author Kenny Root, kenny@the-b.org
- * @version $Id$
- */
-public class PacketChannelAuthAgentReq
-{
- byte[] payload;
-
- public int recipientChannelID;
-
- public PacketChannelAuthAgentReq(int recipientChannelID)
- {
- this.recipientChannelID = recipientChannelID;
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_CHANNEL_REQUEST);
- tw.writeUINT32(recipientChannelID);
- tw.writeString("auth-agent-req@openssh.com");
- tw.writeBoolean(true); // want reply
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketChannelOpenConfirmation.java b/app/src/main/java/com/trilead/ssh2/packets/PacketChannelOpenConfirmation.java
deleted file mode 100644
index bd2ea3f..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketChannelOpenConfirmation.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-/**
- * PacketChannelOpenConfirmation.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketChannelOpenConfirmation.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketChannelOpenConfirmation
-{
- byte[] payload;
-
- public int recipientChannelID;
- public int senderChannelID;
- public int initialWindowSize;
- public int maxPacketSize;
-
- public PacketChannelOpenConfirmation(int recipientChannelID, int senderChannelID, int initialWindowSize,
- int maxPacketSize)
- {
- this.recipientChannelID = recipientChannelID;
- this.senderChannelID = senderChannelID;
- this.initialWindowSize = initialWindowSize;
- this.maxPacketSize = maxPacketSize;
- }
-
- public PacketChannelOpenConfirmation(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_CHANNEL_OPEN_CONFIRMATION)
- throw new IOException(
- "This is not a SSH_MSG_CHANNEL_OPEN_CONFIRMATION! ("
- + packet_type + ")");
-
- recipientChannelID = tr.readUINT32();
- senderChannelID = tr.readUINT32();
- initialWindowSize = tr.readUINT32();
- maxPacketSize = tr.readUINT32();
-
- if (tr.remain() != 0)
- throw new IOException("Padding in SSH_MSG_CHANNEL_OPEN_CONFIRMATION packet!");
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
- tw.writeUINT32(recipientChannelID);
- tw.writeUINT32(senderChannelID);
- tw.writeUINT32(initialWindowSize);
- tw.writeUINT32(maxPacketSize);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketChannelOpenFailure.java b/app/src/main/java/com/trilead/ssh2/packets/PacketChannelOpenFailure.java
deleted file mode 100644
index 1370355..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketChannelOpenFailure.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-/**
- * PacketChannelOpenFailure.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketChannelOpenFailure.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketChannelOpenFailure
-{
- byte[] payload;
-
- public int recipientChannelID;
- public int reasonCode;
- public String description;
- public String languageTag;
-
- public PacketChannelOpenFailure(int recipientChannelID, int reasonCode, String description,
- String languageTag)
- {
- this.recipientChannelID = recipientChannelID;
- this.reasonCode = reasonCode;
- this.description = description;
- this.languageTag = languageTag;
- }
-
- public PacketChannelOpenFailure(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_CHANNEL_OPEN_FAILURE)
- throw new IOException(
- "This is not a SSH_MSG_CHANNEL_OPEN_FAILURE! ("
- + packet_type + ")");
-
- recipientChannelID = tr.readUINT32();
- reasonCode = tr.readUINT32();
- description = tr.readString();
- languageTag = tr.readString();
-
- if (tr.remain() != 0)
- throw new IOException("Padding in SSH_MSG_CHANNEL_OPEN_FAILURE packet!");
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_CHANNEL_OPEN_FAILURE);
- tw.writeUINT32(recipientChannelID);
- tw.writeUINT32(reasonCode);
- tw.writeString(description);
- tw.writeString(languageTag);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketChannelTrileadPing.java b/app/src/main/java/com/trilead/ssh2/packets/PacketChannelTrileadPing.java
deleted file mode 100644
index c337930..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketChannelTrileadPing.java
+++ /dev/null
@@ -1,35 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-/**
- * PacketChannelTrileadPing.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketChannelTrileadPing.java,v 1.1 2008/03/03 07:01:36
- * cplattne Exp $
- */
-public class PacketChannelTrileadPing
-{
- byte[] payload;
-
- public int recipientChannelID;
-
- public PacketChannelTrileadPing(int recipientChannelID)
- {
- this.recipientChannelID = recipientChannelID;
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_CHANNEL_REQUEST);
- tw.writeUINT32(recipientChannelID);
- tw.writeString("trilead-ping");
- tw.writeBoolean(true);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketChannelWindowAdjust.java b/app/src/main/java/com/trilead/ssh2/packets/PacketChannelWindowAdjust.java
deleted file mode 100644
index 37ec081..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketChannelWindowAdjust.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-/**
- * PacketChannelWindowAdjust.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketChannelWindowAdjust.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketChannelWindowAdjust
-{
- byte[] payload;
-
- public int recipientChannelID;
- public int windowChange;
-
- public PacketChannelWindowAdjust(int recipientChannelID, int windowChange)
- {
- this.recipientChannelID = recipientChannelID;
- this.windowChange = windowChange;
- }
-
- public PacketChannelWindowAdjust(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_CHANNEL_WINDOW_ADJUST)
- throw new IOException(
- "This is not a SSH_MSG_CHANNEL_WINDOW_ADJUST! ("
- + packet_type + ")");
-
- recipientChannelID = tr.readUINT32();
- windowChange = tr.readUINT32();
-
- if (tr.remain() != 0)
- throw new IOException("Padding in SSH_MSG_CHANNEL_WINDOW_ADJUST packet!");
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_CHANNEL_WINDOW_ADJUST);
- tw.writeUINT32(recipientChannelID);
- tw.writeUINT32(windowChange);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketDisconnect.java b/app/src/main/java/com/trilead/ssh2/packets/PacketDisconnect.java
deleted file mode 100644
index 50d6ec2..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketDisconnect.java
+++ /dev/null
@@ -1,57 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-/**
- * PacketDisconnect.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketDisconnect.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
- */
-public class PacketDisconnect
-{
- byte[] payload;
-
- int reason;
- String desc;
- String lang;
-
- public PacketDisconnect(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_DISCONNECT)
- throw new IOException("This is not a Disconnect Packet! (" + packet_type + ")");
-
- reason = tr.readUINT32();
- desc = tr.readString();
- lang = tr.readString();
- }
-
- public PacketDisconnect(int reason, String desc, String lang)
- {
- this.reason = reason;
- this.desc = desc;
- this.lang = lang;
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_DISCONNECT);
- tw.writeUINT32(reason);
- tw.writeString(desc);
- tw.writeString(lang);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketGlobalCancelForwardRequest.java b/app/src/main/java/com/trilead/ssh2/packets/PacketGlobalCancelForwardRequest.java
deleted file mode 100644
index 20bd558..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketGlobalCancelForwardRequest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-/**
- * PacketGlobalCancelForwardRequest.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketGlobalCancelForwardRequest.java,v 1.1 2007/10/15 12:49:55
- * cplattne Exp $
- */
-public class PacketGlobalCancelForwardRequest
-{
- byte[] payload;
-
- public boolean wantReply;
- public String bindAddress;
- public int bindPort;
-
- public PacketGlobalCancelForwardRequest(boolean wantReply, String bindAddress, int bindPort)
- {
- this.wantReply = wantReply;
- this.bindAddress = bindAddress;
- this.bindPort = bindPort;
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_GLOBAL_REQUEST);
-
- tw.writeString("cancel-tcpip-forward");
- tw.writeBoolean(wantReply);
- tw.writeString(bindAddress);
- tw.writeUINT32(bindPort);
-
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketGlobalForwardRequest.java b/app/src/main/java/com/trilead/ssh2/packets/PacketGlobalForwardRequest.java
deleted file mode 100644
index 55257e9..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketGlobalForwardRequest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-/**
- * PacketGlobalForwardRequest.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketGlobalForwardRequest.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketGlobalForwardRequest
-{
- byte[] payload;
-
- public boolean wantReply;
- public String bindAddress;
- public int bindPort;
-
- public PacketGlobalForwardRequest(boolean wantReply, String bindAddress, int bindPort)
- {
- this.wantReply = wantReply;
- this.bindAddress = bindAddress;
- this.bindPort = bindPort;
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_GLOBAL_REQUEST);
-
- tw.writeString("tcpip-forward");
- tw.writeBoolean(wantReply);
- tw.writeString(bindAddress);
- tw.writeUINT32(bindPort);
-
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketGlobalTrileadPing.java b/app/src/main/java/com/trilead/ssh2/packets/PacketGlobalTrileadPing.java
deleted file mode 100644
index 3d8930e..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketGlobalTrileadPing.java
+++ /dev/null
@@ -1,32 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-/**
- * PacketGlobalTrileadPing.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketGlobalTrileadPing.java,v 1.1 2008/03/03 07:01:36 cplattne Exp $
- */
-public class PacketGlobalTrileadPing
-{
- byte[] payload;
-
- public PacketGlobalTrileadPing()
- {
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_GLOBAL_REQUEST);
-
- tw.writeString("trilead-ping");
- tw.writeBoolean(true);
-
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketIgnore.java b/app/src/main/java/com/trilead/ssh2/packets/PacketIgnore.java
deleted file mode 100644
index 2b4d917..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketIgnore.java
+++ /dev/null
@@ -1,59 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-/**
- * PacketIgnore.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketIgnore.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketIgnore
-{
- byte[] payload;
-
- byte[] data;
-
- public void setData(byte[] data)
- {
- this.data = data;
- payload = null;
- }
-
- public PacketIgnore()
- {
- }
-
- public PacketIgnore(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_IGNORE)
- throw new IOException("This is not a SSH_MSG_IGNORE packet! (" + packet_type + ")");
-
- /* Could parse String body */
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_IGNORE);
-
- if (data != null)
- tw.writeString(data, 0, data.length);
- else
- tw.writeString("");
-
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketKexDHInit.java b/app/src/main/java/com/trilead/ssh2/packets/PacketKexDHInit.java
deleted file mode 100644
index 0092516..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketKexDHInit.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.trilead.ssh2.packets;
-
-/**
- * PacketKexDHInit.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketKexDHInit.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketKexDHInit
-{
- byte[] payload;
-
- byte[] publicKey;
-
- public PacketKexDHInit(byte[] publicKey)
- {
- this.publicKey = publicKey;
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_KEXDH_INIT);
- tw.writeString(publicKey, 0, publicKey.length);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketKexDHReply.java b/app/src/main/java/com/trilead/ssh2/packets/PacketKexDHReply.java
deleted file mode 100644
index 51f2bda..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketKexDHReply.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-/**
- * PacketKexDHReply.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketKexDHReply.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketKexDHReply
-{
- byte[] payload;
-
- byte[] hostKey;
- byte[] publicKey;
- byte[] signature;
-
- public PacketKexDHReply(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_KEXDH_REPLY)
- throw new IOException("This is not a SSH_MSG_KEXDH_REPLY! ("
- + packet_type + ")");
-
- hostKey = tr.readByteString();
- publicKey = tr.readByteString();
- signature = tr.readByteString();
-
- if (tr.remain() != 0) throw new IOException("PADDING IN SSH_MSG_KEXDH_REPLY!");
- }
-
- public byte[] getF()
- {
- return publicKey;
- }
-
- public byte[] getHostKey()
- {
- return hostKey;
- }
-
- public byte[] getSignature()
- {
- return signature;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexGroup.java b/app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexGroup.java
deleted file mode 100644
index db85b61..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexGroup.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-import java.math.BigInteger;
-
-/**
- * PacketKexDhGexGroup.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketKexDhGexGroup.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketKexDhGexGroup
-{
- byte[] payload;
-
- BigInteger p;
- BigInteger g;
-
- public PacketKexDhGexGroup(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_KEX_DH_GEX_GROUP)
- throw new IllegalArgumentException(
- "This is not a SSH_MSG_KEX_DH_GEX_GROUP! (" + packet_type
- + ")");
-
- p = tr.readMPINT();
- g = tr.readMPINT();
-
- if (tr.remain() != 0)
- throw new IOException("PADDING IN SSH_MSG_KEX_DH_GEX_GROUP!");
- }
-
- public BigInteger getG()
- {
- return g;
- }
-
- public BigInteger getP()
- {
- return p;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexInit.java b/app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexInit.java
deleted file mode 100644
index 8b34230..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexInit.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.trilead.ssh2.packets;
-
-import java.math.BigInteger;
-
-/**
- * PacketKexDhGexInit.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketKexDhGexInit.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketKexDhGexInit
-{
- byte[] payload;
-
- BigInteger e;
-
- public PacketKexDhGexInit(BigInteger e)
- {
- this.e = e;
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_KEX_DH_GEX_INIT);
- tw.writeMPInt(e);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexReply.java b/app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexReply.java
deleted file mode 100644
index 382b3b7..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexReply.java
+++ /dev/null
@@ -1,56 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-import java.math.BigInteger;
-
-/**
- * PacketKexDhGexReply.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketKexDhGexReply.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketKexDhGexReply
-{
- byte[] payload;
-
- byte[] hostKey;
- BigInteger f;
- byte[] signature;
-
- public PacketKexDhGexReply(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_KEX_DH_GEX_REPLY)
- throw new IOException("This is not a SSH_MSG_KEX_DH_GEX_REPLY! (" + packet_type + ")");
-
- hostKey = tr.readByteString();
- f = tr.readMPINT();
- signature = tr.readByteString();
-
- if (tr.remain() != 0)
- throw new IOException("PADDING IN SSH_MSG_KEX_DH_GEX_REPLY!");
- }
-
- public BigInteger getF()
- {
- return f;
- }
-
- public byte[] getHostKey()
- {
- return hostKey;
- }
-
- public byte[] getSignature()
- {
- return signature;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexRequest.java b/app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexRequest.java
deleted file mode 100644
index 50369df..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexRequest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.trilead.ssh2.packets;
-
-import com.trilead.ssh2.DHGexParameters;
-
-/**
- * PacketKexDhGexRequest.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketKexDhGexRequest.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketKexDhGexRequest
-{
- byte[] payload;
-
- int min;
- int n;
- int max;
-
- public PacketKexDhGexRequest(DHGexParameters para)
- {
- this.min = para.getMin_group_len();
- this.n = para.getPref_group_len();
- this.max = para.getMax_group_len();
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_KEX_DH_GEX_REQUEST);
- tw.writeUINT32(min);
- tw.writeUINT32(n);
- tw.writeUINT32(max);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexRequestOld.java b/app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexRequestOld.java
deleted file mode 100644
index 327f379..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketKexDhGexRequestOld.java
+++ /dev/null
@@ -1,34 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-import com.trilead.ssh2.DHGexParameters;
-
-/**
- * PacketKexDhGexRequestOld.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketKexDhGexRequestOld.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketKexDhGexRequestOld
-{
- byte[] payload;
-
- int n;
-
- public PacketKexDhGexRequestOld(DHGexParameters para)
- {
- this.n = para.getPref_group_len();
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_KEX_DH_GEX_REQUEST_OLD);
- tw.writeUINT32(n);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketKexInit.java b/app/src/main/java/com/trilead/ssh2/packets/PacketKexInit.java
deleted file mode 100644
index 087d658..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketKexInit.java
+++ /dev/null
@@ -1,165 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-import java.security.SecureRandom;
-
-import com.trilead.ssh2.crypto.CryptoWishList;
-import com.trilead.ssh2.transport.KexParameters;
-
-
-/**
- * PacketKexInit.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketKexInit.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketKexInit
-{
- byte[] payload;
-
- KexParameters kp = new KexParameters();
-
- public PacketKexInit(CryptoWishList cwl)
- {
- kp.cookie = new byte[16];
- new SecureRandom().nextBytes(kp.cookie);
-
- kp.kex_algorithms = cwl.kexAlgorithms;
- kp.server_host_key_algorithms = cwl.serverHostKeyAlgorithms;
- kp.encryption_algorithms_client_to_server = cwl.c2s_enc_algos;
- kp.encryption_algorithms_server_to_client = cwl.s2c_enc_algos;
- kp.mac_algorithms_client_to_server = cwl.c2s_mac_algos;
- kp.mac_algorithms_server_to_client = cwl.s2c_mac_algos;
- kp.compression_algorithms_client_to_server = cwl.c2s_comp_algos;
- kp.compression_algorithms_server_to_client = cwl.s2c_comp_algos;
- kp.languages_client_to_server = new String[] {};
- kp.languages_server_to_client = new String[] {};
- kp.first_kex_packet_follows = false;
- kp.reserved_field1 = 0;
- }
-
- public PacketKexInit(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_KEXINIT)
- throw new IOException("This is not a KexInitPacket! (" + packet_type + ")");
-
- kp.cookie = tr.readBytes(16);
- kp.kex_algorithms = tr.readNameList();
- kp.server_host_key_algorithms = tr.readNameList();
- kp.encryption_algorithms_client_to_server = tr.readNameList();
- kp.encryption_algorithms_server_to_client = tr.readNameList();
- kp.mac_algorithms_client_to_server = tr.readNameList();
- kp.mac_algorithms_server_to_client = tr.readNameList();
- kp.compression_algorithms_client_to_server = tr.readNameList();
- kp.compression_algorithms_server_to_client = tr.readNameList();
- kp.languages_client_to_server = tr.readNameList();
- kp.languages_server_to_client = tr.readNameList();
- kp.first_kex_packet_follows = tr.readBoolean();
- kp.reserved_field1 = tr.readUINT32();
-
- if (tr.remain() != 0)
- throw new IOException("Padding in KexInitPacket!");
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_KEXINIT);
- tw.writeBytes(kp.cookie, 0, 16);
- tw.writeNameList(kp.kex_algorithms);
- tw.writeNameList(kp.server_host_key_algorithms);
- tw.writeNameList(kp.encryption_algorithms_client_to_server);
- tw.writeNameList(kp.encryption_algorithms_server_to_client);
- tw.writeNameList(kp.mac_algorithms_client_to_server);
- tw.writeNameList(kp.mac_algorithms_server_to_client);
- tw.writeNameList(kp.compression_algorithms_client_to_server);
- tw.writeNameList(kp.compression_algorithms_server_to_client);
- tw.writeNameList(kp.languages_client_to_server);
- tw.writeNameList(kp.languages_server_to_client);
- tw.writeBoolean(kp.first_kex_packet_follows);
- tw.writeUINT32(kp.reserved_field1);
- payload = tw.getBytes();
- }
- return payload;
- }
-
- public KexParameters getKexParameters()
- {
- return kp;
- }
-
- public String[] getCompression_algorithms_client_to_server()
- {
- return kp.compression_algorithms_client_to_server;
- }
-
- public String[] getCompression_algorithms_server_to_client()
- {
- return kp.compression_algorithms_server_to_client;
- }
-
- public byte[] getCookie()
- {
- return kp.cookie;
- }
-
- public String[] getEncryption_algorithms_client_to_server()
- {
- return kp.encryption_algorithms_client_to_server;
- }
-
- public String[] getEncryption_algorithms_server_to_client()
- {
- return kp.encryption_algorithms_server_to_client;
- }
-
- public boolean isFirst_kex_packet_follows()
- {
- return kp.first_kex_packet_follows;
- }
-
- public String[] getKex_algorithms()
- {
- return kp.kex_algorithms;
- }
-
- public String[] getLanguages_client_to_server()
- {
- return kp.languages_client_to_server;
- }
-
- public String[] getLanguages_server_to_client()
- {
- return kp.languages_server_to_client;
- }
-
- public String[] getMac_algorithms_client_to_server()
- {
- return kp.mac_algorithms_client_to_server;
- }
-
- public String[] getMac_algorithms_server_to_client()
- {
- return kp.mac_algorithms_server_to_client;
- }
-
- public int getReserved_field1()
- {
- return kp.reserved_field1;
- }
-
- public String[] getServer_host_key_algorithms()
- {
- return kp.server_host_key_algorithms;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketNewKeys.java b/app/src/main/java/com/trilead/ssh2/packets/PacketNewKeys.java
deleted file mode 100644
index 3ca6503..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketNewKeys.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-/**
- * PacketNewKeys.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketNewKeys.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketNewKeys
-{
- byte[] payload;
-
- public PacketNewKeys()
- {
- }
-
- public PacketNewKeys(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_NEWKEYS)
- throw new IOException("This is not a SSH_MSG_NEWKEYS! ("
- + packet_type + ")");
-
- if (tr.remain() != 0)
- throw new IOException("Padding in SSH_MSG_NEWKEYS packet!");
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_NEWKEYS);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketOpenDirectTCPIPChannel.java b/app/src/main/java/com/trilead/ssh2/packets/PacketOpenDirectTCPIPChannel.java
deleted file mode 100644
index da6cbef..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketOpenDirectTCPIPChannel.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.trilead.ssh2.packets;
-
-
-/**
- * PacketOpenDirectTCPIPChannel.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketOpenDirectTCPIPChannel.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketOpenDirectTCPIPChannel
-{
- byte[] payload;
-
- int channelID;
- int initialWindowSize;
- int maxPacketSize;
-
- String host_to_connect;
- int port_to_connect;
- String originator_IP_address;
- int originator_port;
-
- public PacketOpenDirectTCPIPChannel(int channelID, int initialWindowSize, int maxPacketSize,
- String host_to_connect, int port_to_connect, String originator_IP_address,
- int originator_port)
- {
- this.channelID = channelID;
- this.initialWindowSize = initialWindowSize;
- this.maxPacketSize = maxPacketSize;
- this.host_to_connect = host_to_connect;
- this.port_to_connect = port_to_connect;
- this.originator_IP_address = originator_IP_address;
- this.originator_port = originator_port;
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
-
- tw.writeByte(Packets.SSH_MSG_CHANNEL_OPEN);
- tw.writeString("direct-tcpip");
- tw.writeUINT32(channelID);
- tw.writeUINT32(initialWindowSize);
- tw.writeUINT32(maxPacketSize);
- tw.writeString(host_to_connect);
- tw.writeUINT32(port_to_connect);
- tw.writeString(originator_IP_address);
- tw.writeUINT32(originator_port);
-
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketOpenSessionChannel.java b/app/src/main/java/com/trilead/ssh2/packets/PacketOpenSessionChannel.java
deleted file mode 100644
index a75ea63..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketOpenSessionChannel.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-/**
- * PacketOpenSessionChannel.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketOpenSessionChannel.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketOpenSessionChannel
-{
- byte[] payload;
-
- int channelID;
- int initialWindowSize;
- int maxPacketSize;
-
- public PacketOpenSessionChannel(int channelID, int initialWindowSize,
- int maxPacketSize)
- {
- this.channelID = channelID;
- this.initialWindowSize = initialWindowSize;
- this.maxPacketSize = maxPacketSize;
- }
-
- public PacketOpenSessionChannel(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_CHANNEL_OPEN)
- throw new IOException("This is not a SSH_MSG_CHANNEL_OPEN! ("
- + packet_type + ")");
-
- channelID = tr.readUINT32();
- initialWindowSize = tr.readUINT32();
- maxPacketSize = tr.readUINT32();
-
- if (tr.remain() != 0)
- throw new IOException("Padding in SSH_MSG_CHANNEL_OPEN packet!");
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_CHANNEL_OPEN);
- tw.writeString("session");
- tw.writeUINT32(channelID);
- tw.writeUINT32(initialWindowSize);
- tw.writeUINT32(maxPacketSize);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketServiceAccept.java b/app/src/main/java/com/trilead/ssh2/packets/PacketServiceAccept.java
deleted file mode 100644
index d5c9a90..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketServiceAccept.java
+++ /dev/null
@@ -1,61 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-/**
- * PacketServiceAccept.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketServiceAccept.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
- */
-public class PacketServiceAccept
-{
- byte[] payload;
-
- String serviceName;
-
- public PacketServiceAccept(String serviceName)
- {
- this.serviceName = serviceName;
- }
-
- public PacketServiceAccept(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_SERVICE_ACCEPT)
- throw new IOException("This is not a SSH_MSG_SERVICE_ACCEPT! (" + packet_type + ")");
-
- /* Be clever in case the server is not. Some servers seem to violate RFC4253 */
-
- if (tr.remain() > 0)
- {
- serviceName = tr.readString();
- }
- else
- {
- serviceName = "";
- }
-
- if (tr.remain() != 0)
- throw new IOException("Padding in SSH_MSG_SERVICE_ACCEPT packet!");
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_SERVICE_ACCEPT);
- tw.writeString(serviceName);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketServiceRequest.java b/app/src/main/java/com/trilead/ssh2/packets/PacketServiceRequest.java
deleted file mode 100644
index c2d2065..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketServiceRequest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-/**
- * PacketServiceRequest.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketServiceRequest.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketServiceRequest
-{
- byte[] payload;
-
- String serviceName;
-
- public PacketServiceRequest(String serviceName)
- {
- this.serviceName = serviceName;
- }
-
- public PacketServiceRequest(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_SERVICE_REQUEST)
- throw new IOException("This is not a SSH_MSG_SERVICE_REQUEST! ("
- + packet_type + ")");
-
- serviceName = tr.readString();
-
- if (tr.remain() != 0)
- throw new IOException("Padding in SSH_MSG_SERVICE_REQUEST packet!");
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_SERVICE_REQUEST);
- tw.writeString(serviceName);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketSessionExecCommand.java b/app/src/main/java/com/trilead/ssh2/packets/PacketSessionExecCommand.java
deleted file mode 100644
index 84efa5d..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketSessionExecCommand.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.trilead.ssh2.packets;
-
-
-/**
- * PacketSessionExecCommand.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketSessionExecCommand.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketSessionExecCommand
-{
- byte[] payload;
-
- public int recipientChannelID;
- public boolean wantReply;
- public String command;
-
- public PacketSessionExecCommand(int recipientChannelID, boolean wantReply, String command)
- {
- this.recipientChannelID = recipientChannelID;
- this.wantReply = wantReply;
- this.command = command;
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_CHANNEL_REQUEST);
- tw.writeUINT32(recipientChannelID);
- tw.writeString("exec");
- tw.writeBoolean(wantReply);
- tw.writeString(command);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketSessionPtyRequest.java b/app/src/main/java/com/trilead/ssh2/packets/PacketSessionPtyRequest.java
deleted file mode 100644
index d9c3d59..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketSessionPtyRequest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.trilead.ssh2.packets;
-
-
-/**
- * PacketSessionPtyRequest.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketSessionPtyRequest.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketSessionPtyRequest
-{
- byte[] payload;
-
- public int recipientChannelID;
- public boolean wantReply;
- public String term;
- public int character_width;
- public int character_height;
- public int pixel_width;
- public int pixel_height;
- public byte[] terminal_modes;
-
- public PacketSessionPtyRequest(int recipientChannelID, boolean wantReply, String term,
- int character_width, int character_height, int pixel_width, int pixel_height,
- byte[] terminal_modes)
- {
- this.recipientChannelID = recipientChannelID;
- this.wantReply = wantReply;
- this.term = term;
- this.character_width = character_width;
- this.character_height = character_height;
- this.pixel_width = pixel_width;
- this.pixel_height = pixel_height;
- this.terminal_modes = terminal_modes;
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_CHANNEL_REQUEST);
- tw.writeUINT32(recipientChannelID);
- tw.writeString("pty-req");
- tw.writeBoolean(wantReply);
- tw.writeString(term);
- tw.writeUINT32(character_width);
- tw.writeUINT32(character_height);
- tw.writeUINT32(pixel_width);
- tw.writeUINT32(pixel_height);
- tw.writeString(terminal_modes, 0, terminal_modes.length);
-
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketSessionPtyResize.java b/app/src/main/java/com/trilead/ssh2/packets/PacketSessionPtyResize.java
deleted file mode 100644
index 1e3b558..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketSessionPtyResize.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.trilead.ssh2.packets;
-
-public class PacketSessionPtyResize {
- byte[] payload;
-
- public int recipientChannelID;
- public int width;
- public int height;
- public int pixelWidth;
- public int pixelHeight;
-
- public PacketSessionPtyResize(int recipientChannelID, int width, int height, int pixelWidth, int pixelHeight) {
- this.recipientChannelID = recipientChannelID;
- this.width = width;
- this.height = height;
- this.pixelWidth = pixelWidth;
- this.pixelHeight = pixelHeight;
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_CHANNEL_REQUEST);
- tw.writeUINT32(recipientChannelID);
- tw.writeString("window-change");
- tw.writeBoolean(false);
- tw.writeUINT32(width);
- tw.writeUINT32(height);
- tw.writeUINT32(pixelWidth);
- tw.writeUINT32(pixelHeight);
-
- payload = tw.getBytes();
- }
- return payload;
- }
-}
-
-
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketSessionStartShell.java b/app/src/main/java/com/trilead/ssh2/packets/PacketSessionStartShell.java
deleted file mode 100644
index e5add01..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketSessionStartShell.java
+++ /dev/null
@@ -1,36 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-/**
- * PacketSessionStartShell.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketSessionStartShell.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketSessionStartShell
-{
- byte[] payload;
-
- public int recipientChannelID;
- public boolean wantReply;
-
- public PacketSessionStartShell(int recipientChannelID, boolean wantReply)
- {
- this.recipientChannelID = recipientChannelID;
- this.wantReply = wantReply;
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_CHANNEL_REQUEST);
- tw.writeUINT32(recipientChannelID);
- tw.writeString("shell");
- tw.writeBoolean(wantReply);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketSessionSubsystemRequest.java b/app/src/main/java/com/trilead/ssh2/packets/PacketSessionSubsystemRequest.java
deleted file mode 100644
index cdc3a8c..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketSessionSubsystemRequest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.trilead.ssh2.packets;
-
-
-/**
- * PacketSessionSubsystemRequest.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketSessionSubsystemRequest.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketSessionSubsystemRequest
-{
- byte[] payload;
-
- public int recipientChannelID;
- public boolean wantReply;
- public String subsystem;
-
- public PacketSessionSubsystemRequest(int recipientChannelID, boolean wantReply, String subsystem)
- {
- this.recipientChannelID = recipientChannelID;
- this.wantReply = wantReply;
- this.subsystem = subsystem;
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_CHANNEL_REQUEST);
- tw.writeUINT32(recipientChannelID);
- tw.writeString("subsystem");
- tw.writeBoolean(wantReply);
- tw.writeString(subsystem);
- payload = tw.getBytes();
- tw.getBytes(payload);
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketSessionX11Request.java b/app/src/main/java/com/trilead/ssh2/packets/PacketSessionX11Request.java
deleted file mode 100644
index 26479c7..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketSessionX11Request.java
+++ /dev/null
@@ -1,53 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-/**
- * PacketSessionX11Request.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketSessionX11Request.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketSessionX11Request
-{
- byte[] payload;
-
- public int recipientChannelID;
- public boolean wantReply;
-
- public boolean singleConnection;
- String x11AuthenticationProtocol;
- String x11AuthenticationCookie;
- int x11ScreenNumber;
-
- public PacketSessionX11Request(int recipientChannelID, boolean wantReply, boolean singleConnection,
- String x11AuthenticationProtocol, String x11AuthenticationCookie, int x11ScreenNumber)
- {
- this.recipientChannelID = recipientChannelID;
- this.wantReply = wantReply;
-
- this.singleConnection = singleConnection;
- this.x11AuthenticationProtocol = x11AuthenticationProtocol;
- this.x11AuthenticationCookie = x11AuthenticationCookie;
- this.x11ScreenNumber = x11ScreenNumber;
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_CHANNEL_REQUEST);
- tw.writeUINT32(recipientChannelID);
- tw.writeString("x11-req");
- tw.writeBoolean(wantReply);
-
- tw.writeBoolean(singleConnection);
- tw.writeString(x11AuthenticationProtocol);
- tw.writeString(x11AuthenticationCookie);
- tw.writeUINT32(x11ScreenNumber);
-
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthBanner.java b/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthBanner.java
deleted file mode 100644
index 8ad8c3b..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthBanner.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-/**
- * PacketUserauthBanner.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketUserauthBanner.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketUserauthBanner
-{
- byte[] payload;
-
- String message;
- String language;
-
- public PacketUserauthBanner(String message, String language)
- {
- this.message = message;
- this.language = language;
- }
-
- public String getBanner()
- {
- return message;
- }
-
- public PacketUserauthBanner(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_USERAUTH_BANNER)
- throw new IOException("This is not a SSH_MSG_USERAUTH_BANNER! (" + packet_type + ")");
-
- message = tr.readString("UTF-8");
- language = tr.readString();
-
- if (tr.remain() != 0)
- throw new IOException("Padding in SSH_MSG_USERAUTH_REQUEST packet!");
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_USERAUTH_BANNER);
- tw.writeString(message);
- tw.writeString(language);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthFailure.java b/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthFailure.java
deleted file mode 100644
index fd4a726..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthFailure.java
+++ /dev/null
@@ -1,53 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-/**
- * PacketUserauthBanner.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketUserauthFailure.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketUserauthFailure
-{
- byte[] payload;
-
- String[] authThatCanContinue;
- boolean partialSuccess;
-
- public PacketUserauthFailure(String[] authThatCanContinue, boolean partialSuccess)
- {
- this.authThatCanContinue = authThatCanContinue;
- this.partialSuccess = partialSuccess;
- }
-
- public PacketUserauthFailure(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_USERAUTH_FAILURE)
- throw new IOException("This is not a SSH_MSG_USERAUTH_FAILURE! (" + packet_type + ")");
-
- authThatCanContinue = tr.readNameList();
- partialSuccess = tr.readBoolean();
-
- if (tr.remain() != 0)
- throw new IOException("Padding in SSH_MSG_USERAUTH_FAILURE packet!");
- }
-
- public String[] getAuthThatCanContinue()
- {
- return authThatCanContinue;
- }
-
- public boolean isPartialSuccess()
- {
- return partialSuccess;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthInfoRequest.java b/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthInfoRequest.java
deleted file mode 100644
index e1606d1..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthInfoRequest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-/**
- * PacketUserauthInfoRequest.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketUserauthInfoRequest.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketUserauthInfoRequest
-{
- byte[] payload;
-
- String name;
- String instruction;
- String languageTag;
- int numPrompts;
-
- String prompt[];
- boolean echo[];
-
- public PacketUserauthInfoRequest(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_USERAUTH_INFO_REQUEST)
- throw new IOException("This is not a SSH_MSG_USERAUTH_INFO_REQUEST! (" + packet_type + ")");
-
- name = tr.readString();
- instruction = tr.readString();
- languageTag = tr.readString();
-
- numPrompts = tr.readUINT32();
-
- prompt = new String[numPrompts];
- echo = new boolean[numPrompts];
-
- for (int i = 0; i < numPrompts; i++)
- {
- prompt[i] = tr.readString();
- echo[i] = tr.readBoolean();
- }
-
- if (tr.remain() != 0)
- throw new IOException("Padding in SSH_MSG_USERAUTH_INFO_REQUEST packet!");
- }
-
- public boolean[] getEcho()
- {
- return echo;
- }
-
- public String getInstruction()
- {
- return instruction;
- }
-
- public String getLanguageTag()
- {
- return languageTag;
- }
-
- public String getName()
- {
- return name;
- }
-
- public int getNumPrompts()
- {
- return numPrompts;
- }
-
- public String[] getPrompt()
- {
- return prompt;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthInfoResponse.java b/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthInfoResponse.java
deleted file mode 100644
index e8795d4..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthInfoResponse.java
+++ /dev/null
@@ -1,35 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-/**
- * PacketUserauthInfoResponse.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketUserauthInfoResponse.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketUserauthInfoResponse
-{
- byte[] payload;
-
- String[] responses;
-
- public PacketUserauthInfoResponse(String[] responses)
- {
- this.responses = responses;
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_USERAUTH_INFO_RESPONSE);
- tw.writeUINT32(responses.length);
- for (int i = 0; i < responses.length; i++)
- tw.writeString(responses[i]);
-
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthRequestInteractive.java b/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthRequestInteractive.java
deleted file mode 100644
index 83e9f49..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthRequestInteractive.java
+++ /dev/null
@@ -1,42 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-/**
- * PacketUserauthRequestInteractive.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketUserauthRequestInteractive.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketUserauthRequestInteractive
-{
- byte[] payload;
-
- String userName;
- String serviceName;
- String[] submethods;
-
- public PacketUserauthRequestInteractive(String serviceName, String user, String[] submethods)
- {
- this.serviceName = serviceName;
- this.userName = user;
- this.submethods = submethods;
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_USERAUTH_REQUEST);
- tw.writeString(userName);
- tw.writeString(serviceName);
- tw.writeString("keyboard-interactive");
- tw.writeString(""); // draft-ietf-secsh-newmodes-04.txt says that
- // the language tag should be empty.
- tw.writeNameList(submethods);
-
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthRequestNone.java b/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthRequestNone.java
deleted file mode 100644
index d786003..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthRequestNone.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-/**
- * PacketUserauthRequestPassword.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketUserauthRequestNone.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketUserauthRequestNone
-{
- byte[] payload;
-
- String userName;
- String serviceName;
-
- public PacketUserauthRequestNone(String serviceName, String user)
- {
- this.serviceName = serviceName;
- this.userName = user;
- }
-
- public PacketUserauthRequestNone(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_USERAUTH_REQUEST)
- throw new IOException("This is not a SSH_MSG_USERAUTH_REQUEST! (" + packet_type + ")");
-
- userName = tr.readString();
- serviceName = tr.readString();
-
- String method = tr.readString();
-
- if (method.equals("none") == false)
- throw new IOException("This is not a SSH_MSG_USERAUTH_REQUEST with type none!");
-
- if (tr.remain() != 0)
- throw new IOException("Padding in SSH_MSG_USERAUTH_REQUEST packet!");
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_USERAUTH_REQUEST);
- tw.writeString(userName);
- tw.writeString(serviceName);
- tw.writeString("none");
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthRequestPassword.java b/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthRequestPassword.java
deleted file mode 100644
index 83047dd..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthRequestPassword.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-/**
- * PacketUserauthRequestPassword.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketUserauthRequestPassword.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketUserauthRequestPassword
-{
- byte[] payload;
-
- String userName;
- String serviceName;
- String password;
-
- public PacketUserauthRequestPassword(String serviceName, String user, String pass)
- {
- this.serviceName = serviceName;
- this.userName = user;
- this.password = pass;
- }
-
- public PacketUserauthRequestPassword(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_USERAUTH_REQUEST)
- throw new IOException("This is not a SSH_MSG_USERAUTH_REQUEST! (" + packet_type + ")");
-
- userName = tr.readString();
- serviceName = tr.readString();
-
- String method = tr.readString();
-
- if (method.equals("password") == false)
- throw new IOException("This is not a SSH_MSG_USERAUTH_REQUEST with type password!");
-
- /* ... */
-
- if (tr.remain() != 0)
- throw new IOException("Padding in SSH_MSG_USERAUTH_REQUEST packet!");
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_USERAUTH_REQUEST);
- tw.writeString(userName);
- tw.writeString(serviceName);
- tw.writeString("password");
- tw.writeBoolean(false);
- tw.writeString(password);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthRequestPublicKey.java b/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthRequestPublicKey.java
deleted file mode 100644
index 6462864..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/PacketUserauthRequestPublicKey.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-
-/**
- * PacketUserauthRequestPublicKey.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: PacketUserauthRequestPublicKey.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class PacketUserauthRequestPublicKey
-{
- byte[] payload;
-
- String userName;
- String serviceName;
- String password;
- String pkAlgoName;
- byte[] pk;
- byte[] sig;
-
- public PacketUserauthRequestPublicKey(String serviceName, String user,
- String pkAlgorithmName, byte[] pk, byte[] sig)
- {
- this.serviceName = serviceName;
- this.userName = user;
- this.pkAlgoName = pkAlgorithmName;
- this.pk = pk;
- this.sig = sig;
- }
-
- public PacketUserauthRequestPublicKey(byte payload[], int off, int len) throws IOException
- {
- this.payload = new byte[len];
- System.arraycopy(payload, off, this.payload, 0, len);
-
- TypesReader tr = new TypesReader(payload, off, len);
-
- int packet_type = tr.readByte();
-
- if (packet_type != Packets.SSH_MSG_USERAUTH_REQUEST)
- throw new IOException("This is not a SSH_MSG_USERAUTH_REQUEST! ("
- + packet_type + ")");
-
- throw new IOException("Not implemented!");
- }
-
- public byte[] getPayload()
- {
- if (payload == null)
- {
- TypesWriter tw = new TypesWriter();
- tw.writeByte(Packets.SSH_MSG_USERAUTH_REQUEST);
- tw.writeString(userName);
- tw.writeString(serviceName);
- tw.writeString("publickey");
- tw.writeBoolean(true);
- tw.writeString(pkAlgoName);
- tw.writeString(pk, 0, pk.length);
- tw.writeString(sig, 0, sig.length);
- payload = tw.getBytes();
- }
- return payload;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/Packets.java b/app/src/main/java/com/trilead/ssh2/packets/Packets.java
deleted file mode 100644
index 6989286..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/Packets.java
+++ /dev/null
@@ -1,149 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-/**
- * Packets.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: Packets.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class Packets
-{
- public static final int SSH_MSG_DISCONNECT = 1;
- public static final int SSH_MSG_IGNORE = 2;
- public static final int SSH_MSG_UNIMPLEMENTED = 3;
- public static final int SSH_MSG_DEBUG = 4;
- public static final int SSH_MSG_SERVICE_REQUEST = 5;
- public static final int SSH_MSG_SERVICE_ACCEPT = 6;
-
- public static final int SSH_MSG_KEXINIT = 20;
- public static final int SSH_MSG_NEWKEYS = 21;
-
- public static final int SSH_MSG_KEXDH_INIT = 30;
- public static final int SSH_MSG_KEXDH_REPLY = 31;
-
- public static final int SSH_MSG_KEX_DH_GEX_REQUEST_OLD = 30;
- public static final int SSH_MSG_KEX_DH_GEX_REQUEST = 34;
- public static final int SSH_MSG_KEX_DH_GEX_GROUP = 31;
- public static final int SSH_MSG_KEX_DH_GEX_INIT = 32;
- public static final int SSH_MSG_KEX_DH_GEX_REPLY = 33;
-
- public static final int SSH_MSG_USERAUTH_REQUEST = 50;
- public static final int SSH_MSG_USERAUTH_FAILURE = 51;
- public static final int SSH_MSG_USERAUTH_SUCCESS = 52;
- public static final int SSH_MSG_USERAUTH_BANNER = 53;
- public static final int SSH_MSG_USERAUTH_INFO_REQUEST = 60;
- public static final int SSH_MSG_USERAUTH_INFO_RESPONSE = 61;
-
- public static final int SSH_MSG_GLOBAL_REQUEST = 80;
- public static final int SSH_MSG_REQUEST_SUCCESS = 81;
- public static final int SSH_MSG_REQUEST_FAILURE = 82;
-
- public static final int SSH_MSG_CHANNEL_OPEN = 90;
- public static final int SSH_MSG_CHANNEL_OPEN_CONFIRMATION = 91;
- public static final int SSH_MSG_CHANNEL_OPEN_FAILURE = 92;
- public static final int SSH_MSG_CHANNEL_WINDOW_ADJUST = 93;
- public static final int SSH_MSG_CHANNEL_DATA = 94;
- public static final int SSH_MSG_CHANNEL_EXTENDED_DATA = 95;
- public static final int SSH_MSG_CHANNEL_EOF = 96;
- public static final int SSH_MSG_CHANNEL_CLOSE = 97;
- public static final int SSH_MSG_CHANNEL_REQUEST = 98;
- public static final int SSH_MSG_CHANNEL_SUCCESS = 99;
- public static final int SSH_MSG_CHANNEL_FAILURE = 100;
-
- public static final int SSH_EXTENDED_DATA_STDERR = 1;
-
- public static final int SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT = 1;
- public static final int SSH_DISCONNECT_PROTOCOL_ERROR = 2;
- public static final int SSH_DISCONNECT_KEY_EXCHANGE_FAILED = 3;
- public static final int SSH_DISCONNECT_RESERVED = 4;
- public static final int SSH_DISCONNECT_MAC_ERROR = 5;
- public static final int SSH_DISCONNECT_COMPRESSION_ERROR = 6;
- public static final int SSH_DISCONNECT_SERVICE_NOT_AVAILABLE = 7;
- public static final int SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED = 8;
- public static final int SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE = 9;
- public static final int SSH_DISCONNECT_CONNECTION_LOST = 10;
- public static final int SSH_DISCONNECT_BY_APPLICATION = 11;
- public static final int SSH_DISCONNECT_TOO_MANY_CONNECTIONS = 12;
- public static final int SSH_DISCONNECT_AUTH_CANCELLED_BY_USER = 13;
- public static final int SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE = 14;
- public static final int SSH_DISCONNECT_ILLEGAL_USER_NAME = 15;
-
- public static final int SSH_OPEN_ADMINISTRATIVELY_PROHIBITED = 1;
- public static final int SSH_OPEN_CONNECT_FAILED = 2;
- public static final int SSH_OPEN_UNKNOWN_CHANNEL_TYPE = 3;
- public static final int SSH_OPEN_RESOURCE_SHORTAGE = 4;
-
- private static final String[] reverseNames = new String[101];
-
- static
- {
- reverseNames[1] = "SSH_MSG_DISCONNECT";
- reverseNames[2] = "SSH_MSG_IGNORE";
- reverseNames[3] = "SSH_MSG_UNIMPLEMENTED";
- reverseNames[4] = "SSH_MSG_DEBUG";
- reverseNames[5] = "SSH_MSG_SERVICE_REQUEST";
- reverseNames[6] = "SSH_MSG_SERVICE_ACCEPT";
-
- reverseNames[20] = "SSH_MSG_KEXINIT";
- reverseNames[21] = "SSH_MSG_NEWKEYS";
-
- reverseNames[30] = "SSH_MSG_KEXDH_INIT";
- reverseNames[31] = "SSH_MSG_KEXDH_REPLY/SSH_MSG_KEX_DH_GEX_GROUP";
- reverseNames[32] = "SSH_MSG_KEX_DH_GEX_INIT";
- reverseNames[33] = "SSH_MSG_KEX_DH_GEX_REPLY";
- reverseNames[34] = "SSH_MSG_KEX_DH_GEX_REQUEST";
-
- reverseNames[50] = "SSH_MSG_USERAUTH_REQUEST";
- reverseNames[51] = "SSH_MSG_USERAUTH_FAILURE";
- reverseNames[52] = "SSH_MSG_USERAUTH_SUCCESS";
- reverseNames[53] = "SSH_MSG_USERAUTH_BANNER";
-
- reverseNames[60] = "SSH_MSG_USERAUTH_INFO_REQUEST";
- reverseNames[61] = "SSH_MSG_USERAUTH_INFO_RESPONSE";
-
- reverseNames[80] = "SSH_MSG_GLOBAL_REQUEST";
- reverseNames[81] = "SSH_MSG_REQUEST_SUCCESS";
- reverseNames[82] = "SSH_MSG_REQUEST_FAILURE";
-
- reverseNames[90] = "SSH_MSG_CHANNEL_OPEN";
- reverseNames[91] = "SSH_MSG_CHANNEL_OPEN_CONFIRMATION";
- reverseNames[92] = "SSH_MSG_CHANNEL_OPEN_FAILURE";
- reverseNames[93] = "SSH_MSG_CHANNEL_WINDOW_ADJUST";
- reverseNames[94] = "SSH_MSG_CHANNEL_DATA";
- reverseNames[95] = "SSH_MSG_CHANNEL_EXTENDED_DATA";
- reverseNames[96] = "SSH_MSG_CHANNEL_EOF";
- reverseNames[97] = "SSH_MSG_CHANNEL_CLOSE";
- reverseNames[98] = "SSH_MSG_CHANNEL_REQUEST";
- reverseNames[99] = "SSH_MSG_CHANNEL_SUCCESS";
- reverseNames[100] = "SSH_MSG_CHANNEL_FAILURE";
- }
-
- public static final String getMessageName(int type)
- {
- String res = null;
-
- if ((type >= 0) && (type < reverseNames.length))
- {
- res = reverseNames[type];
- }
-
- return (res == null) ? ("UNKNOWN MSG " + type) : res;
- }
-
- // public static final void debug(String tag, byte[] msg)
- // {
- // System.err.println(tag + " Type: " + msg[0] + ", LEN: " + msg.length);
- //
- // for (int i = 0; i < msg.length; i++)
- // {
- // if (((msg[i] >= 'a') && (msg[i] <= 'z')) || ((msg[i] >= 'A') && (msg[i] <= 'Z'))
- // || ((msg[i] >= '0') && (msg[i] <= '9')) || (msg[i] == ' '))
- // System.err.print((char) msg[i]);
- // else
- // System.err.print(".");
- // }
- // System.err.println();
- // System.err.flush();
- // }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/TypesReader.java b/app/src/main/java/com/trilead/ssh2/packets/TypesReader.java
deleted file mode 100644
index 28f5363..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/TypesReader.java
+++ /dev/null
@@ -1,177 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-import java.io.IOException;
-import java.math.BigInteger;
-
-import com.trilead.ssh2.util.Tokenizer;
-
-
-/**
- * TypesReader.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: TypesReader.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
- */
-public class TypesReader
-{
- byte[] arr;
- int pos = 0;
- int max = 0;
-
- public TypesReader(byte[] arr)
- {
- this.arr = arr;
- pos = 0;
- max = arr.length;
- }
-
- public TypesReader(byte[] arr, int off)
- {
- this.arr = arr;
- this.pos = off;
- this.max = arr.length;
-
- if ((pos < 0) || (pos > arr.length))
- throw new IllegalArgumentException("Illegal offset.");
- }
-
- public TypesReader(byte[] arr, int off, int len)
- {
- this.arr = arr;
- this.pos = off;
- this.max = off + len;
-
- if ((pos < 0) || (pos > arr.length))
- throw new IllegalArgumentException("Illegal offset.");
-
- if ((max < 0) || (max > arr.length))
- throw new IllegalArgumentException("Illegal length.");
- }
-
- public int readByte() throws IOException
- {
- if (pos >= max)
- throw new IOException("Packet too short.");
-
- return (arr[pos++] & 0xff);
- }
-
- public byte[] readBytes(int len) throws IOException
- {
- if ((pos + len) > max)
- throw new IOException("Packet too short.");
-
- byte[] res = new byte[len];
-
- System.arraycopy(arr, pos, res, 0, len);
- pos += len;
-
- return res;
- }
-
- public void readBytes(byte[] dst, int off, int len) throws IOException
- {
- if ((pos + len) > max)
- throw new IOException("Packet too short.");
-
- System.arraycopy(arr, pos, dst, off, len);
- pos += len;
- }
-
- public boolean readBoolean() throws IOException
- {
- if (pos >= max)
- throw new IOException("Packet too short.");
-
- return (arr[pos++] != 0);
- }
-
- public int readUINT32() throws IOException
- {
- if ((pos + 4) > max)
- throw new IOException("Packet too short.");
-
- return ((arr[pos++] & 0xff) << 24) | ((arr[pos++] & 0xff) << 16) | ((arr[pos++] & 0xff) << 8)
- | (arr[pos++] & 0xff);
- }
-
- public long readUINT64() throws IOException
- {
- if ((pos + 8) > max)
- throw new IOException("Packet too short.");
-
- long high = ((arr[pos++] & 0xff) << 24) | ((arr[pos++] & 0xff) << 16) | ((arr[pos++] & 0xff) << 8)
- | (arr[pos++] & 0xff); /* sign extension may take place - will be shifted away =) */
-
- long low = ((arr[pos++] & 0xff) << 24) | ((arr[pos++] & 0xff) << 16) | ((arr[pos++] & 0xff) << 8)
- | (arr[pos++] & 0xff); /* sign extension may take place - handle below */
-
- return (high << 32) | (low & 0xffffffffl); /* see Java language spec (15.22.1, 5.6.2) */
- }
-
- public BigInteger readMPINT() throws IOException
- {
- BigInteger b;
-
- byte raw[] = readByteString();
-
- if (raw.length == 0)
- b = BigInteger.ZERO;
- else
- b = new BigInteger(raw);
-
- return b;
- }
-
- public byte[] readByteString() throws IOException
- {
- int len = readUINT32();
-
- if ((len + pos) > max)
- throw new IOException("Malformed SSH byte string.");
-
- byte[] res = new byte[len];
- System.arraycopy(arr, pos, res, 0, len);
- pos += len;
- return res;
- }
-
- public String readString(String charsetName) throws IOException
- {
- int len = readUINT32();
-
- if ((len + pos) > max)
- throw new IOException("Malformed SSH string.");
-
- String res = (charsetName == null) ? new String(arr, pos, len) : new String(arr, pos, len, charsetName);
- pos += len;
-
- return res;
- }
-
- public String readString() throws IOException
- {
- int len = readUINT32();
-
- if ((len + pos) > max)
- throw new IOException("Malformed SSH string.");
-
- String res = new String(arr, pos, len, "ISO-8859-1");
-
- pos += len;
-
- return res;
- }
-
- public String[] readNameList() throws IOException
- {
- return Tokenizer.parseTokens(readString(), ',');
- }
-
- public int remain()
- {
- return max - pos;
- }
-
-}
diff --git a/app/src/main/java/com/trilead/ssh2/packets/TypesWriter.java b/app/src/main/java/com/trilead/ssh2/packets/TypesWriter.java
deleted file mode 100644
index 9f7336b..0000000
--- a/app/src/main/java/com/trilead/ssh2/packets/TypesWriter.java
+++ /dev/null
@@ -1,169 +0,0 @@
-
-package com.trilead.ssh2.packets;
-
-import java.io.UnsupportedEncodingException;
-import java.math.BigInteger;
-
-/**
- * TypesWriter.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: TypesWriter.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
- */
-public class TypesWriter
-{
- byte arr[];
- int pos;
-
- public TypesWriter()
- {
- arr = new byte[256];
- pos = 0;
- }
-
- private void resize(int len)
- {
- byte new_arr[] = new byte[len];
- System.arraycopy(arr, 0, new_arr, 0, arr.length);
- arr = new_arr;
- }
-
- public int length()
- {
- return pos;
- }
-
- public byte[] getBytes()
- {
- byte[] dst = new byte[pos];
- System.arraycopy(arr, 0, dst, 0, pos);
- return dst;
- }
-
- public void getBytes(byte dst[])
- {
- System.arraycopy(arr, 0, dst, 0, pos);
- }
-
- public void writeUINT32(int val, int off)
- {
- if ((off + 4) > arr.length)
- resize(off + 32);
-
- arr[off++] = (byte) (val >> 24);
- arr[off++] = (byte) (val >> 16);
- arr[off++] = (byte) (val >> 8);
- arr[off++] = (byte) val;
- }
-
- public void writeUINT32(int val)
- {
- writeUINT32(val, pos);
- pos += 4;
- }
-
- public void writeUINT64(long val)
- {
- if ((pos + 8) > arr.length)
- resize(arr.length + 32);
-
- arr[pos++] = (byte) (val >> 56);
- arr[pos++] = (byte) (val >> 48);
- arr[pos++] = (byte) (val >> 40);
- arr[pos++] = (byte) (val >> 32);
- arr[pos++] = (byte) (val >> 24);
- arr[pos++] = (byte) (val >> 16);
- arr[pos++] = (byte) (val >> 8);
- arr[pos++] = (byte) val;
- }
-
- public void writeBoolean(boolean v)
- {
- if ((pos + 1) > arr.length)
- resize(arr.length + 32);
-
- arr[pos++] = v ? (byte) 1 : (byte) 0;
- }
-
- public void writeByte(int v, int off)
- {
- if ((off + 1) > arr.length)
- resize(off + 32);
-
- arr[off] = (byte) v;
- }
-
- public void writeByte(int v)
- {
- writeByte(v, pos);
- pos++;
- }
-
- public void writeMPInt(BigInteger b)
- {
- byte raw[] = b.toByteArray();
-
- if ((raw.length == 1) && (raw[0] == 0))
- writeUINT32(0); /* String with zero bytes of data */
- else
- writeString(raw, 0, raw.length);
- }
-
- public void writeBytes(byte[] buff)
- {
- writeBytes(buff, 0, buff.length);
- }
-
- public void writeBytes(byte[] buff, int off, int len)
- {
- if ((pos + len) > arr.length)
- resize(arr.length + len + 32);
-
- System.arraycopy(buff, off, arr, pos, len);
- pos += len;
- }
-
- public void writeString(byte[] buff, int off, int len)
- {
- writeUINT32(len);
- writeBytes(buff, off, len);
- }
-
- public void writeString(String v)
- {
- byte[] b;
-
- try
- {
- /* All Java JVMs must support ISO-8859-1 */
- b = v.getBytes("ISO-8859-1");
- }
- catch (UnsupportedEncodingException ignore)
- {
- b = v.getBytes();
- }
-
- writeUINT32(b.length);
- writeBytes(b, 0, b.length);
- }
-
- public void writeString(String v, String charsetName) throws UnsupportedEncodingException
- {
- byte[] b = (charsetName == null) ? v.getBytes() : v.getBytes(charsetName);
-
- writeUINT32(b.length);
- writeBytes(b, 0, b.length);
- }
-
- public void writeNameList(String v[])
- {
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < v.length; i++)
- {
- if (i > 0)
- sb.append(',');
- sb.append(v[i]);
- }
- writeString(sb.toString());
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/sftp/AttrTextHints.java b/app/src/main/java/com/trilead/ssh2/sftp/AttrTextHints.java
deleted file mode 100644
index 19f0525..0000000
--- a/app/src/main/java/com/trilead/ssh2/sftp/AttrTextHints.java
+++ /dev/null
@@ -1,38 +0,0 @@
-
-package com.trilead.ssh2.sftp;
-
-/**
- *
- * Values for the 'text-hint' field in the SFTP ATTRS data type.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: AttrTextHints.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- *
- */
-public class AttrTextHints
-{
- /**
- * The server knows the file is a text file, and should be opened
- * using the SSH_FXF_ACCESS_TEXT_MODE flag.
- */
- public static final int SSH_FILEXFER_ATTR_KNOWN_TEXT = 0x00;
-
- /**
- * The server has applied a heuristic or other mechanism and
- * believes that the file should be opened with the
- * SSH_FXF_ACCESS_TEXT_MODE flag.
- */
- public static final int SSH_FILEXFER_ATTR_GUESSED_TEXT = 0x01;
-
- /**
- * The server knows the file has binary content.
- */
- public static final int SSH_FILEXFER_ATTR_KNOWN_BINARY = 0x02;
-
- /**
- * The server has applied a heuristic or other mechanism and
- * believes has binary content, and should not be opened with the
- * SSH_FXF_ACCESS_TEXT_MODE flag.
- */
- public static final int SSH_FILEXFER_ATTR_GUESSED_BINARY = 0x03;
-}
diff --git a/app/src/main/java/com/trilead/ssh2/sftp/AttribBits.java b/app/src/main/java/com/trilead/ssh2/sftp/AttribBits.java
deleted file mode 100644
index b143613..0000000
--- a/app/src/main/java/com/trilead/ssh2/sftp/AttribBits.java
+++ /dev/null
@@ -1,129 +0,0 @@
-
-package com.trilead.ssh2.sftp;
-
-/**
- *
- * SFTP Attribute Bits for the "attrib-bits" and "attrib-bits-valid" fields
- * of the SFTP ATTR data type.
- * <p>
- * Yes, these are the "attrib-bits", even though they have "_FLAGS_" in
- * their name. Don't ask - I did not invent it.
- * <p>
- * "<i>These fields, taken together, reflect various attributes of the file
- * or directory, on the server. Bits not set in 'attrib-bits-valid' MUST be
- * ignored in the 'attrib-bits' field. This allows both the server and the
- * client to communicate only the bits it knows about without inadvertently
- * twiddling bits they don't understand.</i>"
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: AttribBits.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- *
- */
-public class AttribBits
-{
- /**
- * Advisory, read-only bit. This bit is not part of the access
- * control information on the file, but is rather an advisory field
- * indicating that the file should not be written.
- */
- public static final int SSH_FILEXFER_ATTR_FLAGS_READONLY = 0x00000001;
-
- /**
- * The file is part of the operating system.
- */
- public static final int SSH_FILEXFER_ATTR_FLAGS_SYSTEM = 0x00000002;
-
- /**
- * File SHOULD NOT be shown to user unless specifically requested.
- * For example, most UNIX systems SHOULD set this bit if the filename
- * begins with a 'period'. This bit may be read-only (see section 5.4 of
- * the SFTP standard draft). Most UNIX systems will not allow this to be
- * changed.
- */
- public static final int SSH_FILEXFER_ATTR_FLAGS_HIDDEN = 0x00000004;
-
- /**
- * This attribute applies only to directories. This attribute is
- * always read-only, and cannot be modified. This attribute means
- * that files and directory names in this directory should be compared
- * without regard to case.
- * <p>
- * It is recommended that where possible, the server's filesystem be
- * allowed to do comparisons. For example, if a client wished to prompt
- * a user before overwriting a file, it should not compare the new name
- * with the previously retrieved list of names in the directory. Rather,
- * it should first try to create the new file by specifying
- * SSH_FXF_CREATE_NEW flag. Then, if this fails and returns
- * SSH_FX_FILE_ALREADY_EXISTS, it should prompt the user and then retry
- * the create specifying SSH_FXF_CREATE_TRUNCATE.
- * <p>
- * Unless otherwise specified, filenames are assumed to be case sensitive.
- */
- public static final int SSH_FILEXFER_ATTR_FLAGS_CASE_INSENSITIVE = 0x00000008;
-
- /**
- * The file should be included in backup / archive operations.
- */
- public static final int SSH_FILEXFER_ATTR_FLAGS_ARCHIVE = 0x00000010;
-
- /**
- * The file is stored on disk using file-system level transparent
- * encryption. This flag does not affect the file data on the wire
- * (for either READ or WRITE requests.)
- */
- public static final int SSH_FILEXFER_ATTR_FLAGS_ENCRYPTED = 0x00000020;
-
- /**
- * The file is stored on disk using file-system level transparent
- * compression. This flag does not affect the file data on the wire.
- */
- public static final int SSH_FILEXFER_ATTR_FLAGS_COMPRESSED = 0x00000040;
-
- /**
- * The file is a sparse file; this means that file blocks that have
- * not been explicitly written are not stored on disk. For example, if
- * a client writes a buffer at 10 M from the beginning of the file,
- * the blocks between the previous EOF marker and the 10 M offset would
- * not consume physical disk space.
- * <p>
- * Some servers may store all files as sparse files, in which case
- * this bit will be unconditionally set. Other servers may not have
- * a mechanism for determining if the file is sparse, and so the file
- * MAY be stored sparse even if this flag is not set.
- */
- public static final int SSH_FILEXFER_ATTR_FLAGS_SPARSE = 0x00000080;
-
- /**
- * Opening the file without either the SSH_FXF_ACCESS_APPEND_DATA or
- * the SSH_FXF_ACCESS_APPEND_DATA_ATOMIC flag (see section 8.1.1.3
- * of the SFTP standard draft) MUST result in an
- * SSH_FX_INVALID_PARAMETER error.
- */
- public static final int SSH_FILEXFER_ATTR_FLAGS_APPEND_ONLY = 0x00000100;
-
- /**
- * The file cannot be deleted or renamed, no hard link can be created
- * to this file, and no data can be written to the file.
- * <p>
- * This bit implies a stronger level of protection than
- * SSH_FILEXFER_ATTR_FLAGS_READONLY, the file permission mask or ACLs.
- * Typically even the superuser cannot write to immutable files, and
- * only the superuser can set or remove the bit.
- */
- public static final int SSH_FILEXFER_ATTR_FLAGS_IMMUTABLE = 0x00000200;
-
- /**
- * When the file is modified, the changes are written synchronously
- * to the disk.
- */
- public static final int SSH_FILEXFER_ATTR_FLAGS_SYNC = 0x00000400;
-
- /**
- * The server MAY include this bit in a directory listing or realpath
- * response. It indicates there was a failure in the translation to UTF-8.
- * If this flag is included, the server SHOULD also include the
- * UNTRANSLATED_NAME attribute.
- */
- public static final int SSH_FILEXFER_ATTR_FLAGS_TRANSLATION_ERR = 0x00000800;
-
-}
diff --git a/app/src/main/java/com/trilead/ssh2/sftp/AttribFlags.java b/app/src/main/java/com/trilead/ssh2/sftp/AttribFlags.java
deleted file mode 100644
index ea27871..0000000
--- a/app/src/main/java/com/trilead/ssh2/sftp/AttribFlags.java
+++ /dev/null
@@ -1,112 +0,0 @@
-
-package com.trilead.ssh2.sftp;
-
-/**
- *
- * Attribute Flags. The 'valid-attribute-flags' field in
- * the SFTP ATTRS data type specifies which of the fields are actually present.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: AttribFlags.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- *
- */
-public class AttribFlags
-{
- /**
- * Indicates that the 'allocation-size' field is present.
- */
- public static final int SSH_FILEXFER_ATTR_SIZE = 0x00000001;
-
- /** Protocol version 6:
- * 0x00000002 was used in a previous version of this protocol.
- * It is now a reserved value and MUST NOT appear in the mask.
- * Some future version of this protocol may reuse this value.
- */
- public static final int SSH_FILEXFER_ATTR_V3_UIDGID = 0x00000002;
-
- /**
- * Indicates that the 'permissions' field is present.
- */
- public static final int SSH_FILEXFER_ATTR_PERMISSIONS = 0x00000004;
-
- /**
- * Indicates that the 'atime' and 'mtime' field are present
- * (protocol v3).
- */
- public static final int SSH_FILEXFER_ATTR_V3_ACMODTIME = 0x00000008;
-
- /**
- * Indicates that the 'atime' field is present.
- */
- public static final int SSH_FILEXFER_ATTR_ACCESSTIME = 0x00000008;
-
- /**
- * Indicates that the 'createtime' field is present.
- */
- public static final int SSH_FILEXFER_ATTR_CREATETIME = 0x00000010;
-
- /**
- * Indicates that the 'mtime' field is present.
- */
- public static final int SSH_FILEXFER_ATTR_MODIFYTIME = 0x00000020;
-
- /**
- * Indicates that the 'acl' field is present.
- */
- public static final int SSH_FILEXFER_ATTR_ACL = 0x00000040;
-
- /**
- * Indicates that the 'owner' and 'group' fields are present.
- */
- public static final int SSH_FILEXFER_ATTR_OWNERGROUP = 0x00000080;
-
- /**
- * Indicates that additionally to the 'atime', 'createtime',
- * 'mtime' and 'ctime' fields (if present), there is also
- * 'atime-nseconds', 'createtime-nseconds', 'mtime-nseconds'
- * and 'ctime-nseconds'.
- */
- public static final int SSH_FILEXFER_ATTR_SUBSECOND_TIMES = 0x00000100;
-
- /**
- * Indicates that the 'attrib-bits' and 'attrib-bits-valid'
- * fields are present.
- */
- public static final int SSH_FILEXFER_ATTR_BITS = 0x00000200;
-
- /**
- * Indicates that the 'allocation-size' field is present.
- */
- public static final int SSH_FILEXFER_ATTR_ALLOCATION_SIZE = 0x00000400;
-
- /**
- * Indicates that the 'text-hint' field is present.
- */
- public static final int SSH_FILEXFER_ATTR_TEXT_HINT = 0x00000800;
-
- /**
- * Indicates that the 'mime-type' field is present.
- */
- public static final int SSH_FILEXFER_ATTR_MIME_TYPE = 0x00001000;
-
- /**
- * Indicates that the 'link-count' field is present.
- */
- public static final int SSH_FILEXFER_ATTR_LINK_COUNT = 0x00002000;
-
- /**
- * Indicates that the 'untranslated-name' field is present.
- */
- public static final int SSH_FILEXFER_ATTR_UNTRANSLATED_NAME = 0x00004000;
-
- /**
- * Indicates that the 'ctime' field is present.
- */
- public static final int SSH_FILEXFER_ATTR_CTIME = 0x00008000;
-
- /**
- * Indicates that the 'extended-count' field (and probablby some
- * 'extensions') is present.
- */
- public static final int SSH_FILEXFER_ATTR_EXTENDED = 0x80000000;
-}
diff --git a/app/src/main/java/com/trilead/ssh2/sftp/AttribPermissions.java b/app/src/main/java/com/trilead/ssh2/sftp/AttribPermissions.java
deleted file mode 100644
index 558aa6f..0000000
--- a/app/src/main/java/com/trilead/ssh2/sftp/AttribPermissions.java
+++ /dev/null
@@ -1,32 +0,0 @@
-
-package com.trilead.ssh2.sftp;
-
-/**
- *
- * Permissions for the 'permissions' field in the SFTP ATTRS data type.
- * <p>
- * "<i>The 'permissions' field contains a bit mask specifying file permissions.
- * These permissions correspond to the st_mode field of the stat structure
- * defined by POSIX [IEEE.1003-1.1996].</i>"
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: AttribPermissions.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- *
- */
-public class AttribPermissions
-{
- /* Octal values! */
-
- public static final int S_IRUSR = 0400;
- public static final int S_IWUSR = 0200;
- public static final int S_IXUSR = 0100;
- public static final int S_IRGRP = 0040;
- public static final int S_IWGRP = 0020;
- public static final int S_IXGRP = 0010;
- public static final int S_IROTH = 0004;
- public static final int S_IWOTH = 0002;
- public static final int S_IXOTH = 0001;
- public static final int S_ISUID = 04000;
- public static final int S_ISGID = 02000;
- public static final int S_ISVTX = 01000;
-}
diff --git a/app/src/main/java/com/trilead/ssh2/sftp/AttribTypes.java b/app/src/main/java/com/trilead/ssh2/sftp/AttribTypes.java
deleted file mode 100644
index e2f4169..0000000
--- a/app/src/main/java/com/trilead/ssh2/sftp/AttribTypes.java
+++ /dev/null
@@ -1,28 +0,0 @@
-
-package com.trilead.ssh2.sftp;
-
-/**
- *
- * Types for the 'type' field in the SFTP ATTRS data type.
- * <p>
- * "<i>On a POSIX system, these values would be derived from the mode field
- * of the stat structure. SPECIAL should be used for files that are of
- * a known type which cannot be expressed in the protocol. UNKNOWN
- * should be used if the type is not known.</i>"
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: AttribTypes.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- *
- */
-public class AttribTypes
-{
- public static final int SSH_FILEXFER_TYPE_REGULAR = 1;
- public static final int SSH_FILEXFER_TYPE_DIRECTORY = 2;
- public static final int SSH_FILEXFER_TYPE_SYMLINK = 3;
- public static final int SSH_FILEXFER_TYPE_SPECIAL = 4;
- public static final int SSH_FILEXFER_TYPE_UNKNOWN = 5;
- public static final int SSH_FILEXFER_TYPE_SOCKET = 6;
- public static final int SSH_FILEXFER_TYPE_CHAR_DEVICE = 7;
- public static final int SSH_FILEXFER_TYPE_BLOCK_DEVICE = 8;
- public static final int SSH_FILEXFER_TYPE_FIFO = 9;
-}
diff --git a/app/src/main/java/com/trilead/ssh2/sftp/ErrorCodes.java b/app/src/main/java/com/trilead/ssh2/sftp/ErrorCodes.java
deleted file mode 100644
index 7317a00..0000000
--- a/app/src/main/java/com/trilead/ssh2/sftp/ErrorCodes.java
+++ /dev/null
@@ -1,104 +0,0 @@
-
-package com.trilead.ssh2.sftp;
-
-/**
- *
- * SFTP Error Codes
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: ErrorCodes.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- *
- */
-public class ErrorCodes
-{
- 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;
- public static final int SSH_FX_INVALID_HANDLE = 9;
- public static final int SSH_FX_NO_SUCH_PATH = 10;
- public static final int SSH_FX_FILE_ALREADY_EXISTS = 11;
- public static final int SSH_FX_WRITE_PROTECT = 12;
- public static final int SSH_FX_NO_MEDIA = 13;
- public static final int SSH_FX_NO_SPACE_ON_FILESYSTEM = 14;
- public static final int SSH_FX_QUOTA_EXCEEDED = 15;
- public static final int SSH_FX_UNKNOWN_PRINCIPAL = 16;
- public static final int SSH_FX_LOCK_CONFLICT = 17;
- public static final int SSH_FX_DIR_NOT_EMPTY = 18;
- public static final int SSH_FX_NOT_A_DIRECTORY = 19;
- public static final int SSH_FX_INVALID_FILENAME = 20;
- public static final int SSH_FX_LINK_LOOP = 21;
- public static final int SSH_FX_CANNOT_DELETE = 22;
- public static final int SSH_FX_INVALID_PARAMETER = 23;
- public static final int SSH_FX_FILE_IS_A_DIRECTORY = 24;
- public static final int SSH_FX_BYTE_RANGE_LOCK_CONFLICT = 25;
- public static final int SSH_FX_BYTE_RANGE_LOCK_REFUSED = 26;
- public static final int SSH_FX_DELETE_PENDING = 27;
- public static final int SSH_FX_FILE_CORRUPT = 28;
- public static final int SSH_FX_OWNER_INVALID = 29;
- public static final int SSH_FX_GROUP_INVALID = 30;
- public static final int SSH_FX_NO_MATCHING_BYTE_RANGE_LOCK = 31;
-
- private static final String[][] messages = {
-
- { "SSH_FX_OK", "Indicates successful completion of the operation." },
- { "SSH_FX_EOF",
- "An attempt to read past the end-of-file was made; or, there are no more directory entries to return." },
- { "SSH_FX_NO_SUCH_FILE", "A reference was made to a file which does not exist." },
- { "SSH_FX_PERMISSION_DENIED", "The user does not have sufficient permissions to perform the operation." },
- { "SSH_FX_FAILURE", "An error occurred, but no specific error code exists to describe the failure." },
- { "SSH_FX_BAD_MESSAGE", "A badly formatted packet or other SFTP protocol incompatibility was detected." },
- { "SSH_FX_NO_CONNECTION", "There is no connection to the server." },
- { "SSH_FX_CONNECTION_LOST", "The connection to the server was lost." },
- { "SSH_FX_OP_UNSUPPORTED",
- "An attempted operation could not be completed by the server because the server does not support the operation." },
- { "SSH_FX_INVALID_HANDLE", "The handle value was invalid." },
- { "SSH_FX_NO_SUCH_PATH", "The file path does not exist or is invalid." },
- { "SSH_FX_FILE_ALREADY_EXISTS", "The file already exists." },
- { "SSH_FX_WRITE_PROTECT", "The file is on read-only media, or the media is write protected." },
- { "SSH_FX_NO_MEDIA",
- "The requested operation cannot be completed because there is no media available in the drive." },
- { "SSH_FX_NO_SPACE_ON_FILESYSTEM",
- "The requested operation cannot be completed because there is insufficient free space on the filesystem." },
- { "SSH_FX_QUOTA_EXCEEDED",
- "The operation cannot be completed because it would exceed the user's storage quota." },
- {
- "SSH_FX_UNKNOWN_PRINCIPAL",
- "A principal referenced by the request (either the 'owner', 'group', or 'who' field of an ACL), was unknown. The error specific data contains the problematic names." },
- { "SSH_FX_LOCK_CONFLICT", "The file could not be opened because it is locked by another process." },
- { "SSH_FX_DIR_NOT_EMPTY", "The directory is not empty." },
- { "SSH_FX_NOT_A_DIRECTORY", "The specified file is not a directory." },
- { "SSH_FX_INVALID_FILENAME", "The filename is not valid." },
- { "SSH_FX_LINK_LOOP",
- "Too many symbolic links encountered or, an SSH_FXF_NOFOLLOW open encountered a symbolic link as the final component." },
- { "SSH_FX_CANNOT_DELETE",
- "The file cannot be deleted. One possible reason is that the advisory READONLY attribute-bit is set." },
- { "SSH_FX_INVALID_PARAMETER",
- "One of the parameters was out of range, or the parameters specified cannot be used together." },
- { "SSH_FX_FILE_IS_A_DIRECTORY",
- "The specified file was a directory in a context where a directory cannot be used." },
- { "SSH_FX_BYTE_RANGE_LOCK_CONFLICT",
- " A read or write operation failed because another process's mandatory byte-range lock overlaps with the request." },
- { "SSH_FX_BYTE_RANGE_LOCK_REFUSED", "A request for a byte range lock was refused." },
- { "SSH_FX_DELETE_PENDING", "An operation was attempted on a file for which a delete operation is pending." },
- { "SSH_FX_FILE_CORRUPT", "The file is corrupt; an filesystem integrity check should be run." },
- { "SSH_FX_OWNER_INVALID", "The principal specified can not be assigned as an owner of a file." },
- { "SSH_FX_GROUP_INVALID", "The principal specified can not be assigned as the primary group of a file." },
- { "SSH_FX_NO_MATCHING_BYTE_RANGE_LOCK",
- "The requested operation could not be completed because the specifed byte range lock has not been granted." },
-
- };
-
- public static final String[] getDescription(int errorCode)
- {
- if ((errorCode < 0) || (errorCode >= messages.length))
- return null;
-
- return messages[errorCode];
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/sftp/OpenFlags.java b/app/src/main/java/com/trilead/ssh2/sftp/OpenFlags.java
deleted file mode 100644
index b2979b9..0000000
--- a/app/src/main/java/com/trilead/ssh2/sftp/OpenFlags.java
+++ /dev/null
@@ -1,223 +0,0 @@
-
-package com.trilead.ssh2.sftp;
-
-/**
- *
- * SFTP Open Flags.
- *
- * The following table is provided to assist in mapping POSIX semantics
- * to equivalent SFTP file open parameters:
- * <p>
- * TODO: This comment should be moved to the open method.
- * <p>
- * <ul>
- * <li>O_RDONLY
- * <ul><li>desired-access = READ_DATA | READ_ATTRIBUTES</li></ul>
- * </li>
- * </ul>
- * <ul>
- * <li>O_WRONLY
- * <ul><li>desired-access = WRITE_DATA | WRITE_ATTRIBUTES</li></ul>
- * </li>
- * </ul>
- * <ul>
- * <li>O_RDWR
- * <ul><li>desired-access = READ_DATA | READ_ATTRIBUTES | WRITE_DATA | WRITE_ATTRIBUTES</li></ul>
- * </li>
- * </ul>
- * <ul>
- * <li>O_APPEND
- * <ul>
- * <li>desired-access = WRITE_DATA | WRITE_ATTRIBUTES | APPEND_DATA</li>
- * <li>flags = SSH_FXF_ACCESS_APPEND_DATA and or SSH_FXF_ACCESS_APPEND_DATA_ATOMIC</li>
- * </ul>
- * </li>
- * </ul>
- * <ul>
- * <li>O_CREAT
- * <ul>
- * <li>flags = SSH_FXF_OPEN_OR_CREATE</li>
- * </ul>
- * </li>
- * </ul>
- * <ul>
- * <li>O_TRUNC
- * <ul>
- * <li>flags = SSH_FXF_TRUNCATE_EXISTING</li>
- * </ul>
- * </li>
- * </ul>
- * <ul>
- * <li>O_TRUNC|O_CREATE
- * <ul>
- * <li>flags = SSH_FXF_CREATE_TRUNCATE</li>
- * </ul>
- * </li>
- * </ul>
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: OpenFlags.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- */
-public class OpenFlags
-{
- /**
- * Disposition is a 3 bit field that controls how the file is opened.
- * The server MUST support these bits (possible enumaration values:
- * SSH_FXF_CREATE_NEW, SSH_FXF_CREATE_TRUNCATE, SSH_FXF_OPEN_EXISTING,
- * SSH_FXF_OPEN_OR_CREATE or SSH_FXF_TRUNCATE_EXISTING).
- */
- public static final int SSH_FXF_ACCESS_DISPOSITION = 0x00000007;
-
- /**
- * A new file is created; if the file already exists, the server
- * MUST return status SSH_FX_FILE_ALREADY_EXISTS.
- */
- public static final int SSH_FXF_CREATE_NEW = 0x00000000;
-
- /**
- * A new file is created; if the file already exists, it is opened
- * and truncated.
- */
- public static final int SSH_FXF_CREATE_TRUNCATE = 0x00000001;
-
- /**
- * An existing file is opened. If the file does not exist, the
- * server MUST return SSH_FX_NO_SUCH_FILE. If a directory in the
- * path does not exist, the server SHOULD return
- * SSH_FX_NO_SUCH_PATH. It is also acceptable if the server
- * returns SSH_FX_NO_SUCH_FILE in this case.
- */
- public static final int SSH_FXF_OPEN_EXISTING = 0x00000002;
-
- /**
- * If the file exists, it is opened. If the file does not exist,
- * it is created.
- */
- public static final int SSH_FXF_OPEN_OR_CREATE = 0x00000003;
-
- /**
- * An existing file is opened and truncated. If the file does not
- * exist, the server MUST return the same error codes as defined
- * for SSH_FXF_OPEN_EXISTING.
- */
- public static final int SSH_FXF_TRUNCATE_EXISTING = 0x00000004;
-
- /**
- * Data is always written at the end of the file. The offset field
- * of the SSH_FXP_WRITE requests are ignored.
- * <p>
- * Data is not required to be appended atomically. This means that
- * if multiple writers attempt to append data simultaneously, data
- * from the first may be lost. However, data MAY be appended
- * atomically.
- */
- public static final int SSH_FXF_ACCESS_APPEND_DATA = 0x00000008;
-
- /**
- * Data is always written at the end of the file. The offset field
- * of the SSH_FXP_WRITE requests are ignored.
- * <p>
- * Data MUST be written atomically so that there is no chance that
- * multiple appenders can collide and result in data being lost.
- * <p>
- * If both append flags are specified, the server SHOULD use atomic
- * append if it is available, but SHOULD use non-atomic appends
- * otherwise. The server SHOULD NOT fail the request in this case.
- */
- public static final int SSH_FXF_ACCESS_APPEND_DATA_ATOMIC = 0x00000010;
-
- /**
- * Indicates that the server should treat the file as text and
- * convert it to the canonical newline convention in use.
- * (See Determining Server Newline Convention in section 5.3 in the
- * SFTP standard draft).
- * <p>
- * When a file is opened with this flag, the offset field in the read
- * and write functions is ignored.
- * <p>
- * Servers MUST process multiple, parallel reads and writes correctly
- * in this mode. Naturally, it is permissible for them to do this by
- * serializing the requests.
- * <p>
- * Clients SHOULD use the SSH_FXF_ACCESS_APPEND_DATA flag to append
- * data to a text file rather then using write with a calculated offset.
- */
- public static final int SSH_FXF_ACCESS_TEXT_MODE = 0x00000020;
-
- /**
- * The server MUST guarantee that no other handle has been opened
- * with ACE4_READ_DATA access, and that no other handle will be
- * opened with ACE4_READ_DATA access until the client closes the
- * handle. (This MUST apply both to other clients and to other
- * processes on the server.)
- * <p>
- * If there is a conflicting lock the server MUST return
- * SSH_FX_LOCK_CONFLICT. If the server cannot make the locking
- * guarantee, it MUST return SSH_FX_OP_UNSUPPORTED.
- * <p>
- * Other handles MAY be opened for ACE4_WRITE_DATA or any other
- * combination of accesses, as long as ACE4_READ_DATA is not included
- * in the mask.
- */
- public static final int SSH_FXF_ACCESS_BLOCK_READ = 0x00000040;
-
- /**
- * The server MUST guarantee that no other handle has been opened
- * with ACE4_WRITE_DATA or ACE4_APPEND_DATA access, and that no other
- * handle will be opened with ACE4_WRITE_DATA or ACE4_APPEND_DATA
- * access until the client closes the handle. (This MUST apply both
- * to other clients and to other processes on the server.)
- * <p>
- * If there is a conflicting lock the server MUST return
- * SSH_FX_LOCK_CONFLICT. If the server cannot make the locking
- * guarantee, it MUST return SSH_FX_OP_UNSUPPORTED.
- * <p>
- * Other handles MAY be opened for ACE4_READ_DATA or any other
- * combination of accesses, as long as neither ACE4_WRITE_DATA nor
- * ACE4_APPEND_DATA are included in the mask.
- */
- public static final int SSH_FXF_ACCESS_BLOCK_WRITE = 0x00000080;
-
- /**
- * The server MUST guarantee that no other handle has been opened
- * with ACE4_DELETE access, opened with the
- * SSH_FXF_ACCESS_DELETE_ON_CLOSE flag set, and that no other handle
- * will be opened with ACE4_DELETE access or with the
- * SSH_FXF_ACCESS_DELETE_ON_CLOSE flag set, and that the file itself
- * is not deleted in any other way until the client closes the handle.
- * <p>
- * If there is a conflicting lock the server MUST return
- * SSH_FX_LOCK_CONFLICT. If the server cannot make the locking
- * guarantee, it MUST return SSH_FX_OP_UNSUPPORTED.
- */
- public static final int SSH_FXF_ACCESS_BLOCK_DELETE = 0x00000100;
-
- /**
- * If this bit is set, the above BLOCK modes are advisory. In advisory
- * mode, only other accesses that specify a BLOCK mode need be
- * considered when determining whether the BLOCK can be granted,
- * and the server need not prevent I/O operations that violate the
- * block mode.
- * <p>
- * The server MAY perform mandatory locking even if the BLOCK_ADVISORY
- * bit is set.
- */
- public static final int SSH_FXF_ACCESS_BLOCK_ADVISORY = 0x00000200;
-
- /**
- * If the final component of the path is a symlink, then the open
- * MUST fail, and the error SSH_FX_LINK_LOOP MUST be returned.
- */
- public static final int SSH_FXF_ACCESS_NOFOLLOW = 0x00000400;
-
- /**
- * The file should be deleted when the last handle to it is closed.
- * (The last handle may not be an sftp-handle.) This MAY be emulated
- * by a server if the OS doesn't support it by deleting the file when
- * this handle is closed.
- * <p>
- * It is implementation specific whether the directory entry is
- * removed immediately or when the handle is closed.
- */
- public static final int SSH_FXF_ACCESS_DELETE_ON_CLOSE = 0x00000800;
-}
diff --git a/app/src/main/java/com/trilead/ssh2/sftp/Packet.java b/app/src/main/java/com/trilead/ssh2/sftp/Packet.java
deleted file mode 100644
index 444af90..0000000
--- a/app/src/main/java/com/trilead/ssh2/sftp/Packet.java
+++ /dev/null
@@ -1,43 +0,0 @@
-
-package com.trilead.ssh2.sftp;
-
-/**
- *
- * SFTP Paket Types
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: Packet.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
- *
- */
-public class Packet
-{
- public static final int SSH_FXP_INIT = 1;
- public static final int SSH_FXP_VERSION = 2;
- public static final int SSH_FXP_OPEN = 3;
- public static final int SSH_FXP_CLOSE = 4;
- public static final int SSH_FXP_READ = 5;
- public static final int SSH_FXP_WRITE = 6;
- public static final int SSH_FXP_LSTAT = 7;
- public static final int SSH_FXP_FSTAT = 8;
- public static final int SSH_FXP_SETSTAT = 9;
- public static final int SSH_FXP_FSETSTAT = 10;
- public static final int SSH_FXP_OPENDIR = 11;
- public static final int SSH_FXP_READDIR = 12;
- public static final int SSH_FXP_REMOVE = 13;
- public static final int SSH_FXP_MKDIR = 14;
- public static final int SSH_FXP_RMDIR = 15;
- public static final int SSH_FXP_REALPATH = 16;
- public static final int SSH_FXP_STAT = 17;
- public static final int SSH_FXP_RENAME = 18;
- public static final int SSH_FXP_READLINK = 19;
- public static final int SSH_FXP_SYMLINK = 20;
-
- public static final int SSH_FXP_STATUS = 101;
- public static final int SSH_FXP_HANDLE = 102;
- public static final int SSH_FXP_DATA = 103;
- public static final int SSH_FXP_NAME = 104;
- public static final int SSH_FXP_ATTRS = 105;
-
- public static final int SSH_FXP_EXTENDED = 200;
- public static final int SSH_FXP_EXTENDED_REPLY = 201;
-}
diff --git a/app/src/main/java/com/trilead/ssh2/signature/DSASHA1Verify.java b/app/src/main/java/com/trilead/ssh2/signature/DSASHA1Verify.java
deleted file mode 100644
index 6fb6ddb..0000000
--- a/app/src/main/java/com/trilead/ssh2/signature/DSASHA1Verify.java
+++ /dev/null
@@ -1,255 +0,0 @@
-
-package com.trilead.ssh2.signature;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.DSAPublicKey;
-import java.security.spec.DSAPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-
-import com.trilead.ssh2.log.Logger;
-import com.trilead.ssh2.packets.TypesReader;
-import com.trilead.ssh2.packets.TypesWriter;
-
-
-/**
- * DSASHA1Verify.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: DSASHA1Verify.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
- */
-public class DSASHA1Verify
-{
- private static final Logger log = Logger.getLogger(DSASHA1Verify.class);
-
- public static DSAPublicKey decodeSSHDSAPublicKey(byte[] key) throws IOException
- {
- TypesReader tr = new TypesReader(key);
-
- String key_format = tr.readString();
-
- if (key_format.equals("ssh-dss") == false)
- throw new IllegalArgumentException("This is not a ssh-dss public key!");
-
- BigInteger p = tr.readMPINT();
- BigInteger q = tr.readMPINT();
- BigInteger g = tr.readMPINT();
- BigInteger y = tr.readMPINT();
-
- if (tr.remain() != 0)
- throw new IOException("Padding in DSA public key!");
-
- try {
- KeyFactory kf = KeyFactory.getInstance("DSA");
-
- KeySpec ks = new DSAPublicKeySpec(y, p, q, g);
- return (DSAPublicKey) kf.generatePublic(ks);
- } catch (NoSuchAlgorithmException e) {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- } catch (InvalidKeySpecException e) {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- }
- }
-
- public static byte[] encodeSSHDSAPublicKey(DSAPublicKey pk) throws IOException
- {
- TypesWriter tw = new TypesWriter();
-
- tw.writeString("ssh-dss");
-
- DSAParams params = pk.getParams();
- tw.writeMPInt(params.getP());
- tw.writeMPInt(params.getQ());
- tw.writeMPInt(params.getG());
- tw.writeMPInt(pk.getY());
-
- return tw.getBytes();
- }
-
- /**
- * Convert from Java's signature ASN.1 encoding to the SSH spec.
- * <p>
- * Java ASN.1 encoding:
- * <pre>
- * SEQUENCE ::= {
- * r INTEGER,
- * s INTEGER
- * }
- * </pre>
- */
- public static byte[] encodeSSHDSASignature(byte[] ds)
- {
- TypesWriter tw = new TypesWriter();
-
- tw.writeString("ssh-dss");
-
- int len, index;
-
- index = 3;
- len = ds[index++] & 0xff;
- byte[] r = new byte[len];
- System.arraycopy(ds, index, r, 0, r.length);
-
- index = index + len + 1;
- len = ds[index++] & 0xff;
- byte[] s = new byte[len];
- System.arraycopy(ds, index, s, 0, s.length);
-
- byte[] a40 = new byte[40];
-
- /* Patch (unsigned) r and s into the target array. */
-
- int r_copylen = (r.length < 20) ? r.length : 20;
- int s_copylen = (s.length < 20) ? s.length : 20;
-
- System.arraycopy(r, r.length - r_copylen, a40, 20 - r_copylen, r_copylen);
- System.arraycopy(s, s.length - s_copylen, a40, 40 - s_copylen, s_copylen);
-
- tw.writeString(a40, 0, 40);
-
- return tw.getBytes();
- }
-
- public static byte[] decodeSSHDSASignature(byte[] sig) throws IOException
- {
- byte[] rsArray = null;
-
- if (sig.length == 40)
- {
- /* OK, another broken SSH server. */
- rsArray = sig;
- }
- else
- {
- /* Hopefully a server obeying the standard... */
- TypesReader tr = new TypesReader(sig);
-
- String sig_format = tr.readString();
- if (sig_format.equals("ssh-dss") == false)
- throw new IOException("Peer sent wrong signature format");
-
- rsArray = tr.readByteString();
-
- if (rsArray.length != 40)
- throw new IOException("Peer sent corrupt signature");
-
- if (tr.remain() != 0)
- throw new IOException("Padding in DSA signature!");
- }
-
- int i = 0;
- int j = 0;
- byte[] tmp;
-
- if (rsArray[0] == 0 && rsArray[1] == 0 && rsArray[2] == 0) {
- j = ((rsArray[i++] << 24) & 0xff000000) | ((rsArray[i++] << 16) & 0x00ff0000)
- | ((rsArray[i++] << 8) & 0x0000ff00) | ((rsArray[i++]) & 0x000000ff);
- i += j;
- j = ((rsArray[i++] << 24) & 0xff000000) | ((rsArray[i++] << 16) & 0x00ff0000)
- | ((rsArray[i++] << 8) & 0x0000ff00) | ((rsArray[i++]) & 0x000000ff);
- tmp = new byte[j];
- System.arraycopy(rsArray, i, tmp, 0, j);
- rsArray = tmp;
- }
-
- /* ASN.1 */
- int frst = ((rsArray[0] & 0x80) != 0 ? 1 : 0);
- int scnd = ((rsArray[20] & 0x80) != 0 ? 1 : 0);
-
- /* Calculate output length */
- int length = rsArray.length + 6 + frst + scnd;
- tmp = new byte[length];
-
- /* DER-encoding to match Java */
- tmp[0] = (byte) 0x30;
-
- if (rsArray.length != 40)
- throw new IOException("Peer sent corrupt signature");
- /* Calculate length */
- tmp[1] = (byte) 0x2c;
- tmp[1] += frst;
- tmp[1] += scnd;
-
- /* First item */
- tmp[2] = (byte) 0x02;
-
- /* First item length */
- tmp[3] = (byte) 0x14;
- tmp[3] += frst;
-
- /* Copy in the data for first item */
- System.arraycopy(rsArray, 0, tmp, 4 + frst, 20);
-
- /* Second item */
- tmp[4 + tmp[3]] = (byte) 0x02;
-
- /* Second item length */
- tmp[5 + tmp[3]] = (byte) 0x14;
- tmp[5 + tmp[3]] += scnd;
-
- /* Copy in the data for the second item */
- System.arraycopy(rsArray, 20, tmp, 6 + tmp[3] + scnd, 20);
-
- /* Swap buffers */
- rsArray = tmp;
-
- return rsArray;
- }
-
- public static boolean verifySignature(byte[] message, byte[] ds, DSAPublicKey dpk) throws IOException
- {
- try {
- Signature s = Signature.getInstance("SHA1withDSA");
- s.initVerify(dpk);
- s.update(message);
- return s.verify(ds);
- } catch (NoSuchAlgorithmException e) {
- IOException ex = new IOException("No such algorithm");
- ex.initCause(e);
- throw ex;
- } catch (InvalidKeyException e) {
- IOException ex = new IOException("No such algorithm");
- ex.initCause(e);
- throw ex;
- } catch (SignatureException e) {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- }
- }
-
- public static byte[] generateSignature(byte[] message, DSAPrivateKey pk, SecureRandom rnd) throws IOException
- {
- try {
- Signature s = Signature.getInstance("SHA1withDSA");
- s.initSign(pk);
- s.update(message);
- return s.sign();
- } catch (NoSuchAlgorithmException e) {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- } catch (InvalidKeyException e) {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- } catch (SignatureException e) {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/signature/ECDSASHA2Verify.java b/app/src/main/java/com/trilead/ssh2/signature/ECDSASHA2Verify.java
deleted file mode 100644
index 281a59d..0000000
--- a/app/src/main/java/com/trilead/ssh2/signature/ECDSASHA2Verify.java
+++ /dev/null
@@ -1,487 +0,0 @@
-/**
- *
- */
-package com.trilead.ssh2.signature;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.ECFieldFp;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
-import java.security.spec.ECPublicKeySpec;
-import java.security.spec.EllipticCurve;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import java.util.Map;
-import java.util.TreeMap;
-
-import com.trilead.ssh2.log.Logger;
-import com.trilead.ssh2.packets.TypesReader;
-import com.trilead.ssh2.packets.TypesWriter;
-
-/**
- * @author Kenny Root
- *
- */
-public class ECDSASHA2Verify {
- private static final Logger log = Logger.getLogger(ECDSASHA2Verify.class);
-
- public static final String ECDSA_SHA2_PREFIX = "ecdsa-sha2-";
-
- private static final String NISTP256 = "nistp256";
- private static final String NISTP256_OID = "1.2.840.10045.3.1.7";
- private static final String NISTP384 = "nistp384";
- private static final String NISTP384_OID = "1.3.132.0.34";
- private static final String NISTP521 = "nistp521";
- private static final String NISTP521_OID = "1.3.132.0.35";
-
- private static final Map<String, ECParameterSpec> CURVES = new TreeMap<String, ECParameterSpec>();
- static {
- CURVES.put(NISTP256, EllipticCurves.nistp256);
- CURVES.put(NISTP384, EllipticCurves.nistp384);
- CURVES.put(NISTP521, EllipticCurves.nistp521);
- }
-
- private static final Map<Integer, String> CURVE_SIZES = new TreeMap<Integer, String>();
- static {
- CURVE_SIZES.put(256, NISTP256);
- CURVE_SIZES.put(384, NISTP384);
- CURVE_SIZES.put(521, NISTP521);
- }
-
- private static final Map<String, String> CURVE_OIDS = new TreeMap<String, String>();
- static {
- CURVE_OIDS.put(NISTP256_OID, NISTP256);
- CURVE_OIDS.put(NISTP384_OID, NISTP256);
- CURVE_OIDS.put(NISTP521_OID, NISTP256);
- }
-
- public static int[] getCurveSizes() {
- int[] keys = new int[CURVE_SIZES.size()];
- int i = 0;
- for (Integer n : CURVE_SIZES.keySet().toArray(new Integer[keys.length])) {
- keys[i++] = n;
- }
- return keys;
- }
-
- public static ECParameterSpec getCurveForSize(int size) {
- final String name = CURVE_SIZES.get(size);
- if (name == null) {
- return null;
- }
- return CURVES.get(name);
- }
-
- public static ECPublicKey decodeSSHECDSAPublicKey(byte[] key) throws IOException
- {
- TypesReader tr = new TypesReader(key);
-
- String key_format = tr.readString();
-
- if (key_format.startsWith(ECDSA_SHA2_PREFIX) == false)
- throw new IllegalArgumentException("This is not an ECDSA public key");
-
- String curveName = tr.readString();
- byte[] groupBytes = tr.readByteString();
-
- if (tr.remain() != 0)
- throw new IOException("Padding in ECDSA public key!");
-
- if (key_format.equals(ECDSA_SHA2_PREFIX + curveName) == false) {
- throw new IOException("Key format is inconsistent with curve name: " + key_format
- + " != " + curveName);
- }
-
- ECParameterSpec params = CURVES.get(curveName);
- if (params == null) {
- throw new IOException("Curve is not supported: " + curveName);
- }
-
- ECPoint group = ECDSASHA2Verify.decodeECPoint(groupBytes, params.getCurve());
- if (group == null) {
- throw new IOException("Invalid ECDSA group");
- }
-
- KeySpec keySpec = new ECPublicKeySpec(group, params);
-
- try {
- KeyFactory kf = KeyFactory.getInstance("EC");
- return (ECPublicKey) kf.generatePublic(keySpec);
- } catch (NoSuchAlgorithmException nsae) {
- IOException ioe = new IOException("No EC KeyFactory available");
- ioe.initCause(nsae);
- throw ioe;
- } catch (InvalidKeySpecException ikse) {
- IOException ioe = new IOException("No EC KeyFactory available");
- ioe.initCause(ikse);
- throw ioe;
- }
- }
-
- public static byte[] encodeSSHECDSAPublicKey(ECPublicKey key) throws IOException {
- TypesWriter tw = new TypesWriter();
-
- String curveName = getCurveName(key.getParams());
-
- String keyFormat = ECDSA_SHA2_PREFIX + curveName;
-
- tw.writeString(keyFormat);
-
- tw.writeString(curveName);
-
- byte[] encoded = encodeECPoint(key.getW(), key.getParams().getCurve());
- tw.writeString(encoded, 0, encoded.length);
-
- return tw.getBytes();
- }
-
- public static String getCurveName(ECParameterSpec params) throws IOException {
- int fieldSize = getCurveSize(params);
- final String curveName = getCurveName(fieldSize);
- if (curveName == null) {
- throw new IOException("invalid curve size " + fieldSize);
- }
- return curveName;
- }
-
- public static String getCurveName(int fieldSize) {
- String curveName = CURVE_SIZES.get(fieldSize);
- if (curveName == null) {
- return null;
- }
- return curveName;
- }
-
- public static int getCurveSize(ECParameterSpec params) {
- return params.getCurve().getField().getFieldSize();
- }
-
- public static ECParameterSpec getCurveForOID(String oid) {
- String name = CURVE_OIDS.get(oid);
- if (name == null)
- return null;
- return CURVES.get(name);
- }
-
- public static byte[] decodeSSHECDSASignature(byte[] sig) throws IOException {
- byte[] rsArray = null;
-
- TypesReader tr = new TypesReader(sig);
-
- String sig_format = tr.readString();
- if (sig_format.startsWith(ECDSA_SHA2_PREFIX) == false)
- throw new IOException("Peer sent wrong signature format");
-
- String curveName = sig_format.substring(ECDSA_SHA2_PREFIX.length());
- if (CURVES.containsKey(curveName) == false) {
- throw new IOException("Unsupported curve: " + curveName);
- }
-
- rsArray = tr.readByteString();
-
- if (tr.remain() != 0)
- throw new IOException("Padding in ECDSA signature!");
-
- byte[] rArray;
- byte[] sArray;
- {
- TypesReader rsReader = new TypesReader(rsArray);
- rArray = rsReader.readMPINT().toByteArray();
- sArray = rsReader.readMPINT().toByteArray();
- }
-
- int first = rArray.length;
- int second = sArray.length;
-
- /* We can't have the high bit set, so add an extra zero at the beginning if so. */
- if ((rArray[0] & 0x80) != 0) {
- first++;
- }
- if ((sArray[0] & 0x80) != 0) {
- second++;
- }
-
- /* Calculate total output length */
- ByteArrayOutputStream os = new ByteArrayOutputStream(6 + first + second);
-
- /* ASN.1 SEQUENCE tag */
- os.write(0x30);
-
- /* Size of SEQUENCE */
- writeLength(4 + first + second, os);
-
- /* ASN.1 INTEGER tag */
- os.write(0x02);
-
- /* "r" INTEGER length */
- writeLength(first, os);
-
- /* Copy in the "r" INTEGER */
- if (first != rArray.length) {
- os.write(0x00);
- }
- os.write(rArray);
-
- /* ASN.1 INTEGER tag */
- os.write(0x02);
-
- /* "s" INTEGER length */
- writeLength(second, os);
-
- /* Copy in the "s" INTEGER */
- if (second != sArray.length) {
- os.write(0x00);
- }
- os.write(sArray);
-
- return os.toByteArray();
- }
-
- private static final void writeLength(int length, OutputStream os) throws IOException {
- if (length <= 0x7F) {
- os.write(length);
- return;
- }
-
- int numOctets = 0;
- int lenCopy = length;
- while (lenCopy != 0) {
- lenCopy >>>= 8;
- numOctets++;
- }
-
- os.write(0x80 | numOctets);
-
- for (int i = (numOctets - 1) * 8; i >= 0; i -= 8) {
- os.write((byte) (length >> i));
- }
- }
-
- public static byte[] encodeSSHECDSASignature(byte[] sig, ECParameterSpec params) throws IOException
- {
- TypesWriter tw = new TypesWriter();
-
- String curveName = getCurveName(params);
- tw.writeString(ECDSA_SHA2_PREFIX + curveName);
-
- if ((sig[0] != 0x30) || (sig[1] != sig.length - 2) || (sig[2] != 0x02)) {
- throw new IOException("Invalid signature format");
- }
-
- int rLength = sig[3];
- if ((rLength + 6 > sig.length) || (sig[4 + rLength] != 0x02)) {
- throw new IOException("Invalid signature format");
- }
-
- int sLength = sig[5 + rLength];
- if (6 + rLength + sLength > sig.length) {
- throw new IOException("Invalid signature format");
- }
-
- byte[] rArray = new byte[rLength];
- byte[] sArray = new byte[sLength];
-
- System.arraycopy(sig, 4, rArray, 0, rLength);
- System.arraycopy(sig, 6 + rLength, sArray, 0, sLength);
-
- BigInteger r = new BigInteger(1, rArray);
- BigInteger s = new BigInteger(1, sArray);
-
- // Write the <r,s> to its own types writer.
- TypesWriter rsWriter = new TypesWriter();
- rsWriter.writeMPInt(r);
- rsWriter.writeMPInt(s);
- byte[] encoded = rsWriter.getBytes();
- tw.writeString(encoded, 0, encoded.length);
-
- return tw.getBytes();
- }
-
- public static byte[] generateSignature(byte[] message, ECPrivateKey pk) throws IOException
- {
- final String algo = getSignatureAlgorithmForParams(pk.getParams());
-
- try {
- Signature s = Signature.getInstance(algo);
- s.initSign(pk);
- s.update(message);
- return s.sign();
- } catch (NoSuchAlgorithmException e) {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- } catch (InvalidKeyException e) {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- } catch (SignatureException e) {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- }
- }
-
- public static boolean verifySignature(byte[] message, byte[] ds, ECPublicKey dpk) throws IOException
- {
- final String algo = getSignatureAlgorithmForParams(dpk.getParams());
-
- try {
- Signature s = Signature.getInstance(algo);
- s.initVerify(dpk);
- s.update(message);
- return s.verify(ds);
- } catch (NoSuchAlgorithmException e) {
- IOException ex = new IOException("No such algorithm");
- ex.initCause(e);
- throw ex;
- } catch (InvalidKeyException e) {
- IOException ex = new IOException("No such algorithm");
- ex.initCause(e);
- throw ex;
- } catch (SignatureException e) {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- }
- }
-
- private static String getSignatureAlgorithmForParams(ECParameterSpec params) {
- int size = getCurveSize(params);
- if (size <= 256) {
- return "SHA256withECDSA";
- } else if (size <= 384) {
- return "SHA384withECDSA";
- } else {
- return "SHA512withECDSA";
- }
- }
-
- public static String getDigestAlgorithmForParams(ECParameterSpec params) {
- int size = getCurveSize(params);
- if (size <= 256) {
- return "SHA-256";
- } else if (size <= 384) {
- return "SHA-384";
- } else {
- return "SHA-512";
- }
- }
-
- /**
- * Decode an OctetString to EllipticCurvePoint according to SECG 2.3.4
- */
- public static ECPoint decodeECPoint(byte[] M, EllipticCurve curve) {
- if (M.length == 0) {
- return null;
- }
-
- // M has len 2 ceil(log_2(q)/8) + 1 ?
- int elementSize = (curve.getField().getFieldSize() + 7) / 8;
- if (M.length != 2 * elementSize + 1) {
- return null;
- }
-
- // step 3.2
- if (M[0] != 0x04) {
- return null;
- }
-
- // Step 3.3
- byte[] xp = new byte[elementSize];
- System.arraycopy(M, 1, xp, 0, elementSize);
-
- // Step 3.4
- byte[] yp = new byte[elementSize];
- System.arraycopy(M, 1 + elementSize, yp, 0, elementSize);
-
- ECPoint P = new ECPoint(new BigInteger(1, xp), new BigInteger(1, yp));
-
- // TODO check point 3.5
-
- // Step 3.6
- return P;
- }
-
- /**
- * Encode EllipticCurvePoint to an OctetString
- */
- public static byte[] encodeECPoint(ECPoint group, EllipticCurve curve)
- {
- // M has len 2 ceil(log_2(q)/8) + 1 ?
- int elementSize = (curve.getField().getFieldSize() + 7) / 8;
- byte[] M = new byte[2 * elementSize + 1];
-
- // Uncompressed format
- M[0] = 0x04;
-
- {
- byte[] affineX = removeLeadingZeroes(group.getAffineX().toByteArray());
- System.arraycopy(affineX, 0, M, 1 + elementSize - affineX.length, affineX.length);
- }
-
- {
- byte[] affineY = removeLeadingZeroes(group.getAffineY().toByteArray());
- System.arraycopy(affineY, 0, M, 1 + elementSize + elementSize - affineY.length,
- affineY.length);
- }
-
- return M;
- }
-
- private static byte[] removeLeadingZeroes(byte[] input) {
- if (input[0] != 0x00) {
- return input;
- }
-
- int pos = 1;
- while (pos < input.length - 1 && input[pos] == 0x00) {
- pos++;
- }
-
- byte[] output = new byte[input.length - pos];
- System.arraycopy(input, pos, output, 0, output.length);
- return output;
- }
-
- public static class EllipticCurves {
- public static ECParameterSpec nistp256 = new ECParameterSpec(
- new EllipticCurve(
- new ECFieldFp(new BigInteger("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", 16)),
- new BigInteger("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", 16),
- new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16)),
- new ECPoint(new BigInteger("6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", 16),
- new BigInteger("4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", 16)),
- new BigInteger("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 16),
- 1);
-
- public static ECParameterSpec nistp384 = new ECParameterSpec(
- new EllipticCurve(
- new ECFieldFp(new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", 16)),
- new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", 16),
- new BigInteger("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", 16)),
- new ECPoint(new BigInteger("AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", 16),
- new BigInteger("3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", 16)),
- new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", 16),
- 1);
-
- public static ECParameterSpec nistp521 = new ECParameterSpec(
- new EllipticCurve(
- new ECFieldFp(new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16)),
- new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16),
- new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16)),
- new ECPoint(new BigInteger("00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", 16),
- new BigInteger("011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", 16)),
- new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16),
- 1);
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/signature/RSASHA1Verify.java b/app/src/main/java/com/trilead/ssh2/signature/RSASHA1Verify.java
deleted file mode 100644
index 3406312..0000000
--- a/app/src/main/java/com/trilead/ssh2/signature/RSASHA1Verify.java
+++ /dev/null
@@ -1,180 +0,0 @@
-
-package com.trilead.ssh2.signature;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import java.security.spec.RSAPublicKeySpec;
-
-import com.trilead.ssh2.log.Logger;
-import com.trilead.ssh2.packets.TypesReader;
-import com.trilead.ssh2.packets.TypesWriter;
-
-
-/**
- * RSASHA1Verify.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: RSASHA1Verify.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
- */
-public class RSASHA1Verify
-{
- private static final Logger log = Logger.getLogger(RSASHA1Verify.class);
-
- public static RSAPublicKey decodeSSHRSAPublicKey(byte[] key) throws IOException
- {
- TypesReader tr = new TypesReader(key);
-
- String key_format = tr.readString();
-
- if (key_format.equals("ssh-rsa") == false)
- throw new IllegalArgumentException("This is not a ssh-rsa public key");
-
- BigInteger e = tr.readMPINT();
- BigInteger n = tr.readMPINT();
-
- if (tr.remain() != 0)
- throw new IOException("Padding in RSA public key!");
-
- KeySpec keySpec = new RSAPublicKeySpec(n, e);
-
- try {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- return (RSAPublicKey) kf.generatePublic(keySpec);
- } catch (NoSuchAlgorithmException nsae) {
- IOException ioe = new IOException("No RSA KeyFactory available");
- ioe.initCause(nsae);
- throw ioe;
- } catch (InvalidKeySpecException ikse) {
- IOException ioe = new IOException("No RSA KeyFactory available");
- ioe.initCause(ikse);
- throw ioe;
- }
- }
-
- public static byte[] encodeSSHRSAPublicKey(RSAPublicKey pk) throws IOException
- {
- TypesWriter tw = new TypesWriter();
-
- tw.writeString("ssh-rsa");
- tw.writeMPInt(pk.getPublicExponent());
- tw.writeMPInt(pk.getModulus());
-
- return tw.getBytes();
- }
-
- public static byte[] decodeSSHRSASignature(byte[] sig) throws IOException
- {
- TypesReader tr = new TypesReader(sig);
-
- String sig_format = tr.readString();
-
- if (sig_format.equals("ssh-rsa") == false)
- throw new IOException("Peer sent wrong signature format");
-
- /* S is NOT an MPINT. "The value for 'rsa_signature_blob' is encoded as a string
- * containing s (which is an integer, without lengths or padding, unsigned and in
- * network byte order)." See also below.
- */
-
- byte[] s = tr.readByteString();
-
- if (s.length == 0)
- throw new IOException("Error in RSA signature, S is empty.");
-
- if (log.isEnabled())
- {
- log.log(80, "Decoding ssh-rsa signature string (length: " + s.length + ")");
- }
-
- if (tr.remain() != 0)
- throw new IOException("Padding in RSA signature!");
-
- if (s[0] == 0 && s[1] == 0 && s[2] == 0) {
- int i = 0;
- int j = ((s[i++] << 24) & 0xff000000) | ((s[i++] << 16) & 0x00ff0000)
- | ((s[i++] << 8) & 0x0000ff00) | ((s[i++]) & 0x000000ff);
- i += j;
- j = ((s[i++] << 24) & 0xff000000) | ((s[i++] << 16) & 0x00ff0000)
- | ((s[i++] << 8) & 0x0000ff00) | ((s[i++]) & 0x000000ff);
- byte[] tmp = new byte[j];
- System.arraycopy(s, i, tmp, 0, j);
- sig = tmp;
- }
-
- return s;
- }
-
- public static byte[] encodeSSHRSASignature(byte[] s) throws IOException
- {
- TypesWriter tw = new TypesWriter();
-
- tw.writeString("ssh-rsa");
-
- /* S is NOT an MPINT. "The value for 'rsa_signature_blob' is encoded as a string
- * containing s (which is an integer, without lengths or padding, unsigned and in
- * network byte order)."
- */
-
- /* Remove first zero sign byte, if present */
-
- if ((s.length > 1) && (s[0] == 0x00))
- tw.writeString(s, 1, s.length - 1);
- else
- tw.writeString(s, 0, s.length);
-
- return tw.getBytes();
- }
-
- public static byte[] generateSignature(byte[] message, RSAPrivateKey pk) throws IOException
- {
- try {
- Signature s = Signature.getInstance("SHA1withRSA");
- s.initSign(pk);
- s.update(message);
- return s.sign();
- } catch (NoSuchAlgorithmException e) {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- } catch (InvalidKeyException e) {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- } catch (SignatureException e) {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- }
- }
-
- public static boolean verifySignature(byte[] message, byte[] ds, RSAPublicKey dpk) throws IOException
- {
- try {
- Signature s = Signature.getInstance("SHA1withRSA");
- s.initVerify(dpk);
- s.update(message);
- return s.verify(ds);
- } catch (NoSuchAlgorithmException e) {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- } catch (InvalidKeyException e) {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- } catch (SignatureException e) {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/transport/ClientServerHello.java b/app/src/main/java/com/trilead/ssh2/transport/ClientServerHello.java
deleted file mode 100644
index d7a5ee5..0000000
--- a/app/src/main/java/com/trilead/ssh2/transport/ClientServerHello.java
+++ /dev/null
@@ -1,125 +0,0 @@
-
-package com.trilead.ssh2.transport;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-
-import com.trilead.ssh2.Connection;
-
-/**
- * ClientServerHello.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: ClientServerHello.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
- */
-public class ClientServerHello
-{
- String server_line;
- String client_line;
-
- String server_versioncomment;
-
- public final static int readLineRN(InputStream is, byte[] buffer) throws IOException
- {
- int pos = 0;
- boolean need10 = false;
- int len = 0;
- while (true)
- {
- int c = is.read();
- if (c == -1)
- throw new IOException("Premature connection close");
-
- buffer[pos++] = (byte) c;
-
- if (c == 13)
- {
- need10 = true;
- continue;
- }
-
- if (c == 10)
- break;
-
- if (need10 == true)
- throw new IOException("Malformed line sent by the server, the line does not end correctly.");
-
- len++;
- if (pos >= buffer.length)
- throw new IOException("The server sent a too long line.");
- }
-
- return len;
- }
-
- public ClientServerHello(InputStream bi, OutputStream bo) throws IOException
- {
- client_line = "SSH-2.0-" + Connection.identification;
-
- bo.write((client_line + "\r\n").getBytes("ISO-8859-1"));
- bo.flush();
-
- byte[] serverVersion = new byte[512];
-
- for (int i = 0; i < 50; i++)
- {
- int len = readLineRN(bi, serverVersion);
-
- server_line = new String(serverVersion, 0, len, "ISO-8859-1");
-
- if (server_line.startsWith("SSH-"))
- break;
- }
-
- if (server_line.startsWith("SSH-") == false)
- throw new IOException(
- "Malformed server identification string. There was no line starting with 'SSH-' amongst the first 50 lines.");
-
- if (server_line.startsWith("SSH-1.99-"))
- server_versioncomment = server_line.substring(9);
- else if (server_line.startsWith("SSH-2.0-"))
- server_versioncomment = server_line.substring(8);
- else
- throw new IOException("Server uses incompatible protocol, it is not SSH-2 compatible.");
- }
-
- /**
- * @return Returns the client_versioncomment.
- */
- public byte[] getClientString()
- {
- byte[] result;
-
- try
- {
- result = client_line.getBytes("ISO-8859-1");
- }
- catch (UnsupportedEncodingException ign)
- {
- result = client_line.getBytes();
- }
-
- return result;
- }
-
- /**
- * @return Returns the server_versioncomment.
- */
- public byte[] getServerString()
- {
- byte[] result;
-
- try
- {
- result = server_line.getBytes("ISO-8859-1");
- }
- catch (UnsupportedEncodingException ign)
- {
- result = server_line.getBytes();
- }
-
- return result;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/transport/KexManager.java b/app/src/main/java/com/trilead/ssh2/transport/KexManager.java
deleted file mode 100644
index ee0784a..0000000
--- a/app/src/main/java/com/trilead/ssh2/transport/KexManager.java
+++ /dev/null
@@ -1,690 +0,0 @@
-
-package com.trilead.ssh2.transport;
-
-import java.io.IOException;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.interfaces.DSAPublicKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAPublicKey;
-import java.util.LinkedHashSet;
-import java.util.Set;
-import java.util.TreeSet;
-
-import com.trilead.ssh2.ConnectionInfo;
-import com.trilead.ssh2.DHGexParameters;
-import com.trilead.ssh2.ServerHostKeyVerifier;
-import com.trilead.ssh2.compression.CompressionFactory;
-import com.trilead.ssh2.compression.ICompressor;
-import com.trilead.ssh2.crypto.CryptoWishList;
-import com.trilead.ssh2.crypto.KeyMaterial;
-import com.trilead.ssh2.crypto.cipher.BlockCipher;
-import com.trilead.ssh2.crypto.cipher.BlockCipherFactory;
-import com.trilead.ssh2.crypto.dh.DhGroupExchange;
-import com.trilead.ssh2.crypto.dh.GenericDhExchange;
-import com.trilead.ssh2.crypto.digest.MAC;
-import com.trilead.ssh2.log.Logger;
-import com.trilead.ssh2.packets.PacketKexDHInit;
-import com.trilead.ssh2.packets.PacketKexDHReply;
-import com.trilead.ssh2.packets.PacketKexDhGexGroup;
-import com.trilead.ssh2.packets.PacketKexDhGexInit;
-import com.trilead.ssh2.packets.PacketKexDhGexReply;
-import com.trilead.ssh2.packets.PacketKexDhGexRequest;
-import com.trilead.ssh2.packets.PacketKexDhGexRequestOld;
-import com.trilead.ssh2.packets.PacketKexInit;
-import com.trilead.ssh2.packets.PacketNewKeys;
-import com.trilead.ssh2.packets.Packets;
-import com.trilead.ssh2.signature.DSASHA1Verify;
-import com.trilead.ssh2.signature.ECDSASHA2Verify;
-import com.trilead.ssh2.signature.RSASHA1Verify;
-
-
-/**
- * KexManager.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: KexManager.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public class KexManager
-{
- private static final Logger log = Logger.getLogger(KexManager.class);
-
- private static final boolean supportsEc;
- static {
- KeyFactory keyFact;
- try {
- keyFact = KeyFactory.getInstance("EC");
- } catch (NoSuchAlgorithmException ignored) {
- keyFact = null;
- log.log(10, "Disabling EC support due to lack of KeyFactory");
- }
- supportsEc = keyFact != null;
- }
-
- private static final Set<String> HOSTKEY_ALGS = new LinkedHashSet<String>();
- static {
- if (supportsEc) {
- HOSTKEY_ALGS.add("ecdsa-sha2-nistp256");
- HOSTKEY_ALGS.add("ecdsa-sha2-nistp384");
- HOSTKEY_ALGS.add("ecdsa-sha2-nistp521");
- }
- HOSTKEY_ALGS.add("ssh-rsa");
- HOSTKEY_ALGS.add("ssh-dss");
- }
-
- private static final Set<String> KEX_ALGS = new LinkedHashSet<String>();
- static {
- if (supportsEc) {
- KEX_ALGS.add("ecdh-sha2-nistp256");
- KEX_ALGS.add("ecdh-sha2-nistp384");
- KEX_ALGS.add("ecdh-sha2-nistp521");
- }
- KEX_ALGS.add("diffie-hellman-group-exchange-sha256");
- KEX_ALGS.add("diffie-hellman-group-exchange-sha1");
- KEX_ALGS.add("diffie-hellman-group14-sha1");
- KEX_ALGS.add("diffie-hellman-group1-sha1");
- }
-
- KexState kxs;
- int kexCount = 0;
- KeyMaterial km;
- byte[] sessionId;
- ClientServerHello csh;
-
- final Object accessLock = new Object();
- ConnectionInfo lastConnInfo = null;
-
- boolean connectionClosed = false;
-
- boolean ignore_next_kex_packet = false;
-
- final TransportManager tm;
-
- CryptoWishList nextKEXcryptoWishList;
- DHGexParameters nextKEXdhgexParameters;
-
- ServerHostKeyVerifier verifier;
- final String hostname;
- final int port;
- final SecureRandom rnd;
-
- public KexManager(TransportManager tm, ClientServerHello csh, CryptoWishList initialCwl, String hostname, int port,
- ServerHostKeyVerifier keyVerifier, SecureRandom rnd)
- {
- this.tm = tm;
- this.csh = csh;
- this.nextKEXcryptoWishList = initialCwl;
- this.nextKEXdhgexParameters = new DHGexParameters();
- this.hostname = hostname;
- this.port = port;
- this.verifier = keyVerifier;
- this.rnd = rnd;
- }
-
- public ConnectionInfo getOrWaitForConnectionInfo(int minKexCount) throws IOException
- {
- synchronized (accessLock)
- {
- while (true)
- {
- if ((lastConnInfo != null) && (lastConnInfo.keyExchangeCounter >= minKexCount))
- return lastConnInfo;
-
- if (connectionClosed)
- throw (IOException) new IOException("Key exchange was not finished, connection is closed.")
- .initCause(tm.getReasonClosedCause());
-
- try
- {
- accessLock.wait();
- }
- catch (InterruptedException e)
- {
- }
- }
- }
- }
-
- private String getFirstMatch(String[] client, String[] server) throws NegotiateException
- {
- if (client == null || server == null)
- throw new IllegalArgumentException();
-
- if (client.length == 0)
- return null;
-
- for (int i = 0; i < client.length; i++)
- {
- for (int j = 0; j < server.length; j++)
- {
- if (client[i].equals(server[j]))
- return client[i];
- }
- }
- throw new NegotiateException();
- }
-
- private boolean compareFirstOfNameList(String[] a, String[] b)
- {
- if (a == null || b == null)
- throw new IllegalArgumentException();
-
- if ((a.length == 0) && (b.length == 0))
- return true;
-
- if ((a.length == 0) || (b.length == 0))
- return false;
-
- return (a[0].equals(b[0]));
- }
-
- private boolean isGuessOK(KexParameters cpar, KexParameters spar)
- {
- if (cpar == null || spar == null)
- throw new IllegalArgumentException();
-
- if (compareFirstOfNameList(cpar.kex_algorithms, spar.kex_algorithms) == false)
- {
- return false;
- }
-
- if (compareFirstOfNameList(cpar.server_host_key_algorithms, spar.server_host_key_algorithms) == false)
- {
- return false;
- }
-
- /*
- * We do NOT check here if the other algorithms can be agreed on, this
- * is just a check if kex_algorithms and server_host_key_algorithms were
- * guessed right!
- */
-
- return true;
- }
-
- private NegotiatedParameters mergeKexParameters(KexParameters client, KexParameters server)
- {
- NegotiatedParameters np = new NegotiatedParameters();
-
- try
- {
- np.kex_algo = getFirstMatch(client.kex_algorithms, server.kex_algorithms);
-
- log.log(20, "kex_algo=" + np.kex_algo);
-
- np.server_host_key_algo = getFirstMatch(client.server_host_key_algorithms,
- server.server_host_key_algorithms);
-
- log.log(20, "server_host_key_algo=" + np.server_host_key_algo);
-
- np.enc_algo_client_to_server = getFirstMatch(client.encryption_algorithms_client_to_server,
- server.encryption_algorithms_client_to_server);
- np.enc_algo_server_to_client = getFirstMatch(client.encryption_algorithms_server_to_client,
- server.encryption_algorithms_server_to_client);
-
- log.log(20, "enc_algo_client_to_server=" + np.enc_algo_client_to_server);
- log.log(20, "enc_algo_server_to_client=" + np.enc_algo_server_to_client);
-
- np.mac_algo_client_to_server = getFirstMatch(client.mac_algorithms_client_to_server,
- server.mac_algorithms_client_to_server);
- np.mac_algo_server_to_client = getFirstMatch(client.mac_algorithms_server_to_client,
- server.mac_algorithms_server_to_client);
-
- log.log(20, "mac_algo_client_to_server=" + np.mac_algo_client_to_server);
- log.log(20, "mac_algo_server_to_client=" + np.mac_algo_server_to_client);
-
- np.comp_algo_client_to_server = getFirstMatch(client.compression_algorithms_client_to_server,
- server.compression_algorithms_client_to_server);
- np.comp_algo_server_to_client = getFirstMatch(client.compression_algorithms_server_to_client,
- server.compression_algorithms_server_to_client);
-
- log.log(20, "comp_algo_client_to_server=" + np.comp_algo_client_to_server);
- log.log(20, "comp_algo_server_to_client=" + np.comp_algo_server_to_client);
-
- }
- catch (NegotiateException e)
- {
- return null;
- }
-
- try
- {
- np.lang_client_to_server = getFirstMatch(client.languages_client_to_server,
- server.languages_client_to_server);
- }
- catch (NegotiateException e1)
- {
- np.lang_client_to_server = null;
- }
-
- try
- {
- np.lang_server_to_client = getFirstMatch(client.languages_server_to_client,
- server.languages_server_to_client);
- }
- catch (NegotiateException e2)
- {
- np.lang_server_to_client = null;
- }
-
- if (isGuessOK(client, server))
- np.guessOK = true;
-
- return np;
- }
-
- public synchronized void initiateKEX(CryptoWishList cwl, DHGexParameters dhgex) throws IOException
- {
- nextKEXcryptoWishList = cwl;
- nextKEXdhgexParameters = dhgex;
-
- if (kxs == null)
- {
- kxs = new KexState();
-
- kxs.dhgexParameters = nextKEXdhgexParameters;
- PacketKexInit kp = new PacketKexInit(nextKEXcryptoWishList);
- kxs.localKEX = kp;
- tm.sendKexMessage(kp.getPayload());
- }
- }
-
- private boolean establishKeyMaterial()
- {
- try
- {
- int mac_cs_key_len = MAC.getKeyLen(kxs.np.mac_algo_client_to_server);
- int enc_cs_key_len = BlockCipherFactory.getKeySize(kxs.np.enc_algo_client_to_server);
- int enc_cs_block_len = BlockCipherFactory.getBlockSize(kxs.np.enc_algo_client_to_server);
-
- int mac_sc_key_len = MAC.getKeyLen(kxs.np.mac_algo_server_to_client);
- int enc_sc_key_len = BlockCipherFactory.getKeySize(kxs.np.enc_algo_server_to_client);
- int enc_sc_block_len = BlockCipherFactory.getBlockSize(kxs.np.enc_algo_server_to_client);
-
- km = KeyMaterial.create(kxs.hashAlgo, kxs.H, kxs.K, sessionId, enc_cs_key_len, enc_cs_block_len, mac_cs_key_len,
- enc_sc_key_len, enc_sc_block_len, mac_sc_key_len);
- }
- catch (IllegalArgumentException e)
- {
- return false;
- }
- return true;
- }
-
- private void finishKex() throws IOException
- {
- if (sessionId == null)
- sessionId = kxs.H;
-
- establishKeyMaterial();
-
- /* Tell the other side that we start using the new material */
-
- PacketNewKeys ign = new PacketNewKeys();
- tm.sendKexMessage(ign.getPayload());
-
- BlockCipher cbc;
- MAC mac;
- ICompressor comp;
-
- try
- {
- cbc = BlockCipherFactory.createCipher(kxs.np.enc_algo_client_to_server, true, km.enc_key_client_to_server,
- km.initial_iv_client_to_server);
-
- mac = new MAC(kxs.np.mac_algo_client_to_server, km.integrity_key_client_to_server);
-
- comp = CompressionFactory.createCompressor(kxs.np.comp_algo_client_to_server);
-
- }
- catch (IllegalArgumentException e1)
- {
- throw new IOException("Fatal error during MAC startup!");
- }
-
- tm.changeSendCipher(cbc, mac);
- tm.changeSendCompression(comp);
- tm.kexFinished();
- }
-
- public static final String[] getDefaultServerHostkeyAlgorithmList()
- {
- return HOSTKEY_ALGS.toArray(new String[HOSTKEY_ALGS.size()]);
- }
-
- public static final void checkServerHostkeyAlgorithmsList(String[] algos)
- {
- for (int i = 0; i < algos.length; i++)
- {
- if (!HOSTKEY_ALGS.contains(algos[i]))
- throw new IllegalArgumentException("Unknown server host key algorithm '" + algos[i] + "'");
- }
- }
-
- public static final String[] getDefaultKexAlgorithmList()
- {
- return KEX_ALGS.toArray(new String[KEX_ALGS.size()]);
- }
-
- public static final void checkKexAlgorithmList(String[] algos)
- {
- for (int i = 0; i < algos.length; i++)
- {
- if (!KEX_ALGS.contains(algos[i]))
- throw new IllegalArgumentException("Unknown kex algorithm '" + algos[i] + "'");
- }
- }
-
- private boolean verifySignature(byte[] sig, byte[] hostkey) throws IOException
- {
- if (kxs.np.server_host_key_algo.startsWith("ecdsa-sha2-"))
- {
- byte[] rs = ECDSASHA2Verify.decodeSSHECDSASignature(sig);
- ECPublicKey epk = ECDSASHA2Verify.decodeSSHECDSAPublicKey(hostkey);
-
- log.log(50, "Verifying ecdsa signature");
-
- return ECDSASHA2Verify.verifySignature(kxs.H, rs, epk);
- }
-
- if (kxs.np.server_host_key_algo.equals("ssh-rsa"))
- {
- byte[] rs = RSASHA1Verify.decodeSSHRSASignature(sig);
- RSAPublicKey rpk = RSASHA1Verify.decodeSSHRSAPublicKey(hostkey);
-
- log.log(50, "Verifying ssh-rsa signature");
-
- return RSASHA1Verify.verifySignature(kxs.H, rs, rpk);
- }
-
- if (kxs.np.server_host_key_algo.equals("ssh-dss"))
- {
- byte[] ds = DSASHA1Verify.decodeSSHDSASignature(sig);
- DSAPublicKey dpk = DSASHA1Verify.decodeSSHDSAPublicKey(hostkey);
-
- log.log(50, "Verifying ssh-dss signature");
-
- return DSASHA1Verify.verifySignature(kxs.H, ds, dpk);
- }
-
- throw new IOException("Unknown server host key algorithm '" + kxs.np.server_host_key_algo + "'");
- }
-
- public synchronized void handleMessage(byte[] msg, int msglen) throws IOException
- {
- PacketKexInit kip;
-
- if (msg == null)
- {
- synchronized (accessLock)
- {
- connectionClosed = true;
- accessLock.notifyAll();
- return;
- }
- }
-
- if ((kxs == null) && (msg[0] != Packets.SSH_MSG_KEXINIT))
- throw new IOException("Unexpected KEX message (type " + msg[0] + ")");
-
- if (ignore_next_kex_packet)
- {
- ignore_next_kex_packet = false;
- return;
- }
-
- if (msg[0] == Packets.SSH_MSG_KEXINIT)
- {
- if ((kxs != null) && (kxs.state != 0))
- throw new IOException("Unexpected SSH_MSG_KEXINIT message during on-going kex exchange!");
-
- if (kxs == null)
- {
- /*
- * Ah, OK, peer wants to do KEX. Let's be nice and play
- * together.
- */
- kxs = new KexState();
- kxs.dhgexParameters = nextKEXdhgexParameters;
- kip = new PacketKexInit(nextKEXcryptoWishList);
- kxs.localKEX = kip;
- tm.sendKexMessage(kip.getPayload());
- }
-
- kip = new PacketKexInit(msg, 0, msglen);
- kxs.remoteKEX = kip;
-
- kxs.np = mergeKexParameters(kxs.localKEX.getKexParameters(), kxs.remoteKEX.getKexParameters());
-
- if (kxs.np == null)
- throw new IOException("Cannot negotiate, proposals do not match.");
-
- if (kxs.remoteKEX.isFirst_kex_packet_follows() && (kxs.np.guessOK == false))
- {
- /*
- * Guess was wrong, we need to ignore the next kex packet.
- */
-
- ignore_next_kex_packet = true;
- }
-
- if (kxs.np.kex_algo.equals("diffie-hellman-group-exchange-sha1")
- || kxs.np.kex_algo.equals("diffie-hellman-group-exchange-sha256"))
- {
- if (kxs.dhgexParameters.getMin_group_len() == 0 || csh.server_versioncomment.matches("OpenSSH_2\\.([0-4]\\.|5\\.[0-2]).*"))
- {
- PacketKexDhGexRequestOld dhgexreq = new PacketKexDhGexRequestOld(kxs.dhgexParameters);
- tm.sendKexMessage(dhgexreq.getPayload());
- }
- else
- {
- PacketKexDhGexRequest dhgexreq = new PacketKexDhGexRequest(kxs.dhgexParameters);
- tm.sendKexMessage(dhgexreq.getPayload());
- }
- if (kxs.np.kex_algo.endsWith("sha1")) {
- kxs.hashAlgo = "SHA1";
- } else {
- kxs.hashAlgo = "SHA-256";
- }
- kxs.state = 1;
- return;
- }
-
- if (kxs.np.kex_algo.equals("diffie-hellman-group1-sha1")
- || kxs.np.kex_algo.equals("diffie-hellman-group14-sha1")
- || kxs.np.kex_algo.equals("ecdh-sha2-nistp256")
- || kxs.np.kex_algo.equals("ecdh-sha2-nistp384")
- || kxs.np.kex_algo.equals("ecdh-sha2-nistp521")) {
- kxs.dhx = GenericDhExchange.getInstance(kxs.np.kex_algo);
-
- kxs.dhx.init(kxs.np.kex_algo);
- kxs.hashAlgo = kxs.dhx.getHashAlgo();
-
- PacketKexDHInit kp = new PacketKexDHInit(kxs.dhx.getE());
- tm.sendKexMessage(kp.getPayload());
- kxs.state = 1;
- return;
- }
-
- throw new IllegalStateException("Unknown KEX method!");
- }
-
- if (msg[0] == Packets.SSH_MSG_NEWKEYS)
- {
- if (km == null)
- throw new IOException("Peer sent SSH_MSG_NEWKEYS, but I have no key material ready!");
-
- BlockCipher cbc;
- MAC mac;
- ICompressor comp;
-
- try
- {
- cbc = BlockCipherFactory.createCipher(kxs.np.enc_algo_server_to_client, false,
- km.enc_key_server_to_client, km.initial_iv_server_to_client);
-
- mac = new MAC(kxs.np.mac_algo_server_to_client, km.integrity_key_server_to_client);
-
- comp = CompressionFactory.createCompressor(kxs.np.comp_algo_server_to_client);
- }
- catch (IllegalArgumentException e1)
- {
- throw new IOException("Fatal error during MAC startup!");
- }
-
- tm.changeRecvCipher(cbc, mac);
- tm.changeRecvCompression(comp);
-
- ConnectionInfo sci = new ConnectionInfo();
-
- kexCount++;
-
- sci.keyExchangeAlgorithm = kxs.np.kex_algo;
- sci.keyExchangeCounter = kexCount;
- sci.clientToServerCryptoAlgorithm = kxs.np.enc_algo_client_to_server;
- sci.serverToClientCryptoAlgorithm = kxs.np.enc_algo_server_to_client;
- sci.clientToServerMACAlgorithm = kxs.np.mac_algo_client_to_server;
- sci.serverToClientMACAlgorithm = kxs.np.mac_algo_server_to_client;
- sci.serverHostKeyAlgorithm = kxs.np.server_host_key_algo;
- sci.serverHostKey = kxs.hostkey;
-
- synchronized (accessLock)
- {
- lastConnInfo = sci;
- accessLock.notifyAll();
- }
-
- kxs = null;
- return;
- }
-
- if ((kxs == null) || (kxs.state == 0))
- throw new IOException("Unexpected Kex submessage!");
-
- if (kxs.np.kex_algo.equals("diffie-hellman-group-exchange-sha1")
- || kxs.np.kex_algo.equals("diffie-hellman-group-exchange-sha256"))
- {
- if (kxs.state == 1)
- {
- PacketKexDhGexGroup dhgexgrp = new PacketKexDhGexGroup(msg, 0, msglen);
- kxs.dhgx = new DhGroupExchange(dhgexgrp.getP(), dhgexgrp.getG());
- kxs.dhgx.init(rnd);
- PacketKexDhGexInit dhgexinit = new PacketKexDhGexInit(kxs.dhgx.getE());
- tm.sendKexMessage(dhgexinit.getPayload());
- kxs.state = 2;
- return;
- }
-
- if (kxs.state == 2)
- {
- PacketKexDhGexReply dhgexrpl = new PacketKexDhGexReply(msg, 0, msglen);
-
- kxs.hostkey = dhgexrpl.getHostKey();
-
- if (verifier != null)
- {
- boolean vres = false;
-
- try
- {
- vres = verifier.verifyServerHostKey(hostname, port, kxs.np.server_host_key_algo, kxs.hostkey);
- }
- catch (Exception e)
- {
- throw (IOException) new IOException(
- "The server hostkey was not accepted by the verifier callback.").initCause(e);
- }
-
- if (vres == false)
- throw new IOException("The server hostkey was not accepted by the verifier callback");
- }
-
- kxs.dhgx.setF(dhgexrpl.getF());
-
- try
- {
- kxs.H = kxs.dhgx.calculateH(kxs.hashAlgo,
- csh.getClientString(), csh.getServerString(),
- kxs.localKEX.getPayload(), kxs.remoteKEX.getPayload(),
- dhgexrpl.getHostKey(), kxs.dhgexParameters);
- }
- catch (IllegalArgumentException e)
- {
- throw (IOException) new IOException("KEX error.").initCause(e);
- }
-
- boolean res = verifySignature(dhgexrpl.getSignature(), kxs.hostkey);
-
- if (res == false)
- throw new IOException("Hostkey signature sent by remote is wrong!");
-
- kxs.K = kxs.dhgx.getK();
-
- finishKex();
- kxs.state = -1;
- return;
- }
-
- throw new IllegalStateException("Illegal State in KEX Exchange!");
- }
-
- if (kxs.np.kex_algo.equals("diffie-hellman-group1-sha1")
- || kxs.np.kex_algo.equals("diffie-hellman-group14-sha1")
- || kxs.np.kex_algo.equals("ecdh-sha2-nistp256")
- || kxs.np.kex_algo.equals("ecdh-sha2-nistp384")
- || kxs.np.kex_algo.equals("ecdh-sha2-nistp521"))
- {
- if (kxs.state == 1)
- {
-
- PacketKexDHReply dhr = new PacketKexDHReply(msg, 0, msglen);
-
- kxs.hostkey = dhr.getHostKey();
-
- if (verifier != null)
- {
- boolean vres = false;
-
- try
- {
- vres = verifier.verifyServerHostKey(hostname, port, kxs.np.server_host_key_algo, kxs.hostkey);
- }
- catch (Exception e)
- {
- throw (IOException) new IOException(
- "The server hostkey was not accepted by the verifier callback.").initCause(e);
- }
-
- if (vres == false)
- throw new IOException("The server hostkey was not accepted by the verifier callback");
- }
-
- kxs.dhx.setF(dhr.getF());
-
- try
- {
- kxs.H = kxs.dhx.calculateH(csh.getClientString(), csh.getServerString(), kxs.localKEX.getPayload(),
- kxs.remoteKEX.getPayload(), dhr.getHostKey());
- }
- catch (IllegalArgumentException e)
- {
- throw (IOException) new IOException("KEX error.").initCause(e);
- }
-
- boolean res = verifySignature(dhr.getSignature(), kxs.hostkey);
-
- if (res == false)
- throw new IOException("Hostkey signature sent by remote is wrong!");
-
- kxs.K = kxs.dhx.getK();
-
- finishKex();
- kxs.state = -1;
- return;
- }
- }
-
- throw new IllegalStateException("Unkown KEX method! (" + kxs.np.kex_algo + ")");
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/transport/KexParameters.java b/app/src/main/java/com/trilead/ssh2/transport/KexParameters.java
deleted file mode 100644
index 70bcf3e..0000000
--- a/app/src/main/java/com/trilead/ssh2/transport/KexParameters.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.trilead.ssh2.transport;
-
-/**
- * KexParameters.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: KexParameters.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public class KexParameters
-{
- public byte[] cookie;
- public String[] kex_algorithms;
- public String[] server_host_key_algorithms;
- public String[] encryption_algorithms_client_to_server;
- public String[] encryption_algorithms_server_to_client;
- public String[] mac_algorithms_client_to_server;
- public String[] mac_algorithms_server_to_client;
- public String[] compression_algorithms_client_to_server;
- public String[] compression_algorithms_server_to_client;
- public String[] languages_client_to_server;
- public String[] languages_server_to_client;
- public boolean first_kex_packet_follows;
- public int reserved_field1;
-}
diff --git a/app/src/main/java/com/trilead/ssh2/transport/KexState.java b/app/src/main/java/com/trilead/ssh2/transport/KexState.java
deleted file mode 100644
index 8611f3f..0000000
--- a/app/src/main/java/com/trilead/ssh2/transport/KexState.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.trilead.ssh2.transport;
-
-
-import java.math.BigInteger;
-
-import com.trilead.ssh2.DHGexParameters;
-import com.trilead.ssh2.crypto.dh.DhGroupExchange;
-import com.trilead.ssh2.crypto.dh.GenericDhExchange;
-import com.trilead.ssh2.packets.PacketKexInit;
-
-/**
- * KexState.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: KexState.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
- */
-public class KexState
-{
- public PacketKexInit localKEX;
- public PacketKexInit remoteKEX;
- public NegotiatedParameters np;
- public int state = 0;
-
- public BigInteger K;
- public byte[] H;
-
- public byte[] hostkey;
-
- public String hashAlgo;
- public GenericDhExchange dhx;
- public DhGroupExchange dhgx;
- public DHGexParameters dhgexParameters;
-}
diff --git a/app/src/main/java/com/trilead/ssh2/transport/MessageHandler.java b/app/src/main/java/com/trilead/ssh2/transport/MessageHandler.java
deleted file mode 100644
index 039d473..0000000
--- a/app/src/main/java/com/trilead/ssh2/transport/MessageHandler.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.trilead.ssh2.transport;
-
-import java.io.IOException;
-
-/**
- * MessageHandler.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: MessageHandler.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public interface MessageHandler
-{
- public void handleMessage(byte[] msg, int msglen) throws IOException;
-}
diff --git a/app/src/main/java/com/trilead/ssh2/transport/NegotiateException.java b/app/src/main/java/com/trilead/ssh2/transport/NegotiateException.java
deleted file mode 100644
index ff53097..0000000
--- a/app/src/main/java/com/trilead/ssh2/transport/NegotiateException.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.trilead.ssh2.transport;
-
-/**
- * NegotiateException.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: NegotiateException.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public class NegotiateException extends Exception
-{
- private static final long serialVersionUID = 3689910669428143157L;
-}
diff --git a/app/src/main/java/com/trilead/ssh2/transport/NegotiatedParameters.java b/app/src/main/java/com/trilead/ssh2/transport/NegotiatedParameters.java
deleted file mode 100644
index e9f3a0a..0000000
--- a/app/src/main/java/com/trilead/ssh2/transport/NegotiatedParameters.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.trilead.ssh2.transport;
-
-/**
- * NegotiatedParameters.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: NegotiatedParameters.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
- */
-public class NegotiatedParameters
-{
- public boolean guessOK;
- public String kex_algo;
- public String server_host_key_algo;
- public String enc_algo_client_to_server;
- public String enc_algo_server_to_client;
- public String mac_algo_client_to_server;
- public String mac_algo_server_to_client;
- public String comp_algo_client_to_server;
- public String comp_algo_server_to_client;
- public String lang_client_to_server;
- public String lang_server_to_client;
-}
diff --git a/app/src/main/java/com/trilead/ssh2/transport/TransportConnection.java b/app/src/main/java/com/trilead/ssh2/transport/TransportConnection.java
deleted file mode 100644
index 906c3c9..0000000
--- a/app/src/main/java/com/trilead/ssh2/transport/TransportConnection.java
+++ /dev/null
@@ -1,343 +0,0 @@
-
-package com.trilead.ssh2.transport;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.SecureRandom;
-
-import com.trilead.ssh2.compression.ICompressor;
-import com.trilead.ssh2.crypto.cipher.BlockCipher;
-import com.trilead.ssh2.crypto.cipher.CipherInputStream;
-import com.trilead.ssh2.crypto.cipher.CipherOutputStream;
-import com.trilead.ssh2.crypto.cipher.NullCipher;
-import com.trilead.ssh2.crypto.digest.MAC;
-import com.trilead.ssh2.log.Logger;
-import com.trilead.ssh2.packets.Packets;
-
-
-/**
- * TransportConnection.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: TransportConnection.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
- */
-public class TransportConnection
-{
- private static final Logger log = Logger.getLogger(TransportConnection.class);
-
- int send_seq_number = 0;
-
- int recv_seq_number = 0;
-
- CipherInputStream cis;
-
- CipherOutputStream cos;
-
- boolean useRandomPadding = false;
-
- /* Depends on current MAC and CIPHER */
-
- MAC send_mac;
-
- byte[] send_mac_buffer;
-
- int send_padd_blocksize = 8;
-
- MAC recv_mac;
-
- byte[] recv_mac_buffer;
-
- byte[] recv_mac_buffer_cmp;
-
- int recv_padd_blocksize = 8;
-
- ICompressor recv_comp = null;
-
- ICompressor send_comp = null;
-
- boolean can_recv_compress = false;
-
- boolean can_send_compress = false;
-
- byte[] recv_comp_buffer;
-
- byte[] send_comp_buffer;
-
- /* won't change */
-
- final byte[] send_padding_buffer = new byte[256];
-
- final byte[] send_packet_header_buffer = new byte[5];
-
- final byte[] recv_padding_buffer = new byte[256];
-
- final byte[] recv_packet_header_buffer = new byte[5];
-
- boolean recv_packet_header_present = false;
-
- ClientServerHello csh;
-
- final SecureRandom rnd;
-
- public TransportConnection(InputStream is, OutputStream os, SecureRandom rnd)
- {
- this.cis = new CipherInputStream(new NullCipher(), is);
- this.cos = new CipherOutputStream(new NullCipher(), os);
- this.rnd = rnd;
- }
-
- public void changeRecvCipher(BlockCipher bc, MAC mac)
- {
- cis.changeCipher(bc);
- recv_mac = mac;
- recv_mac_buffer = (mac != null) ? new byte[mac.size()] : null;
- recv_mac_buffer_cmp = (mac != null) ? new byte[mac.size()] : null;
- recv_padd_blocksize = bc.getBlockSize();
- if (recv_padd_blocksize < 8)
- recv_padd_blocksize = 8;
- }
-
- public void changeSendCipher(BlockCipher bc, MAC mac)
- {
- if ((bc instanceof NullCipher) == false)
- {
- /* Only use zero byte padding for the first few packets */
- useRandomPadding = true;
- /* Once we start encrypting, there is no way back */
- }
-
- cos.changeCipher(bc);
- send_mac = mac;
- send_mac_buffer = (mac != null) ? new byte[mac.size()] : null;
- send_padd_blocksize = bc.getBlockSize();
- if (send_padd_blocksize < 8)
- send_padd_blocksize = 8;
- }
-
- public void changeRecvCompression(ICompressor comp)
- {
- recv_comp = comp;
-
- if (comp != null) {
- recv_comp_buffer = new byte[comp.getBufferSize()];
- can_recv_compress |= recv_comp.canCompressPreauth();
- }
- }
-
- public void changeSendCompression(ICompressor comp)
- {
- send_comp = comp;
-
- if (comp != null) {
- send_comp_buffer = new byte[comp.getBufferSize()];
- can_send_compress |= send_comp.canCompressPreauth();
- }
- }
-
- public void sendMessage(byte[] message) throws IOException
- {
- sendMessage(message, 0, message.length, 0);
- }
-
- public void sendMessage(byte[] message, int off, int len) throws IOException
- {
- sendMessage(message, off, len, 0);
- }
-
- public int getPacketOverheadEstimate()
- {
- // return an estimate for the paket overhead (for send operations)
- return 5 + 4 + (send_padd_blocksize - 1) + send_mac_buffer.length;
- }
-
- public void sendMessage(byte[] message, int off, int len, int padd) throws IOException
- {
- if (padd < 4)
- padd = 4;
- else if (padd > 64)
- padd = 64;
-
- if (send_comp != null && can_send_compress) {
- if (send_comp_buffer.length < message.length + 1024)
- send_comp_buffer = new byte[message.length + 1024];
- len = send_comp.compress(message, off, len, send_comp_buffer);
- message = send_comp_buffer;
- }
-
- int packet_len = 5 + len + padd; /* Minimum allowed padding is 4 */
-
- int slack = packet_len % send_padd_blocksize;
-
- if (slack != 0)
- {
- packet_len += (send_padd_blocksize - slack);
- }
-
- if (packet_len < 16)
- packet_len = 16;
-
- int padd_len = packet_len - (5 + len);
-
- if (useRandomPadding)
- {
- for (int i = 0; i < padd_len; i = i + 4)
- {
- /*
- * don't waste calls to rnd.nextInt() (by using only 8bit of the
- * output). just believe me: even though we may write here up to 3
- * bytes which won't be used, there is no "buffer overflow" (i.e.,
- * arrayindexoutofbounds). the padding buffer is big enough =) (256
- * bytes, and that is bigger than any current cipher block size + 64).
- */
-
- int r = rnd.nextInt();
- send_padding_buffer[i] = (byte) r;
- send_padding_buffer[i + 1] = (byte) (r >> 8);
- send_padding_buffer[i + 2] = (byte) (r >> 16);
- send_padding_buffer[i + 3] = (byte) (r >> 24);
- }
- }
- else
- {
- /* use zero padding for unencrypted traffic */
- for (int i = 0; i < padd_len; i++)
- send_padding_buffer[i] = 0;
- /* Actually this code is paranoid: we never filled any
- * bytes into the padding buffer so far, therefore it should
- * consist of zeros only.
- */
- }
-
- send_packet_header_buffer[0] = (byte) ((packet_len - 4) >> 24);
- send_packet_header_buffer[1] = (byte) ((packet_len - 4) >> 16);
- send_packet_header_buffer[2] = (byte) ((packet_len - 4) >> 8);
- send_packet_header_buffer[3] = (byte) ((packet_len - 4));
- send_packet_header_buffer[4] = (byte) padd_len;
-
- cos.write(send_packet_header_buffer, 0, 5);
- cos.write(message, off, len);
- cos.write(send_padding_buffer, 0, padd_len);
-
- if (send_mac != null)
- {
- send_mac.initMac(send_seq_number);
- send_mac.update(send_packet_header_buffer, 0, 5);
- send_mac.update(message, off, len);
- send_mac.update(send_padding_buffer, 0, padd_len);
-
- send_mac.getMac(send_mac_buffer, 0);
- cos.writePlain(send_mac_buffer, 0, send_mac_buffer.length);
- }
-
- cos.flush();
-
- if (log.isEnabled())
- {
- log.log(90, "Sent " + Packets.getMessageName(message[off] & 0xff) + " " + len + " bytes payload");
- }
-
- send_seq_number++;
- }
-
- public int peekNextMessageLength() throws IOException
- {
- if (recv_packet_header_present == false)
- {
- cis.read(recv_packet_header_buffer, 0, 5);
- recv_packet_header_present = true;
- }
-
- int packet_length = ((recv_packet_header_buffer[0] & 0xff) << 24)
- | ((recv_packet_header_buffer[1] & 0xff) << 16) | ((recv_packet_header_buffer[2] & 0xff) << 8)
- | ((recv_packet_header_buffer[3] & 0xff));
-
- int padding_length = recv_packet_header_buffer[4] & 0xff;
-
- if (packet_length > 35000 || packet_length < 12)
- throw new IOException("Illegal packet size! (" + packet_length + ")");
-
- int payload_length = packet_length - padding_length - 1;
-
- if (payload_length < 0)
- throw new IOException("Illegal padding_length in packet from remote (" + padding_length + ")");
-
- return payload_length;
- }
-
- public int receiveMessage(byte buffer[], int off, int len) throws IOException
- {
- if (recv_packet_header_present == false)
- {
- cis.read(recv_packet_header_buffer, 0, 5);
- }
- else
- recv_packet_header_present = false;
-
- int packet_length = ((recv_packet_header_buffer[0] & 0xff) << 24)
- | ((recv_packet_header_buffer[1] & 0xff) << 16) | ((recv_packet_header_buffer[2] & 0xff) << 8)
- | ((recv_packet_header_buffer[3] & 0xff));
-
- int padding_length = recv_packet_header_buffer[4] & 0xff;
-
- if (packet_length > 35000 || packet_length < 12)
- throw new IOException("Illegal packet size! (" + packet_length + ")");
-
- int payload_length = packet_length - padding_length - 1;
-
- if (payload_length < 0)
- throw new IOException("Illegal padding_length in packet from remote (" + padding_length + ")");
-
- if (payload_length >= len)
- throw new IOException("Receive buffer too small (" + len + ", need " + payload_length + ")");
-
- cis.read(buffer, off, payload_length);
- cis.read(recv_padding_buffer, 0, padding_length);
-
- if (recv_mac != null)
- {
- cis.readPlain(recv_mac_buffer, 0, recv_mac_buffer.length);
-
- recv_mac.initMac(recv_seq_number);
- recv_mac.update(recv_packet_header_buffer, 0, 5);
- recv_mac.update(buffer, off, payload_length);
- recv_mac.update(recv_padding_buffer, 0, padding_length);
- recv_mac.getMac(recv_mac_buffer_cmp, 0);
-
- for (int i = 0; i < recv_mac_buffer.length; i++)
- {
- if (recv_mac_buffer[i] != recv_mac_buffer_cmp[i])
- throw new IOException("Remote sent corrupt MAC.");
- }
- }
-
- recv_seq_number++;
-
- if (log.isEnabled())
- {
- log.log(90, "Received " + Packets.getMessageName(buffer[off] & 0xff) + " " + payload_length
- + " bytes payload");
- }
-
- if (recv_comp != null && can_recv_compress) {
- int[] uncomp_len = new int[] { payload_length };
- buffer = recv_comp.uncompress(buffer, off, uncomp_len);
-
- if (buffer == null) {
- throw new IOException("Error while inflating remote data");
- } else {
- return uncomp_len[0];
- }
- } else {
- return payload_length;
- }
- }
-
- /**
- *
- */
- public void startCompression() {
- can_recv_compress = true;
- can_send_compress = true;
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/transport/TransportManager.java b/app/src/main/java/com/trilead/ssh2/transport/TransportManager.java
deleted file mode 100644
index 8f3406e..0000000
--- a/app/src/main/java/com/trilead/ssh2/transport/TransportManager.java
+++ /dev/null
@@ -1,750 +0,0 @@
-
-package com.trilead.ssh2.transport;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketTimeoutException;
-import java.net.UnknownHostException;
-import java.security.SecureRandom;
-import java.util.Vector;
-
-import com.trilead.ssh2.ConnectionInfo;
-import com.trilead.ssh2.ConnectionMonitor;
-import com.trilead.ssh2.DHGexParameters;
-import com.trilead.ssh2.HTTPProxyData;
-import com.trilead.ssh2.HTTPProxyException;
-import com.trilead.ssh2.ProxyData;
-import com.trilead.ssh2.ServerHostKeyVerifier;
-import com.trilead.ssh2.compression.ICompressor;
-import com.trilead.ssh2.crypto.Base64;
-import com.trilead.ssh2.crypto.CryptoWishList;
-import com.trilead.ssh2.crypto.cipher.BlockCipher;
-import com.trilead.ssh2.crypto.digest.MAC;
-import com.trilead.ssh2.log.Logger;
-import com.trilead.ssh2.packets.PacketDisconnect;
-import com.trilead.ssh2.packets.Packets;
-import com.trilead.ssh2.packets.TypesReader;
-import com.trilead.ssh2.util.Tokenizer;
-
-
-/*
- * Yes, the "standard" is a big mess. On one side, the say that arbitary channel
- * packets are allowed during kex exchange, on the other side we need to blindly
- * ignore the next _packet_ if the KEX guess was wrong. Where do we know from that
- * the next packet is not a channel data packet? Yes, we could check if it is in
- * the KEX range. But the standard says nothing about this. The OpenSSH guys
- * block local "normal" traffic during KEX. That's fine - however, they assume
- * that the other side is doing the same. During re-key, if they receive traffic
- * other than KEX, they become horribly irritated and kill the connection. Since
- * we are very likely going to communicate with OpenSSH servers, we have to play
- * the same game - even though we could do better.
- *
- * btw: having stdout and stderr on the same channel, with a shared window, is
- * also a VERY good idea... =(
- */
-
-/**
- * TransportManager.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: TransportManager.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
- */
-public class TransportManager
-{
- private static final Logger log = Logger.getLogger(TransportManager.class);
-
- class HandlerEntry
- {
- MessageHandler mh;
- int low;
- int high;
- }
-
- private final Vector<byte[]> asynchronousQueue = new Vector<byte[]>();
- private Thread asynchronousThread = null;
-
- class AsynchronousWorker extends Thread
- {
- public void run()
- {
- while (true)
- {
- byte[] msg = null;
-
- synchronized (asynchronousQueue)
- {
- if (asynchronousQueue.size() == 0)
- {
- /* After the queue is empty for about 2 seconds, stop this thread */
-
- try
- {
- asynchronousQueue.wait(2000);
- }
- catch (InterruptedException e)
- {
- /* OKOK, if somebody interrupts us, then we may die earlier. */
- }
-
- if (asynchronousQueue.size() == 0)
- {
- asynchronousThread = null;
- return;
- }
- }
-
- msg = asynchronousQueue.remove(0);
- }
-
- /* The following invocation may throw an IOException.
- * There is no point in handling it - it simply means
- * that the connection has a problem and we should stop
- * sending asynchronously messages. We do not need to signal that
- * we have exited (asynchronousThread = null): further
- * messages in the queue cannot be sent by this or any
- * other thread.
- * Other threads will sooner or later (when receiving or
- * sending the next message) get the same IOException and
- * get to the same conclusion.
- */
-
- try
- {
- sendMessage(msg);
- }
- catch (IOException e)
- {
- return;
- }
- }
- }
- }
-
- String hostname;
- int port;
- final Socket sock = new Socket();
-
- Object connectionSemaphore = new Object();
-
- boolean flagKexOngoing = false;
- boolean connectionClosed = false;
-
- Throwable reasonClosedCause = null;
-
- TransportConnection tc;
- KexManager km;
-
- Vector<HandlerEntry> messageHandlers = new Vector<HandlerEntry>();
-
- Thread receiveThread;
-
- Vector connectionMonitors = new Vector();
- boolean monitorsWereInformed = false;
-
- public TransportManager(String host, int port) throws IOException
- {
- this.hostname = host;
- this.port = port;
- }
-
- public int getPacketOverheadEstimate()
- {
- return tc.getPacketOverheadEstimate();
- }
-
- public void setTcpNoDelay(boolean state) throws IOException
- {
- sock.setTcpNoDelay(state);
- }
-
- public void setSoTimeout(int timeout) throws IOException
- {
- sock.setSoTimeout(timeout);
- }
-
- public ConnectionInfo getConnectionInfo(int kexNumber) throws IOException
- {
- return km.getOrWaitForConnectionInfo(kexNumber);
- }
-
- public Throwable getReasonClosedCause()
- {
- synchronized (connectionSemaphore)
- {
- return reasonClosedCause;
- }
- }
-
- public byte[] getSessionIdentifier()
- {
- return km.sessionId;
- }
-
- public void close(Throwable cause, boolean useDisconnectPacket)
- {
- if (useDisconnectPacket == false)
- {
- /* OK, hard shutdown - do not aquire the semaphore,
- * perhaps somebody is inside (and waits until the remote
- * side is ready to accept new data). */
-
- try
- {
- sock.close();
- }
- catch (IOException ignore)
- {
- }
-
- /* OK, whoever tried to send data, should now agree that
- * there is no point in further waiting =)
- * It is safe now to aquire the semaphore.
- */
- }
-
- synchronized (connectionSemaphore)
- {
- if (connectionClosed == false)
- {
- if (useDisconnectPacket == true)
- {
- try
- {
- byte[] msg = new PacketDisconnect(Packets.SSH_DISCONNECT_BY_APPLICATION, cause.getMessage(), "")
- .getPayload();
- if (tc != null)
- tc.sendMessage(msg);
- }
- catch (IOException ignore)
- {
- }
-
- try
- {
- sock.close();
- }
- catch (IOException ignore)
- {
- }
- }
-
- connectionClosed = true;
- reasonClosedCause = cause; /* may be null */
- }
- connectionSemaphore.notifyAll();
- }
-
- /* No check if we need to inform the monitors */
-
- Vector monitors = null;
-
- synchronized (this)
- {
- /* Short term lock to protect "connectionMonitors"
- * and "monitorsWereInformed"
- * (they may be modified concurrently)
- */
-
- if (monitorsWereInformed == false)
- {
- monitorsWereInformed = true;
- monitors = (Vector) connectionMonitors.clone();
- }
- }
-
- if (monitors != null)
- {
- for (int i = 0; i < monitors.size(); i++)
- {
- try
- {
- ConnectionMonitor cmon = (ConnectionMonitor) monitors.elementAt(i);
- cmon.connectionLost(reasonClosedCause);
- }
- catch (Exception ignore)
- {
- }
- }
- }
- }
-
- private static void tryAllAddresses(Socket sock, String host, int port, int connectTimeout) throws IOException {
- InetAddress[] addresses = InetAddress.getAllByName(host);
- for (InetAddress addr : addresses) {
- try {
- sock.connect(new InetSocketAddress(addr, port), connectTimeout);
- return;
- } catch (SocketTimeoutException e) {
- }
- }
- throw new SocketTimeoutException("Could not connect; socket timed out");
- }
-
- private void establishConnection(ProxyData proxyData, int connectTimeout) throws IOException
- {
- if (proxyData == null)
- {
- tryAllAddresses(sock, hostname, port, connectTimeout);
- sock.setSoTimeout(0);
- return;
- }
-
- if (proxyData instanceof HTTPProxyData)
- {
- HTTPProxyData pd = (HTTPProxyData) proxyData;
-
- /* At the moment, we only support HTTP proxies */
-
- tryAllAddresses(sock, pd.proxyHost, pd.proxyPort, connectTimeout);
- sock.setSoTimeout(0);
-
- /* OK, now tell the proxy where we actually want to connect to */
-
- StringBuffer sb = new StringBuffer();
-
- sb.append("CONNECT ");
- sb.append(hostname);
- sb.append(':');
- sb.append(port);
- sb.append(" HTTP/1.0\r\n");
-
- if ((pd.proxyUser != null) && (pd.proxyPass != null))
- {
- String credentials = pd.proxyUser + ":" + pd.proxyPass;
- char[] encoded = Base64.encode(credentials.getBytes("ISO-8859-1"));
- sb.append("Proxy-Authorization: Basic ");
- sb.append(encoded);
- sb.append("\r\n");
- }
-
- if (pd.requestHeaderLines != null)
- {
- for (int i = 0; i < pd.requestHeaderLines.length; i++)
- {
- if (pd.requestHeaderLines[i] != null)
- {
- sb.append(pd.requestHeaderLines[i]);
- sb.append("\r\n");
- }
- }
- }
-
- sb.append("\r\n");
-
- OutputStream out = sock.getOutputStream();
-
- out.write(sb.toString().getBytes("ISO-8859-1"));
- out.flush();
-
- /* Now parse the HTTP response */
-
- byte[] buffer = new byte[1024];
- InputStream in = sock.getInputStream();
-
- int len = ClientServerHello.readLineRN(in, buffer);
-
- String httpReponse = new String(buffer, 0, len, "ISO-8859-1");
-
- if (httpReponse.startsWith("HTTP/") == false)
- throw new IOException("The proxy did not send back a valid HTTP response.");
-
- /* "HTTP/1.X XYZ X" => 14 characters minimum */
-
- if ((httpReponse.length() < 14) || (httpReponse.charAt(8) != ' ') || (httpReponse.charAt(12) != ' '))
- throw new IOException("The proxy did not send back a valid HTTP response.");
-
- int errorCode = 0;
-
- try
- {
- errorCode = Integer.parseInt(httpReponse.substring(9, 12));
- }
- catch (NumberFormatException ignore)
- {
- throw new IOException("The proxy did not send back a valid HTTP response.");
- }
-
- if ((errorCode < 0) || (errorCode > 999))
- throw new IOException("The proxy did not send back a valid HTTP response.");
-
- if (errorCode != 200)
- {
- throw new HTTPProxyException(httpReponse.substring(13), errorCode);
- }
-
- /* OK, read until empty line */
-
- while (true)
- {
- len = ClientServerHello.readLineRN(in, buffer);
- if (len == 0)
- break;
- }
- return;
- }
-
- throw new IOException("Unsupported ProxyData");
- }
-
- public void initialize(CryptoWishList cwl, ServerHostKeyVerifier verifier, DHGexParameters dhgex,
- int connectTimeout, SecureRandom rnd, ProxyData proxyData) throws IOException
- {
- /* First, establish the TCP connection to the SSH-2 server */
-
- establishConnection(proxyData, connectTimeout);
-
- /* Parse the server line and say hello - important: this information is later needed for the
- * key exchange (to stop man-in-the-middle attacks) - that is why we wrap it into an object
- * for later use.
- */
-
- ClientServerHello csh = new ClientServerHello(sock.getInputStream(), sock.getOutputStream());
-
- tc = new TransportConnection(sock.getInputStream(), sock.getOutputStream(), rnd);
-
- km = new KexManager(this, csh, cwl, hostname, port, verifier, rnd);
- km.initiateKEX(cwl, dhgex);
-
- receiveThread = new Thread(new Runnable()
- {
- public void run()
- {
- try
- {
- receiveLoop();
- }
- catch (IOException e)
- {
- close(e, false);
-
- if (log.isEnabled())
- log.log(10, "Receive thread: error in receiveLoop: " + e.getMessage());
- }
-
- if (log.isEnabled())
- log.log(50, "Receive thread: back from receiveLoop");
-
- /* Tell all handlers that it is time to say goodbye */
-
- if (km != null)
- {
- try
- {
- km.handleMessage(null, 0);
- }
- catch (IOException e)
- {
- }
- }
-
- for (int i = 0; i < messageHandlers.size(); i++)
- {
- HandlerEntry he = messageHandlers.elementAt(i);
- try
- {
- he.mh.handleMessage(null, 0);
- }
- catch (Exception ignore)
- {
- }
- }
- }
- });
-
- receiveThread.setDaemon(true);
- receiveThread.start();
- }
-
- public void registerMessageHandler(MessageHandler mh, int low, int high)
- {
- HandlerEntry he = new HandlerEntry();
- he.mh = mh;
- he.low = low;
- he.high = high;
-
- synchronized (messageHandlers)
- {
- messageHandlers.addElement(he);
- }
- }
-
- public void removeMessageHandler(MessageHandler mh, int low, int high)
- {
- synchronized (messageHandlers)
- {
- for (int i = 0; i < messageHandlers.size(); i++)
- {
- HandlerEntry he = messageHandlers.elementAt(i);
- if ((he.mh == mh) && (he.low == low) && (he.high == high))
- {
- messageHandlers.removeElementAt(i);
- break;
- }
- }
- }
- }
-
- public void sendKexMessage(byte[] msg) throws IOException
- {
- synchronized (connectionSemaphore)
- {
- if (connectionClosed)
- {
- throw (IOException) new IOException("Sorry, this connection is closed.").initCause(reasonClosedCause);
- }
-
- flagKexOngoing = true;
-
- try
- {
- tc.sendMessage(msg);
- }
- catch (IOException e)
- {
- close(e, false);
- throw e;
- }
- }
- }
-
- public void kexFinished() throws IOException
- {
- synchronized (connectionSemaphore)
- {
- flagKexOngoing = false;
- connectionSemaphore.notifyAll();
- }
- }
-
- public void forceKeyExchange(CryptoWishList cwl, DHGexParameters dhgex) throws IOException
- {
- km.initiateKEX(cwl, dhgex);
- }
-
- public void changeRecvCipher(BlockCipher bc, MAC mac)
- {
- tc.changeRecvCipher(bc, mac);
- }
-
- public void changeSendCipher(BlockCipher bc, MAC mac)
- {
- tc.changeSendCipher(bc, mac);
- }
-
- /**
- * @param comp
- */
- public void changeRecvCompression(ICompressor comp) {
- tc.changeRecvCompression(comp);
- }
-
- /**
- * @param comp
- */
- public void changeSendCompression(ICompressor comp) {
- tc.changeSendCompression(comp);
- }
-
- /**
- *
- */
- public void startCompression() {
- tc.startCompression();
- }
-
- public void sendAsynchronousMessage(byte[] msg) throws IOException
- {
- synchronized (asynchronousQueue)
- {
- asynchronousQueue.addElement(msg);
-
- /* This limit should be flexible enough. We need this, otherwise the peer
- * can flood us with global requests (and other stuff where we have to reply
- * with an asynchronous message) and (if the server just sends data and does not
- * read what we send) this will probably put us in a low memory situation
- * (our send queue would grow and grow and...) */
-
- if (asynchronousQueue.size() > 100)
- throw new IOException("Error: the peer is not consuming our asynchronous replies.");
-
- /* Check if we have an asynchronous sending thread */
-
- if (asynchronousThread == null)
- {
- asynchronousThread = new AsynchronousWorker();
- asynchronousThread.setDaemon(true);
- asynchronousThread.start();
-
- /* The thread will stop after 2 seconds of inactivity (i.e., empty queue) */
- }
- }
- }
-
- public void setConnectionMonitors(Vector monitors)
- {
- synchronized (this)
- {
- connectionMonitors = (Vector) monitors.clone();
- }
- }
-
- public void sendMessage(byte[] msg) throws IOException
- {
- if (Thread.currentThread() == receiveThread)
- throw new IOException("Assertion error: sendMessage may never be invoked by the receiver thread!");
-
- synchronized (connectionSemaphore)
- {
- while (true)
- {
- if (connectionClosed)
- {
- throw (IOException) new IOException("Sorry, this connection is closed.")
- .initCause(reasonClosedCause);
- }
-
- if (flagKexOngoing == false)
- break;
-
- try
- {
- connectionSemaphore.wait();
- }
- catch (InterruptedException e)
- {
- }
- }
-
- try
- {
- tc.sendMessage(msg);
- }
- catch (IOException e)
- {
- close(e, false);
- throw e;
- }
- }
- }
-
- public void receiveLoop() throws IOException
- {
- byte[] msg = new byte[35000];
-
- while (true)
- {
- int msglen = tc.receiveMessage(msg, 0, msg.length);
-
- int type = msg[0] & 0xff;
-
- if (type == Packets.SSH_MSG_IGNORE)
- continue;
-
- if (type == Packets.SSH_MSG_DEBUG)
- {
- if (log.isEnabled())
- {
- TypesReader tr = new TypesReader(msg, 0, msglen);
- tr.readByte();
- tr.readBoolean();
- StringBuffer debugMessageBuffer = new StringBuffer();
- debugMessageBuffer.append(tr.readString("UTF-8"));
-
- for (int i = 0; i < debugMessageBuffer.length(); i++)
- {
- char c = debugMessageBuffer.charAt(i);
-
- if ((c >= 32) && (c <= 126))
- continue;
- debugMessageBuffer.setCharAt(i, '\uFFFD');
- }
-
- log.log(50, "DEBUG Message from remote: '" + debugMessageBuffer.toString() + "'");
- }
- continue;
- }
-
- if (type == Packets.SSH_MSG_UNIMPLEMENTED)
- {
- throw new IOException("Peer sent UNIMPLEMENTED message, that should not happen.");
- }
-
- if (type == Packets.SSH_MSG_DISCONNECT)
- {
- TypesReader tr = new TypesReader(msg, 0, msglen);
- tr.readByte();
- int reason_code = tr.readUINT32();
- StringBuffer reasonBuffer = new StringBuffer();
- reasonBuffer.append(tr.readString("UTF-8"));
-
- /*
- * Do not get fooled by servers that send abnormal long error
- * messages
- */
-
- if (reasonBuffer.length() > 255)
- {
- reasonBuffer.setLength(255);
- reasonBuffer.setCharAt(254, '.');
- reasonBuffer.setCharAt(253, '.');
- reasonBuffer.setCharAt(252, '.');
- }
-
- /*
- * Also, check that the server did not send charcaters that may
- * screw up the receiver -> restrict to reasonable US-ASCII
- * subset -> "printable characters" (ASCII 32 - 126). Replace
- * all others with 0xFFFD (UNICODE replacement character).
- */
-
- for (int i = 0; i < reasonBuffer.length(); i++)
- {
- char c = reasonBuffer.charAt(i);
-
- if ((c >= 32) && (c <= 126))
- continue;
- reasonBuffer.setCharAt(i, '\uFFFD');
- }
-
- throw new IOException("Peer sent DISCONNECT message (reason code " + reason_code + "): "
- + reasonBuffer.toString());
- }
-
- /*
- * Is it a KEX Packet?
- */
-
- if ((type == Packets.SSH_MSG_KEXINIT) || (type == Packets.SSH_MSG_NEWKEYS)
- || ((type >= 30) && (type <= 49)))
- {
- km.handleMessage(msg, msglen);
- continue;
- }
-
- if (type == Packets.SSH_MSG_USERAUTH_SUCCESS) {
- tc.startCompression();
- }
-
- MessageHandler mh = null;
-
- for (int i = 0; i < messageHandlers.size(); i++)
- {
- HandlerEntry he = messageHandlers.elementAt(i);
- if ((he.low <= type) && (type <= he.high))
- {
- mh = he.mh;
- break;
- }
- }
-
- if (mh == null)
- throw new IOException("Unexpected SSH message (type " + type + ")");
-
- mh.handleMessage(msg, msglen);
- }
- }
-}
diff --git a/app/src/main/java/com/trilead/ssh2/util/TimeoutService.java b/app/src/main/java/com/trilead/ssh2/util/TimeoutService.java
deleted file mode 100644
index 3d52161..0000000
--- a/app/src/main/java/com/trilead/ssh2/util/TimeoutService.java
+++ /dev/null
@@ -1,149 +0,0 @@
-
-package com.trilead.ssh2.util;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Collections;
-import java.util.LinkedList;
-
-import com.trilead.ssh2.log.Logger;
-
-
-/**
- * TimeoutService (beta). Here you can register a timeout.
- * <p>
- * Implemented having large scale programs in mind: if you open many concurrent SSH connections
- * that rely on timeouts, then there will be only one timeout thread. Once all timeouts
- * have expired/are cancelled, the thread will (sooner or later) exit.
- * Only after new timeouts arrive a new thread (singleton) will be instantiated.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: TimeoutService.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
- */
-public class TimeoutService
-{
- private static final Logger log = Logger.getLogger(TimeoutService.class);
-
- public static class TimeoutToken implements Comparable
- {
- private long runTime;
- private Runnable handler;
-
- private TimeoutToken(long runTime, Runnable handler)
- {
- this.runTime = runTime;
- this.handler = handler;
- }
-
- public int compareTo(Object o)
- {
- TimeoutToken t = (TimeoutToken) o;
- if (runTime > t.runTime)
- return 1;
- if (runTime == t.runTime)
- return 0;
- return -1;
- }
- }
-
- private static class TimeoutThread extends Thread
- {
- public void run()
- {
- synchronized (todolist)
- {
- while (true)
- {
- if (todolist.size() == 0)
- {
- timeoutThread = null;
- return;
- }
-
- long now = System.currentTimeMillis();
-
- TimeoutToken tt = (TimeoutToken) todolist.getFirst();
-
- if (tt.runTime > now)
- {
- /* Not ready yet, sleep a little bit */
-
- try
- {
- todolist.wait(tt.runTime - now);
- }
- catch (InterruptedException e)
- {
- }
-
- /* We cannot simply go on, since it could be that the token
- * was removed (cancelled) or another one has been inserted in
- * the meantime.
- */
-
- continue;
- }
-
- todolist.removeFirst();
-
- try
- {
- tt.handler.run();
- }
- catch (Exception e)
- {
- StringWriter sw = new StringWriter();
- e.printStackTrace(new PrintWriter(sw));
- log.log(20, "Exeception in Timeout handler:" + e.getMessage() + "(" + sw.toString() + ")");
- }
- }
- }
- }
- }
-
- /* The list object is also used for locking purposes */
- private static final LinkedList todolist = new LinkedList();
-
- private static Thread timeoutThread = null;
-
- /**
- * It is assumed that the passed handler will not execute for a long time.
- *
- * @param runTime
- * @param handler
- * @return a TimeoutToken that can be used to cancel the timeout.
- */
- public static final TimeoutToken addTimeoutHandler(long runTime, Runnable handler)
- {
- TimeoutToken token = new TimeoutToken(runTime, handler);
-
- synchronized (todolist)
- {
- todolist.add(token);
- Collections.sort(todolist);
-
- if (timeoutThread != null)
- timeoutThread.interrupt();
- else
- {
- timeoutThread = new TimeoutThread();
- timeoutThread.setDaemon(true);
- timeoutThread.start();
- }
- }
-
- return token;
- }
-
- public static final void cancelTimeoutHandler(TimeoutToken token)
- {
- synchronized (todolist)
- {
- todolist.remove(token);
-
- if (timeoutThread != null)
- timeoutThread.interrupt();
- }
- }
-
-}
diff --git a/app/src/main/java/com/trilead/ssh2/util/Tokenizer.java b/app/src/main/java/com/trilead/ssh2/util/Tokenizer.java
deleted file mode 100644
index dfd480b..0000000
--- a/app/src/main/java/com/trilead/ssh2/util/Tokenizer.java
+++ /dev/null
@@ -1,51 +0,0 @@
-
-package com.trilead.ssh2.util;
-
-/**
- * Tokenizer. Why? Because StringTokenizer is not available in J2ME.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: Tokenizer.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
- */
-public class Tokenizer
-{
- /**
- * Exists because StringTokenizer is not available in J2ME.
- * Returns an array with at least 1 entry.
- *
- * @param source must be non-null
- * @param delimiter
- * @return an array of Strings
- */
- public static String[] parseTokens(String source, char delimiter)
- {
- int numtoken = 1;
-
- for (int i = 0; i < source.length(); i++)
- {
- if (source.charAt(i) == delimiter)
- numtoken++;
- }
-
- String list[] = new String[numtoken];
- int nextfield = 0;
-
- for (int i = 0; i < numtoken; i++)
- {
- if (nextfield >= source.length())
- {
- list[i] = "";
- }
- else
- {
- int idx = source.indexOf(delimiter, nextfield);
- if (idx == -1)
- idx = source.length();
- list[i] = source.substring(nextfield, idx);
- nextfield = idx + 1;
- }
- }
-
- return list;
- }
-}
diff --git a/app/src/main/java/net/sourceforge/jsocks/Authentication.java b/app/src/main/java/net/sourceforge/jsocks/Authentication.java
deleted file mode 100644
index 18cc48b..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/Authentication.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package net.sourceforge.jsocks;
-
-/**
- The Authentication interface provides for performing method specific
- authentication for SOCKS5 connections.
-*/
-public interface Authentication{
- /**
- This method is called when SOCKS5 server have selected a particular
- authentication method, for whch an implementaion have been registered.
-
- <p>
- This method should return an array {inputstream,outputstream
- [,UDPEncapsulation]}. The reason for that is that SOCKS5 protocol
- allows to have method specific encapsulation of data on the socket for
- purposes of integrity or security. And this encapsulation should be
- performed by those streams returned from the method. It is also possible
- to encapsulate datagrams. If authentication method supports such
- encapsulation an instance of the UDPEncapsulation interface should be
- returned as third element of the array, otherwise either null should be
- returned as third element, or array should contain only 2 elements.
-
- @param methodId Authentication method selected by the server.
- @param proxySocket Socket used to conect to the proxy.
- @return Two or three element array containing
- Input/Output streams which should be used on this connection.
- Third argument is optional and should contain an instance
- of UDPEncapsulation. It should be provided if the authentication
- method used requires any encapsulation to be done on the
- datagrams.
- */
- Object[] doSocksAuthentication(int methodId,java.net.Socket proxySocket)
- throws java.io.IOException;
-}
diff --git a/app/src/main/java/net/sourceforge/jsocks/AuthenticationNone.java b/app/src/main/java/net/sourceforge/jsocks/AuthenticationNone.java
deleted file mode 100644
index f28193a..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/AuthenticationNone.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package net.sourceforge.jsocks;
-
-/**
- SOCKS5 none authentication. Dummy class does almost nothing.
-*/
-public class AuthenticationNone implements Authentication{
-
- public Object[] doSocksAuthentication(int methodId,
- java.net.Socket proxySocket)
- throws java.io.IOException{
-
- if(methodId!=0) return null;
-
- return new Object[] { proxySocket.getInputStream(),
- proxySocket.getOutputStream()};
- }
-}
diff --git a/app/src/main/java/net/sourceforge/jsocks/Proxy.java b/app/src/main/java/net/sourceforge/jsocks/Proxy.java
deleted file mode 100644
index 381c0a0..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/Proxy.java
+++ /dev/null
@@ -1,404 +0,0 @@
-package net.sourceforge.jsocks;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InterruptedIOException;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-
-/**
- Abstract class Proxy, base for classes Socks4Proxy and Socks5Proxy.
- Defines methods for specifying default proxy, to be
- used by all classes of this package.
-*/
-
-public abstract class Proxy{
-
-//Data members
- //protected InetRange directHosts = new InetRange();
-
- protected InetAddress proxyIP = null;
- protected String proxyHost = null;
- protected int proxyPort;
- protected Socket proxySocket = null;
-
- protected InputStream in;
- protected OutputStream out;
-
- protected int version;
-
- protected Proxy chainProxy = null;
-
-
-//Protected static/class variables
- protected static Proxy defaultProxy = null;
-
-//Constructors
-//====================
- Proxy(String proxyHost, int proxyPort) throws UnknownHostException {
- this.proxyHost = proxyHost;
- this.proxyIP = InetAddress.getByName(proxyHost);
- this.proxyPort = proxyPort;
- }
-
- Proxy(Proxy chainProxy,InetAddress proxyIP,int proxyPort){
- this.chainProxy = chainProxy;
- this.proxyIP = proxyIP;
- this.proxyPort = proxyPort;
- }
-
- Proxy(InetAddress proxyIP,int proxyPort){
- this.proxyIP = proxyIP;
- this.proxyPort = proxyPort;
- }
-
- Proxy(Proxy p){
- this.proxyIP = p.proxyIP;
- this.proxyPort = p.proxyPort;
- this.version = p.version;
- }
-
-//Public instance methods
-//========================
-
- /**
- Get the port on which proxy server is running.
- * @return Proxy port.
- */
- public int getPort(){
- return proxyPort;
- }
- /**
- Get the ip address of the proxy server host.
- * @return Proxy InetAddress.
- */
- public InetAddress getInetAddress(){
- return proxyIP;
- }
-
- /**
- Get string representation of this proxy.
- * @returns string in the form:proxyHost:proxyPort \t Version versionNumber
- */
- public String toString(){
- return (""+proxyIP.getHostName()+":"+proxyPort+"\tVersion "+version);
- }
-
-
-//Public Static(Class) Methods
-//==============================
-
- /**
- * Sets SOCKS4 proxy as default.
- @param hostName Host name on which SOCKS4 server is running.
- @param port Port on which SOCKS4 server is running.
- @param user Username to use for communications with proxy.
- */
- public static void setDefaultProxy(String hostName,int port,String user)
- throws UnknownHostException{
- defaultProxy = new Socks4Proxy(hostName,port,user);
- }
-
- /**
- * Sets SOCKS4 proxy as default.
- @param ipAddress Host address on which SOCKS4 server is running.
- @param port Port on which SOCKS4 server is running.
- @param user Username to use for communications with proxy.
- */
- public static void setDefaultProxy(InetAddress ipAddress,int port,
- String user){
- defaultProxy = new Socks4Proxy(ipAddress,port,user);
- }
- /**
- * Sets SOCKS5 proxy as default.
- * Default proxy only supports no-authentication.
- @param hostName Host name on which SOCKS5 server is running.
- @param port Port on which SOCKS5 server is running.
- */
- public static void setDefaultProxy(String hostName,int port)
- throws UnknownHostException{
- defaultProxy = new Socks5Proxy(hostName,port);
- }
- /**
- * Sets SOCKS5 proxy as default.
- * Default proxy only supports no-authentication.
- @param ipAddress Host address on which SOCKS5 server is running.
- @param port Port on which SOCKS5 server is running.
- */
- public static void setDefaultProxy(InetAddress ipAddress,int port){
- defaultProxy = new Socks5Proxy(ipAddress,port);
- }
- /**
- * Sets default proxy.
- @param p Proxy to use as default proxy.
- */
- public static void setDefaultProxy(Proxy p){
- defaultProxy = p;
- }
-
- /**
- Get current default proxy.
- * @return Current default proxy, or null if none is set.
- */
- public static Proxy getDefaultProxy(){
- return defaultProxy;
- }
-
- /**
- Parses strings in the form: host[:port:user:password], and creates
- proxy from information obtained from parsing.
- <p>
- Defaults: port = 1080.<br>
- If user specified but not password, creates Socks4Proxy, if user
- not specified creates Socks5Proxy, if both user and password are
- speciefied creates Socks5Proxy with user/password authentication.
- @param proxy_entry String in the form host[:port:user:password]
- @return Proxy created from the string, null if entry was somehow
- invalid(host unknown for example, or empty string)
- */
- public static Proxy parseProxy(String proxy_entry){
-
- String proxy_host;
- int proxy_port = 1080;
- String proxy_user = null;
- String proxy_password = null;
- Proxy proxy;
-
- java.util.StringTokenizer st = new java.util.StringTokenizer(
- proxy_entry,":");
- if(st.countTokens() < 1) return null;
-
- proxy_host = st.nextToken();
- if(st.hasMoreTokens())
- try{
- proxy_port = Integer.parseInt(st.nextToken().trim());
- }catch(NumberFormatException nfe){}
-
- if(st.hasMoreTokens())
- proxy_user = st.nextToken();
-
- if(st.hasMoreTokens())
- proxy_password = st.nextToken();
-
- try{
- if(proxy_user == null)
- proxy = new Socks5Proxy(proxy_host,proxy_port);
- else if(proxy_password == null)
- proxy = new Socks4Proxy(proxy_host,proxy_port,proxy_user);
- else{
- proxy = new Socks5Proxy(proxy_host,proxy_port);
- /*
- UserPasswordAuthentication upa = new UserPasswordAuthentication(
- proxy_user, proxy_password);
-
- ((Socks5Proxy)proxy).setAuthenticationMethod(upa.METHOD_ID,upa);
- */
- }
- }catch(UnknownHostException uhe){
- return null;
- }
-
- return proxy;
- }
-
-
-//Protected Methods
-//=================
-
- protected void startSession()throws SocksException{
- try{
- proxySocket = new Socket(proxyIP,proxyPort);
- in = proxySocket.getInputStream();
- out = proxySocket.getOutputStream();
- }catch(SocksException se){
- throw se;
- }catch(IOException io_ex){
- throw new SocksException(SOCKS_PROXY_IO_ERROR,""+io_ex);
- }
- }
-
- protected abstract Proxy copy();
- protected abstract ProxyMessage formMessage(int cmd,InetAddress ip,int port);
- protected abstract ProxyMessage formMessage(int cmd,String host,int port)
- throws UnknownHostException;
- protected abstract ProxyMessage formMessage(InputStream in)
- throws SocksException,
- IOException;
-
-
- protected ProxyMessage connect(InetAddress ip,int port)
- throws SocksException{
- try{
- startSession();
- ProxyMessage request = formMessage(SOCKS_CMD_CONNECT,
- ip,port);
- return exchange(request);
- }catch(SocksException se){
- endSession();
- throw se;
- }
- }
- protected ProxyMessage connect(String host,int port)
- throws UnknownHostException,SocksException{
- try{
- startSession();
- ProxyMessage request = formMessage(SOCKS_CMD_CONNECT,
- host,port);
- return exchange(request);
- }catch(SocksException se){
- endSession();
- throw se;
- }
- }
-
- protected ProxyMessage bind(InetAddress ip,int port)
- throws SocksException{
- try{
- startSession();
- ProxyMessage request = formMessage(SOCKS_CMD_BIND,
- ip,port);
- return exchange(request);
- }catch(SocksException se){
- endSession();
- throw se;
- }
- }
- protected ProxyMessage bind(String host,int port)
- throws UnknownHostException,SocksException{
- try{
- startSession();
- ProxyMessage request = formMessage(SOCKS_CMD_BIND,
- host,port);
- return exchange(request);
- }catch(SocksException se){
- endSession();
- throw se;
- }
- }
-
- protected ProxyMessage accept()
- throws IOException,SocksException{
- ProxyMessage msg;
- try{
- msg = formMessage(in);
- }catch(InterruptedIOException iioe){
- throw iioe;
- }catch(IOException io_ex){
- endSession();
- throw new SocksException(SOCKS_PROXY_IO_ERROR,"While Trying accept:"
- +io_ex);
- }
- return msg;
- }
-
- protected ProxyMessage udpAssociate(InetAddress ip,int port)
- throws SocksException{
- try{
- startSession();
- ProxyMessage request = formMessage(SOCKS_CMD_UDP_ASSOCIATE,
- ip,port);
- if(request != null)
- return exchange(request);
- }catch(SocksException se){
- endSession();
- throw se;
- }
- //Only get here if request was null
- endSession();
- throw new SocksException(SOCKS_METHOD_NOTSUPPORTED,
- "This version of proxy does not support UDP associate, use version 5");
- }
- protected ProxyMessage udpAssociate(String host,int port)
- throws UnknownHostException,SocksException{
- try{
- startSession();
- ProxyMessage request = formMessage(SOCKS_CMD_UDP_ASSOCIATE,
- host,port);
- if(request != null) return exchange(request);
- }catch(SocksException se){
- endSession();
- throw se;
- }
- //Only get here if request was null
- endSession();
- throw new SocksException(SOCKS_METHOD_NOTSUPPORTED,
- "This version of proxy does not support UDP associate, use version 5");
- }
-
-
- protected void endSession(){
- try{
- if(proxySocket!=null) proxySocket.close();
- proxySocket = null;
- }catch(IOException io_ex){
- }
- }
-
- /**
- *Sends the request to SOCKS server
- */
- protected void sendMsg(ProxyMessage msg)throws SocksException,
- IOException{
- msg.write(out);
- }
-
- /**
- * Reads the reply from the SOCKS server
- */
- protected ProxyMessage readMsg()throws SocksException,
- IOException{
- return formMessage(in);
- }
- /**
- *Sends the request reads reply and returns it
- *throws exception if something wrong with IO
- *or the reply code is not zero
- */
- protected ProxyMessage exchange(ProxyMessage request)
- throws SocksException{
- ProxyMessage reply;
- try{
- request.write(out);
- reply = formMessage(in);
- }catch(SocksException s_ex){
- throw s_ex;
- }catch(IOException ioe){
- throw(new SocksException(SOCKS_PROXY_IO_ERROR,""+ioe));
- }
- return reply;
- }
-
-
-//Private methods
-//===============
-
-
-//Constants
-
- public static final int SOCKS_SUCCESS =0;
- public static final int SOCKS_FAILURE =1;
- public static final int SOCKS_BADCONNECT =2;
- public static final int SOCKS_BADNETWORK =3;
- public static final int SOCKS_HOST_UNREACHABLE =4;
- public static final int SOCKS_CONNECTION_REFUSED =5;
- public static final int SOCKS_TTL_EXPIRE =6;
- public static final int SOCKS_CMD_NOT_SUPPORTED =7;
- public static final int SOCKS_ADDR_NOT_SUPPORTED =8;
-
- public static final int SOCKS_NO_PROXY =1<<16;
- public static final int SOCKS_PROXY_NO_CONNECT =2<<16;
- public static final int SOCKS_PROXY_IO_ERROR =3<<16;
- public static final int SOCKS_AUTH_NOT_SUPPORTED =4<<16;
- public static final int SOCKS_AUTH_FAILURE =5<<16;
- public static final int SOCKS_JUST_ERROR =6<<16;
-
- public static final int SOCKS_DIRECT_FAILED =7<<16;
- public static final int SOCKS_METHOD_NOTSUPPORTED =8<<16;
-
-
- public static final int SOCKS_CMD_CONNECT =0x1;
- static final int SOCKS_CMD_BIND =0x2;
- static final int SOCKS_CMD_UDP_ASSOCIATE =0x3;
-
-}
diff --git a/app/src/main/java/net/sourceforge/jsocks/ProxyMessage.java b/app/src/main/java/net/sourceforge/jsocks/ProxyMessage.java
deleted file mode 100644
index 442c380..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/ProxyMessage.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package net.sourceforge.jsocks;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- Abstract class which describes SOCKS4/5 response/request.
-*/
-public abstract class ProxyMessage{
- /** Host as an IP address */
- public InetAddress ip=null;
- /** SOCKS version, or version of the response for SOCKS4*/
- public int version;
- /** Port field of the request/response*/
- public int port;
- /** Request/response code as an int*/
- public int command;
- /** Host as string.*/
- public String host=null;
- /** User field for SOCKS4 request messages*/
- public String user=null;
-
- ProxyMessage(int command,InetAddress ip,int port){
- this.command = command;
- this.ip = ip;
- this.port = port;
- }
-
- ProxyMessage(){
- }
-
-
- /**
- Initialises Message from the stream. Reads server response from
- given stream.
- @param in Input stream to read response from.
- @throws SocksException If server response code is not SOCKS_SUCCESS(0), or
- if any error with protocol occurs.
- @throws IOException If any error happens with I/O.
- */
- public abstract void read(InputStream in)
- throws SocksException,
- IOException;
-
-
- /**
- Initialises Message from the stream. Reads server response or client
- request from given stream.
-
- @param in Input stream to read response from.
- @param clinetMode If true read server response, else read client request.
- @throws SocksException If server response code is not SOCKS_SUCCESS(0) and
- reading in client mode, or if any error with protocol occurs.
- @throws IOException If any error happens with I/O.
- */
- public abstract void read(InputStream in,boolean client_mode)
- throws SocksException,
- IOException;
-
-
- /**
- Writes the message to the stream.
- @param out Output stream to which message should be written.
- */
- public abstract void write(OutputStream out)throws SocksException,
- IOException;
-
- /**
- Get the Address field of this message as InetAddress object.
- @return Host address or null, if one can't be determined.
- */
- public InetAddress getInetAddress() throws UnknownHostException{
- return ip;
- }
-
-
- /**
- Get string representaion of this message.
- @return string representation of this message.
- */
- public String toString(){
- return
- "Proxy Message:\n"+
- "Version:"+ version+"\n"+
- "Command:"+ command+"\n"+
- "IP: "+ ip+"\n"+
- "Port: "+ port+"\n"+
- "User: "+ user+"\n" ;
- }
-
-//Package methods
-//////////////////
-
- static final String bytes2IPV4(byte[] addr,int offset){
- String hostName = ""+(addr[offset] & 0xFF);
- for(int i = offset+1;i<offset+4;++i)
- hostName+="."+(addr[i] & 0xFF);
- return hostName;
- }
-
- static final String bytes2IPV6(byte[] addr,int offset){
- //Have no idea how they look like!
- return null;
- }
-
-}
diff --git a/app/src/main/java/net/sourceforge/jsocks/ProxyServer.java b/app/src/main/java/net/sourceforge/jsocks/ProxyServer.java
deleted file mode 100644
index 225149d..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/ProxyServer.java
+++ /dev/null
@@ -1,591 +0,0 @@
-package net.sourceforge.jsocks;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InterruptedIOException;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.PushbackInputStream;
-import java.net.ConnectException;
-import java.net.InetAddress;
-import java.net.NoRouteToHostException;
-import java.net.ServerSocket;
-import java.net.Socket;
-
-import net.sourceforge.jsocks.server.ServerAuthenticator;
-
-/**
- SOCKS4 and SOCKS5 proxy, handles both protocols simultaniously.
- Implements all SOCKS commands, including UDP relaying.
- <p>
- In order to use it you will need to implement ServerAuthenticator
- interface. There is an implementation of this interface which does
- no authentication ServerAuthenticatorNone, but it is very dangerous
- to use, as it will give access to your local network to anybody
- in the world. One should never use this authentication scheme unless
- one have pretty good reason to do so.
- There is a couple of other authentication schemes in socks.server package.
- @see socks.server.ServerAuthenticator
-*/
-public class ProxyServer implements Runnable{
-
- ServerAuthenticator auth;
- ProxyMessage msg = null;
-
- Socket sock=null,remote_sock=null;
- ServerSocket ss=null;
- UDPRelayServer relayServer = null;
- InputStream in,remote_in;
- OutputStream out,remote_out;
-
- int mode;
- static final int START_MODE = 0;
- static final int ACCEPT_MODE = 1;
- static final int PIPE_MODE = 2;
- static final int ABORT_MODE = 3;
-
- static final int BUF_SIZE = 8192;
-
- Thread pipe_thread1,pipe_thread2;
- long lastReadTime;
-
- protected static int iddleTimeout = 180000; //3 minutes
- static int acceptTimeout = 180000; //3 minutes
-
- static PrintStream log = null;
- static Proxy proxy;
-
-
-//Public Constructors
-/////////////////////
-
-
- /**
- Creates a proxy server with given Authentication scheme.
- @param auth Authentication scheme to be used.
- */
- public ProxyServer(ServerAuthenticator auth){
- this.auth = auth;
- }
-
-//Other constructors
-////////////////////
-
- protected ProxyServer(ServerAuthenticator auth,Socket s){
- this.auth = auth;
- this.sock = s;
- mode = START_MODE;
- }
-
-//Public methods
-/////////////////
-
- /**
- Set the logging stream. Specifying null disables logging.
- */
- public static void setLog(OutputStream out){
- if(out == null){
- log = null;
- }else{
- log = new PrintStream(out,true);
- }
-
- UDPRelayServer.log = log;
- }
-
- /**
- Set proxy.
- <p>
- Allows Proxy chaining so that one Proxy server is connected to another
- and so on. If proxy supports SOCKSv4, then only some SOCKSv5 requests
- can be handled, UDP would not work, however CONNECT and BIND will be
- translated.
-
- @param p Proxy which should be used to handle user requests.
- */
- public static void setProxy(Proxy p){
- proxy =p;
- UDPRelayServer.proxy = proxy;
- }
-
- /**
- Get proxy.
- @return Proxy wich is used to handle user requests.
- */
- public static Proxy getProxy(){
- return proxy;
- }
-
- /**
- Sets the timeout for connections, how long shoud server wait
- for data to arrive before dropping the connection.<br>
- Zero timeout implies infinity.<br>
- Default timeout is 3 minutes.
- */
- public static void setIddleTimeout(int timeout){
- iddleTimeout = timeout;
- }
- /**
- Sets the timeout for BIND command, how long the server should
- wait for the incoming connection.<br>
- Zero timeout implies infinity.<br>
- Default timeout is 3 minutes.
- */
- public static void setAcceptTimeout(int timeout){
- acceptTimeout = timeout;
- }
-
- /**
- Sets the timeout for UDPRelay server.<br>
- Zero timeout implies infinity.<br>
- Default timeout is 3 minutes.
- */
- public static void setUDPTimeout(int timeout){
- UDPRelayServer.setTimeout(timeout);
- }
-
- /**
- Sets the size of the datagrams used in the UDPRelayServer.<br>
- Default size is 64K, a bit more than maximum possible size of the
- datagram.
- */
- public static void setDatagramSize(int size){
- UDPRelayServer.setDatagramSize(size);
- }
-
-
- /**
- Start the Proxy server at given port.<br>
- This methods blocks.
- */
- public void start(int port){
- start(port,5,null);
- }
-
- /**
- Create a server with the specified port, listen backlog, and local
- IP address to bind to. The localIP argument can be used on a multi-homed
- host for a ServerSocket that will only accept connect requests to one of
- its addresses. If localIP is null, it will default accepting connections
- on any/all local addresses. The port must be between 0 and 65535,
- inclusive. <br>
- This methods blocks.
- */
- public void start(int port,int backlog,InetAddress localIP){
- try{
- ss = new ServerSocket(port,backlog,localIP);
- log("Starting SOCKS Proxy on:"+ss.getInetAddress().getHostAddress()+":"
- +ss.getLocalPort());
- while(true){
- Socket s = ss.accept();
- log("Accepted from:"+s.getInetAddress().getHostName()+":"
- +s.getPort());
- ProxyServer ps = new ProxyServer(auth,s);
- (new Thread(ps)).start();
- }
- }catch(IOException ioe){
- ioe.printStackTrace();
- }finally{
- }
- }
-
- /**
- Stop server operation.It would be wise to interrupt thread running the
- server afterwards.
- */
- public void stop(){
- try{
- if(ss != null) ss.close();
- }catch(IOException ioe){
- }
- }
-
-//Runnable interface
-////////////////////
- public void run(){
- switch(mode){
- case START_MODE:
- try{
- startSession();
- }catch(IOException ioe){
- handleException(ioe);
- //ioe.printStackTrace();
- }finally{
- abort();
- if(auth!=null) auth.endSession();
- log("Main thread(client->remote)stopped.");
- }
- break;
- case ACCEPT_MODE:
- try{
- doAccept();
- mode = PIPE_MODE;
- pipe_thread1.interrupt(); //Tell other thread that connection have
- //been accepted.
- pipe(remote_in,out);
- }catch(IOException ioe){
- //log("Accept exception:"+ioe);
- handleException(ioe);
- }finally{
- abort();
- log("Accept thread(remote->client) stopped");
- }
- break;
- case PIPE_MODE:
- try{
- pipe(remote_in,out);
- }catch(IOException ioe){
- }finally{
- abort();
- log("Support thread(remote->client) stopped");
- }
- break;
- case ABORT_MODE:
- break;
- default:
- log("Unexpected MODE "+mode);
- }
- }
-
-//Private methods
-/////////////////
- private void startSession() throws IOException{
- sock.setSoTimeout(iddleTimeout);
-
- try{
- auth = auth.startSession(sock);
- }catch(IOException ioe){
- log("Auth throwed exception:"+ioe);
- auth = null;
- return;
- }
-
- if(auth == null){ //Authentication failed
- log("Authentication failed");
- return;
- }
-
- in = auth.getInputStream();
- out = auth.getOutputStream();
-
- msg = readMsg(in);
- handleRequest(msg);
- }
-
- protected void handleRequest(ProxyMessage msg)
- throws IOException{
- if(!auth.checkRequest(msg)) throw new
- SocksException(Proxy.SOCKS_FAILURE);
-
- if(msg.ip == null){
- if(msg instanceof Socks5Message){
- msg.ip = InetAddress.getByName(msg.host);
- }else
- throw new SocksException(Proxy.SOCKS_FAILURE);
- }
- log(msg);
-
- switch(msg.command){
- case Proxy.SOCKS_CMD_CONNECT:
- onConnect(msg);
- break;
- case Proxy.SOCKS_CMD_BIND:
- onBind(msg);
- break;
- case Proxy.SOCKS_CMD_UDP_ASSOCIATE:
- onUDP(msg);
- break;
- default:
- throw new SocksException(Proxy.SOCKS_CMD_NOT_SUPPORTED);
- }
- }
-
- private void handleException(IOException ioe){
- //If we couldn't read the request, return;
- if(msg == null) return;
- //If have been aborted by other thread
- if(mode == ABORT_MODE) return;
- //If the request was successfully completed, but exception happened later
- if(mode == PIPE_MODE) return;
-
- int error_code = Proxy.SOCKS_FAILURE;
-
- if(ioe instanceof SocksException)
- error_code = ((SocksException)ioe).errCode;
- else if(ioe instanceof NoRouteToHostException)
- error_code = Proxy.SOCKS_HOST_UNREACHABLE;
- else if(ioe instanceof ConnectException)
- error_code = Proxy.SOCKS_CONNECTION_REFUSED;
- else if(ioe instanceof InterruptedIOException)
- error_code = Proxy.SOCKS_TTL_EXPIRE;
-
- if(error_code > Proxy.SOCKS_ADDR_NOT_SUPPORTED || error_code < 0){
- error_code = Proxy.SOCKS_FAILURE;
- }
-
- sendErrorMessage(error_code);
- }
-
- private void onConnect(ProxyMessage msg) throws IOException{
- Socket s;
- ProxyMessage response = null;
-
- s = new Socket(msg.ip,msg.port);
-
- log("Connected to "+s.getInetAddress()+":"+s.getPort());
-
- if(msg instanceof Socks5Message){
- response = new Socks5Message(Proxy.SOCKS_SUCCESS,
- s.getLocalAddress(),
- s.getLocalPort());
- }else{
- response = new Socks4Message(Socks4Message.REPLY_OK,
- s.getLocalAddress(),s.getLocalPort());
-
- }
- response.write(out);
- startPipe(s);
- }
-
- private void onBind(ProxyMessage msg) throws IOException{
- ProxyMessage response = null;
-
- if(proxy == null)
- ss = new ServerSocket(0);
- else
- ss = new SocksServerSocket(proxy, msg.ip, msg.port);
-
- ss.setSoTimeout(acceptTimeout);
-
- log("Trying accept on "+ss.getInetAddress()+":"+ss.getLocalPort());
-
- if(msg.version == 5)
- response = new Socks5Message(Proxy.SOCKS_SUCCESS,ss.getInetAddress(),
- ss.getLocalPort());
- else
- response = new Socks4Message(Socks4Message.REPLY_OK,
- ss.getInetAddress(),
- ss.getLocalPort());
- response.write(out);
-
- mode = ACCEPT_MODE;
-
- pipe_thread1 = Thread.currentThread();
- pipe_thread2 = new Thread(this);
- pipe_thread2.start();
-
- //Make timeout infinit.
- sock.setSoTimeout(0);
- int eof=0;
-
- try{
- while((eof=in.read())>=0){
- if(mode != ACCEPT_MODE){
- if(mode != PIPE_MODE) return;//Accept failed
-
- remote_out.write(eof);
- break;
- }
- }
- }catch(EOFException eofe){
- //System.out.println("EOF exception");
- return;//Connection closed while we were trying to accept.
- }catch(InterruptedIOException iioe){
- //Accept thread interrupted us.
- //System.out.println("Interrupted");
- if(mode != PIPE_MODE)
- return;//If accept thread was not successfull return.
- }finally{
- //System.out.println("Finnaly!");
- }
-
- if(eof < 0)//Connection closed while we were trying to accept;
- return;
-
- //Do not restore timeout, instead timeout is set on the
- //remote socket. It does not make any difference.
-
- pipe(in,remote_out);
- }
-
- private void onUDP(ProxyMessage msg) throws IOException{
- if(msg.ip.getHostAddress().equals("0.0.0.0"))
- msg.ip = sock.getInetAddress();
- log("Creating UDP relay server for "+msg.ip+":"+msg.port);
- relayServer = new UDPRelayServer(msg.ip,msg.port,
- Thread.currentThread(),sock,auth);
-
- ProxyMessage response;
-
- response = new Socks5Message(Proxy.SOCKS_SUCCESS,
- relayServer.relayIP,relayServer.relayPort);
-
- response.write(out);
-
- relayServer.start();
-
- //Make timeout infinit.
- sock.setSoTimeout(0);
- try{
- while(in.read()>=0) /*do nothing*/;
- }catch(EOFException eofe){
- }
- }
-
-//Private methods
-//////////////////
-
- private void doAccept() throws IOException{
- Socket s;
- long startTime = System.currentTimeMillis();
-
- while(true){
- s = ss.accept();
- if(s.getInetAddress().equals(msg.ip)){
- //got the connection from the right host
- //Close listenning socket.
- ss.close();
- break;
- }else if(ss instanceof SocksServerSocket){
- //We can't accept more then one connection
- s.close();
- ss.close();
- throw new SocksException(Proxy.SOCKS_FAILURE);
- }else{
- if(acceptTimeout!=0){ //If timeout is not infinit
- int newTimeout = acceptTimeout-(int)(System.currentTimeMillis()-
- startTime);
- if(newTimeout <= 0) throw new InterruptedIOException(
- "In doAccept()");
- ss.setSoTimeout(newTimeout);
- }
- s.close(); //Drop all connections from other hosts
- }
- }
-
- //Accepted connection
- remote_sock = s;
- remote_in = s.getInputStream();
- remote_out = s.getOutputStream();
-
- //Set timeout
- remote_sock.setSoTimeout(iddleTimeout);
-
- log("Accepted from "+s.getInetAddress()+":"+s.getPort());
-
- ProxyMessage response;
-
- if(msg.version == 5)
- response = new Socks5Message(Proxy.SOCKS_SUCCESS, s.getInetAddress(),
- s.getPort());
- else
- response = new Socks4Message(Socks4Message.REPLY_OK,
- s.getInetAddress(), s.getPort());
- response.write(out);
- }
-
- protected ProxyMessage readMsg(InputStream in) throws IOException{
- PushbackInputStream push_in;
- if(in instanceof PushbackInputStream)
- push_in = (PushbackInputStream) in;
- else
- push_in = new PushbackInputStream(in);
-
- int version = push_in.read();
- push_in.unread(version);
-
-
- ProxyMessage msg;
-
- if(version == 5){
- msg = new Socks5Message(push_in,false);
- }else if(version == 4){
- msg = new Socks4Message(push_in,false);
- }else{
- throw new SocksException(Proxy.SOCKS_FAILURE);
- }
- return msg;
- }
-
- private void startPipe(Socket s){
- mode = PIPE_MODE;
- remote_sock = s;
- try{
- remote_in = s.getInputStream();
- remote_out = s.getOutputStream();
- pipe_thread1 = Thread.currentThread();
- pipe_thread2 = new Thread(this);
- pipe_thread2.start();
- pipe(in,remote_out);
- }catch(IOException ioe){
- }
- }
-
- private void sendErrorMessage(int error_code){
- ProxyMessage err_msg;
- if(msg instanceof Socks4Message)
- err_msg = new Socks4Message(Socks4Message.REPLY_REJECTED);
- else
- err_msg = new Socks5Message(error_code);
- try{
- err_msg.write(out);
- }catch(IOException ioe){}
- }
-
- private synchronized void abort(){
- if(mode == ABORT_MODE) return;
- mode = ABORT_MODE;
- try{
- log("Aborting operation");
- if(remote_sock != null) remote_sock.close();
- if(sock != null) sock.close();
- if(relayServer!=null) relayServer.stop();
- if(ss!=null) ss.close();
- if(pipe_thread1 != null) pipe_thread1.interrupt();
- if(pipe_thread2 != null) pipe_thread2.interrupt();
- }catch(IOException ioe){}
- }
-
- static final void log(String s){
- if(log != null){
- log.println(s);
- log.flush();
- }
- }
-
- static final void log(ProxyMessage msg){
- log("Request version:"+msg.version+
- "\tCommand: "+command2String(msg.command));
- log("IP:"+msg.ip +"\tPort:"+msg.port+
- (msg.version==4?"\tUser:"+msg.user:""));
- }
-
- private void pipe(InputStream in,OutputStream out) throws IOException{
- lastReadTime = System.currentTimeMillis();
- byte[] buf = new byte[BUF_SIZE];
- int len = 0;
- while(len >= 0){
- try{
- if(len!=0){
- out.write(buf,0,len);
- out.flush();
- }
- len= in.read(buf);
- lastReadTime = System.currentTimeMillis();
- }catch(InterruptedIOException iioe){
- if(iddleTimeout == 0) return;//Other thread interrupted us.
- long timeSinceRead = System.currentTimeMillis() - lastReadTime;
- if(timeSinceRead >= iddleTimeout - 1000) //-1s for adjustment.
- return;
- len = 0;
-
- }
- }
- }
- static final String command_names[] = {"CONNECT","BIND","UDP_ASSOCIATE"};
-
- static final String command2String(int cmd){
- if(cmd > 0 && cmd < 4) return command_names[cmd-1];
- else return "Unknown Command "+cmd;
- }
-}
diff --git a/app/src/main/java/net/sourceforge/jsocks/Socks4Message.java b/app/src/main/java/net/sourceforge/jsocks/Socks4Message.java
deleted file mode 100644
index 99fb211..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/Socks4Message.java
+++ /dev/null
@@ -1,171 +0,0 @@
-package net.sourceforge.jsocks;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- SOCKS4 Reply/Request message.
-*/
-
-public class Socks4Message extends ProxyMessage{
-
- private byte[] msgBytes;
- private int msgLength;
-
- /**
- * Server failed reply, cmd command for failed request
- */
- public Socks4Message(int cmd){
- super(cmd,null,0);
- this.user = null;
-
- msgLength = 2;
- msgBytes = new byte[2];
-
- msgBytes[0] = (byte) 0;
- msgBytes[1] = (byte) command;
- }
-
- /**
- * Server successfull reply
- */
- public Socks4Message(int cmd,InetAddress ip,int port){
- this(0,cmd,ip,port,null);
- }
-
- /**
- * Client request
- */
- public Socks4Message(int cmd,InetAddress ip,int port,String user){
- this(SOCKS_VERSION,cmd,ip,port,user);
- }
-
- /**
- * Most general constructor
- */
- public Socks4Message(int version, int cmd,
- InetAddress ip,int port,String user){
- super(cmd,ip,port);
- this.user = user;
- this.version = version;
-
- msgLength = user == null?8:9+user.length();
- msgBytes = new byte[msgLength];
-
- msgBytes[0] = (byte) version;
- msgBytes[1] = (byte) command;
- msgBytes[2] = (byte) (port >> 8);
- msgBytes[3] = (byte) port;
-
- byte[] addr;
-
- if(ip != null)
- addr = ip.getAddress();
- else{
- addr = new byte[4];
- addr[0]=addr[1]=addr[2]=addr[3]=0;
- }
- System.arraycopy(addr,0,msgBytes,4,4);
-
- if(user != null){
- byte[] buf = user.getBytes();
- System.arraycopy(buf,0,msgBytes,8,buf.length);
- msgBytes[msgBytes.length -1 ] = 0;
- }
- }
-
- /**
- *Initialise from the stream
- *If clientMode is true attempts to read a server response
- *otherwise reads a client request
- *see read for more detail
- */
- public Socks4Message(InputStream in, boolean clientMode) throws IOException{
- msgBytes = null;
- read(in,clientMode);
- }
-
- @Override
-public void read(InputStream in) throws IOException{
- read(in,true);
- }
-
- @Override
-public void read(InputStream in, boolean clientMode) throws IOException{
- boolean mode4a = false;
- DataInputStream d_in = new DataInputStream(in);
- version= d_in.readUnsignedByte();
- command = d_in.readUnsignedByte();
- if(clientMode && command != REPLY_OK){
- String errMsg;
- if(command >REPLY_OK && command < REPLY_BAD_IDENTD)
- errMsg = replyMessage[command-REPLY_OK];
- else
- errMsg = "Unknown Reply Code";
- throw new SocksException(command,errMsg);
- }
- port = d_in.readUnsignedShort();
- byte[] addr = new byte[4];
- d_in.readFully(addr);
- if (addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] != 0)
- mode4a = true;
- else {
- ip=bytes2IP(addr);
- host = ip.getHostName();
- }
- if(!clientMode){
- StringBuilder sb = new StringBuilder();
- int b;
- while ((b = in.read()) != 0)
- sb.append((char) b);
- user = sb.toString();
- if (mode4a) {
- sb.setLength(0);
- while ((b = in.read()) != 0)
- sb.append((char) b);
- host = sb.toString();
- }
- }
- }
- @Override
-public void write(OutputStream out) throws IOException{
- if(msgBytes == null){
- Socks4Message msg = new Socks4Message(version,command,ip,port,user);
- msgBytes = msg.msgBytes;
- msgLength = msg.msgLength;
- }
- out.write(msgBytes);
- }
-
- //Class methods
- static InetAddress bytes2IP(byte[] addr){
- String s = bytes2IPV4(addr,0);
- try{
- return InetAddress.getByName(s);
- }catch(UnknownHostException uh_ex){
- return null;
- }
- }
-
- //Constants
-
- static final String[] replyMessage ={
- "Request Granted",
- "Request Rejected or Failed",
- "Failed request, can't connect to Identd",
- "Failed request, bad user name"};
-
- static final int SOCKS_VERSION = 4;
-
- public final static int REQUEST_CONNECT = 1;
- public final static int REQUEST_BIND = 2;
-
- public final static int REPLY_OK = 90;
- public final static int REPLY_REJECTED = 91;
- public final static int REPLY_NO_CONNECT = 92;
- public final static int REPLY_BAD_IDENTD = 93;
-
-}
diff --git a/app/src/main/java/net/sourceforge/jsocks/Socks4Proxy.java b/app/src/main/java/net/sourceforge/jsocks/Socks4Proxy.java
deleted file mode 100644
index 9a17fc2..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/Socks4Proxy.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package net.sourceforge.jsocks;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- Proxy which describes SOCKS4 proxy.
-*/
-
-public class Socks4Proxy extends Proxy implements Cloneable{
-
-//Data members
- String user;
-
-//Public Constructors
-//====================
-
- /**
- Creates the SOCKS4 proxy
- @param p Proxy to use to connect to this proxy, allows proxy chaining.
- @param proxyHost Address of the proxy server.
- @param proxyPort Port of the proxy server
- @param user User name to use for identification purposes.
- @throws UnknownHostException If proxyHost can't be resolved.
- */
- public Socks4Proxy(String proxyHost,int proxyPort,String user)
- throws UnknownHostException{
- super(proxyHost,proxyPort);
- this.user = new String(user);
- version = 4;
- }
-
- /**
- Creates the SOCKS4 proxy
- @param p Proxy to use to connect to this proxy, allows proxy chaining.
- @param proxyIP Address of the proxy server.
- @param proxyPort Port of the proxy server
- @param user User name to use for identification purposes.
- */
- public Socks4Proxy(Proxy p,InetAddress proxyIP,int proxyPort,String user){
- super(p,proxyIP,proxyPort);
- this.user = new String(user);
- version = 4;
- }
-
- /**
- Creates the SOCKS4 proxy
- @param proxyIP Address of the proxy server.
- @param proxyPort Port of the proxy server
- @param user User name to use for identification purposes.
- */
- public Socks4Proxy(InetAddress proxyIP,int proxyPort,String user){
- this(null,proxyIP,proxyPort,user);
- }
-
-//Public instance methods
-//========================
-
- /**
- * Creates a clone of this proxy. Changes made to the clone should not
- * affect this object.
- */
- public Object clone(){
- Socks4Proxy newProxy = new Socks4Proxy(proxyIP,proxyPort,user);
- newProxy.chainProxy = chainProxy;
- return newProxy;
- }
-
-
-//Public Static(Class) Methods
-//==============================
-
-
-//Protected Methods
-//=================
-
- protected Proxy copy(){
- Socks4Proxy copy = new Socks4Proxy(proxyIP,proxyPort,user);
- copy.chainProxy = chainProxy;
- return copy;
- }
-
- protected ProxyMessage formMessage(int cmd,InetAddress ip,int port){
- switch(cmd){
- case SOCKS_CMD_CONNECT:
- cmd = Socks4Message.REQUEST_CONNECT;
- break;
- case SOCKS_CMD_BIND:
- cmd = Socks4Message.REQUEST_BIND;
- break;
- default:
- return null;
- }
- return new Socks4Message(cmd,ip,port,user);
- }
- protected ProxyMessage formMessage(int cmd,String host,int port)
- throws UnknownHostException{
- return formMessage(cmd,InetAddress.getByName(host),port);
- }
- protected ProxyMessage formMessage(InputStream in)
- throws SocksException,
- IOException{
- return new Socks4Message(in,true);
- }
-
-}
diff --git a/app/src/main/java/net/sourceforge/jsocks/Socks5DatagramSocket.java b/app/src/main/java/net/sourceforge/jsocks/Socks5DatagramSocket.java
deleted file mode 100644
index b847400..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/Socks5DatagramSocket.java
+++ /dev/null
@@ -1,460 +0,0 @@
-package net.sourceforge.jsocks;
-import java.net.*;
-import java.io.*;
-
-/**
- Datagram socket to interract through the firewall.<BR>
- Can be used same way as the normal DatagramSocket. One should
- be carefull though with the datagram sizes used, as additional data
- is present in both incomming and outgoing datagrams.
- <p>
- SOCKS5 protocol allows to send host address as either:
- <ul>
- <li> IPV4, normal 4 byte address. (10 bytes header size)
- <li> IPV6, version 6 ip address (not supported by Java as for now).
- 22 bytes header size.
- <li> Host name,(7+length of the host name bytes header size).
- </ul>
- As with other Socks equivalents, direct addresses are handled
- transparently, that is data will be send directly when required
- by the proxy settings.
- <p>
- <b>NOTE:</b><br>
- Unlike other SOCKS Sockets, it <b>does not</b> support proxy chaining,
- and will throw an exception if proxy has a chain proxy attached. The
- reason for that is not my laziness, but rather the restrictions of
- the SOCKSv5 protocol. Basicaly SOCKSv5 proxy server, needs to know from
- which host:port datagrams will be send for association, and returns address
- to which datagrams should be send by the client, but it does not
- inform client from which host:port it is going to send datagrams, in fact
- there is even no guarantee they will be send at all and from the same address
- each time.
-
- */
-public class Socks5DatagramSocket extends DatagramSocket{
-
- InetAddress relayIP;
- int relayPort;
- Socks5Proxy proxy;
- private boolean server_mode = false;
- UDPEncapsulation encapsulation;
-
-
- /**
- Construct Datagram socket for communication over SOCKS5 proxy
- server. This constructor uses default proxy, the one set with
- Proxy.setDefaultProxy() method. If default proxy is not set or
- it is set to version4 proxy, which does not support datagram
- forwarding, throws SocksException.
-
- */
- public Socks5DatagramSocket() throws SocksException,
- IOException{
- this(Proxy.defaultProxy,0,null);
- }
- /**
- Construct Datagram socket for communication over SOCKS5 proxy
- server. And binds it to the specified local port.
- This constructor uses default proxy, the one set with
- Proxy.setDefaultProxy() method. If default proxy is not set or
- it is set to version4 proxy, which does not support datagram
- forwarding, throws SocksException.
- */
- public Socks5DatagramSocket(int port) throws SocksException,
- IOException{
- this(Proxy.defaultProxy,port,null);
- }
- /**
- Construct Datagram socket for communication over SOCKS5 proxy
- server. And binds it to the specified local port and address.
- This constructor uses default proxy, the one set with
- Proxy.setDefaultProxy() method. If default proxy is not set or
- it is set to version4 proxy, which does not support datagram
- forwarding, throws SocksException.
- */
- public Socks5DatagramSocket(int port,InetAddress ip) throws SocksException,
- IOException{
- this(Proxy.defaultProxy,port,ip);
- }
-
- /**
- Constructs datagram socket for communication over specified proxy.
- And binds it to the given local address and port. Address of null
- and port of 0, signify any availabale port/address.
- Might throw SocksException, if:
- <ol>
- <li> Given version of proxy does not support UDP_ASSOCIATE.
- <li> Proxy can't be reached.
- <li> Authorization fails.
- <li> Proxy does not want to perform udp forwarding, for any reason.
- </ol>
- Might throw IOException if binding dtagram socket to given address/port
- fails.
- See java.net.DatagramSocket for more details.
- */
- public Socks5DatagramSocket(Proxy p,int port,InetAddress ip)
- throws SocksException,
- IOException{
- super(port,ip);
- if(p == null) throw new SocksException(Proxy.SOCKS_NO_PROXY);
- if(!(p instanceof Socks5Proxy))
- throw new SocksException(-1,"Datagram Socket needs Proxy version 5");
-
- if(p.chainProxy != null)
- throw new SocksException(Proxy.SOCKS_JUST_ERROR,
- "Datagram Sockets do not support proxy chaining.");
-
- proxy =(Socks5Proxy) p.copy();
-
- ProxyMessage msg = proxy.udpAssociate(super.getLocalAddress(),
- super.getLocalPort());
- relayIP = msg.ip;
- if(relayIP.getHostAddress().equals("0.0.0.0")) relayIP = proxy.proxyIP;
- relayPort = msg.port;
-
- encapsulation = proxy.udp_encapsulation;
-
- //debug("Datagram Socket:"+getLocalAddress()+":"+getLocalPort()+"\n");
- //debug("Socks5Datagram: "+relayIP+":"+relayPort+"\n");
- }
-
- /**
- Used by UDPRelayServer.
- */
- Socks5DatagramSocket(boolean server_mode,UDPEncapsulation encapsulation,
- InetAddress relayIP,int relayPort)
- throws IOException{
- super();
- this.server_mode = server_mode;
- this.relayIP = relayIP;
- this.relayPort = relayPort;
- this.encapsulation = encapsulation;
- this.proxy = null;
- }
-
- /**
- Sends the Datagram either through the proxy or directly depending
- on current proxy settings and destination address. <BR>
-
- <B> NOTE: </B> DatagramPacket size should be at least 10 bytes less
- than the systems limit.
-
- <P>
- See documentation on java.net.DatagramSocket
- for full details on how to use this method.
- @param dp Datagram to send.
- @throws IOException If error happens with I/O.
- */
- public void send(DatagramPacket dp) throws IOException{
- //If the host should be accessed directly, send it as is.
- if(!server_mode){
- super.send(dp);
- //debug("Sending directly:");
- return;
- }
-
- byte[] head = formHeader(dp.getAddress(),dp.getPort());
- byte[] buf = new byte[head.length + dp.getLength()];
- byte[] data = dp.getData();
- //Merge head and data
- System.arraycopy(head,0,buf,0,head.length);
- //System.arraycopy(data,dp.getOffset(),buf,head.length,dp.getLength());
- System.arraycopy(data,0,buf,head.length,dp.getLength());
-
- if(encapsulation != null)
- buf = encapsulation.udpEncapsulate(buf,true);
-
- super.send(new DatagramPacket(buf,buf.length,relayIP,relayPort));
- }
- /**
- This method allows to send datagram packets with address type DOMAINNAME.
- SOCKS5 allows to specify host as names rather than ip addresses.Using
- this method one can send udp datagrams through the proxy, without having
- to know the ip address of the destination host.
- <p>
- If proxy specified for that socket has an option resolveAddrLocally set
- to true host will be resolved, and the datagram will be send with address
- type IPV4, if resolve fails, UnknownHostException is thrown.
- @param dp Datagram to send, it should contain valid port and data
- @param host Host name to which datagram should be send.
- @throws IOException If error happens with I/O, or the host can't be
- resolved when proxy settings say that hosts should be resolved locally.
- @see Socks5Proxy#resolveAddrLocally(boolean)
- */
- public void send(DatagramPacket dp, String host) throws IOException {
- dp.setAddress(InetAddress.getByName(host));
- super.send(dp);
- }
-
- /**
- * Receives udp packet. If packet have arrived from the proxy relay server,
- * it is processed and address and port of the packet are set to the
- * address and port of sending host.<BR>
- * If the packet arrived from anywhere else it is not changed.<br>
- * <B> NOTE: </B> DatagramPacket size should be at least 10 bytes bigger
- * than the largest packet you expect (this is for IPV4 addresses).
- * For hostnames and IPV6 it is even more.
- @param dp Datagram in which all relevent information will be copied.
- */
- public void receive(DatagramPacket dp) throws IOException{
- super.receive(dp);
-
- if(server_mode){
- //Drop all datagrams not from relayIP/relayPort
- int init_length = dp.getLength();
- int initTimeout = getSoTimeout();
- long startTime = System.currentTimeMillis();
-
- while(!relayIP.equals(dp.getAddress()) ||
- relayPort != dp.getPort()){
-
- //Restore datagram size
- dp.setLength(init_length);
-
- //If there is a non-infinit timeout on this socket
- //Make sure that it happens no matter how often unexpected
- //packets arrive.
- if(initTimeout != 0){
- int newTimeout = initTimeout - (int)(System.currentTimeMillis() -
- startTime);
- if(newTimeout <= 0) throw new InterruptedIOException(
- "In Socks5DatagramSocket->receive()");
- setSoTimeout(newTimeout);
- }
-
- super.receive(dp);
- }
-
- //Restore timeout settings
- if(initTimeout != 0) setSoTimeout(initTimeout);
-
- }else if(!relayIP.equals(dp.getAddress()) ||
- relayPort != dp.getPort())
- return; // Recieved direct packet
- //If the datagram is not from the relay server, return it it as is.
-
- byte[] data;
- data = dp.getData();
-
- if(encapsulation != null)
- data = encapsulation.udpEncapsulate(data,false);
-
- int offset = 0; //Java 1.1
- //int offset = dp.getOffset(); //Java 1.2
-
- ByteArrayInputStream bIn = new ByteArrayInputStream(data,offset,
- dp.getLength());
-
-
- ProxyMessage msg = new Socks5Message(bIn);
- dp.setPort(msg.port);
- dp.setAddress(msg.getInetAddress());
-
- //what wasn't read by the Message is the data
- int data_length = bIn.available();
- //Shift data to the left
- System.arraycopy(data,offset+dp.getLength()-data_length,
- data,offset,data_length);
-
-
- dp.setLength(data_length);
- }
-
- /**
- * Returns port assigned by the proxy, to which datagrams are relayed.
- * It is not the same port to which other party should send datagrams.
- @return Port assigned by socks server to which datagrams are send
- for association.
- */
- public int getLocalPort(){
- if(server_mode) return super.getLocalPort();
- return relayPort;
- }
- /**
- * Address assigned by the proxy, to which datagrams are send for relay.
- * It is not necesseraly the same address, to which other party should send
- * datagrams.
- @return Address to which datagrams are send for association.
- */
- public InetAddress getLocalAddress(){
- if(server_mode) return super.getLocalAddress();
- return relayIP;
- }
-
- /**
- * Closes datagram socket, and proxy connection.
- */
- public void close(){
- if(!server_mode) proxy.endSession();
- super.close();
- }
-
- /**
- This method checks wether proxy still runs udp forwarding service
- for this socket.
- <p>
- This methods checks wether the primary connection to proxy server
- is active. If it is, chances are that proxy continues to forward
- datagrams being send from this socket. If it was closed, most likely
- datagrams are no longer being forwarded by the server.
- <p>
- Proxy might decide to stop forwarding datagrams, in which case it
- should close primary connection. This method allows to check, wether
- this have been done.
- <p>
- You can specify timeout for which we should be checking EOF condition
- on the primary connection. Timeout is in milliseconds. Specifying 0 as
- timeout implies infinity, in which case method will block, until
- connection to proxy is closed or an error happens, and then return false.
- <p>
- One possible scenario is to call isProxyactive(0) in separate thread,
- and once it returned notify other threads about this event.
-
- @param timeout For how long this method should block, before returning.
- @return true if connection to proxy is active, false if eof or error
- condition have been encountered on the connection.
- */
- public boolean isProxyAlive(int timeout){
- if(server_mode) return false;
- if(proxy != null){
- try{
- proxy.proxySocket.setSoTimeout(timeout);
-
- int eof = proxy.in.read();
- if(eof < 0) return false; // EOF encountered.
- else return true; // This really should not happen
-
- }catch(InterruptedIOException iioe){
- return true; // read timed out.
- }catch(IOException ioe){
- return false;
- }
- }
- return false;
- }
-
-//PRIVATE METHODS
-//////////////////
-
-
- private byte[] formHeader(InetAddress ip, int port){
- Socks5Message request = new Socks5Message(0,ip,port);
- request.data[0] = 0;
- return request.data;
- }
-
-
-/*======================================================================
-
-//Mainly Test functions
-//////////////////////
-
- private String bytes2String(byte[] b){
- String s="";
- char[] hex_digit = { '0','1','2','3','4','5','6','7','8','9',
- 'A','B','C','D','E','F'};
- for(int i=0;i<b.length;++i){
- int i1 = (b[i] & 0xF0) >> 4;
- int i2 = b[i] & 0xF;
- s+=hex_digit[i1];
- s+=hex_digit[i2];
- s+=" ";
- }
- return s;
- }
- private static final void debug(String s){
- if(DEBUG)
- System.out.print(s);
- }
-
- private static final boolean DEBUG = true;
-
-
- public static void usage(){
- System.err.print(
- "Usage: java Socks.SocksDatagramSocket host port [socksHost socksPort]\n");
- }
-
- static final int defaultProxyPort = 1080; //Default Port
- static final String defaultProxyHost = "www-proxy"; //Default proxy
-
- public static void main(String args[]){
- int port;
- String host;
- int proxyPort;
- String proxyHost;
- InetAddress ip;
-
- if(args.length > 1 && args.length < 5){
- try{
-
- host = args[0];
- port = Integer.parseInt(args[1]);
-
- proxyPort =(args.length > 3)? Integer.parseInt(args[3])
- : defaultProxyPort;
-
- host = args[0];
- ip = InetAddress.getByName(host);
-
- proxyHost =(args.length > 2)? args[2]
- : defaultProxyHost;
-
- Proxy.setDefaultProxy(proxyHost,proxyPort);
- Proxy p = Proxy.getDefaultProxy();
- p.addDirect("lux");
-
-
- DatagramSocket ds = new Socks5DatagramSocket();
-
-
- BufferedReader in = new BufferedReader(
- new InputStreamReader(System.in));
- String s;
-
- System.out.print("Enter line:");
- s = in.readLine();
-
- while(s != null){
- byte[] data = (s+"\r\n").getBytes();
- DatagramPacket dp = new DatagramPacket(data,0,data.length,
- ip,port);
- System.out.println("Sending to: "+ip+":"+port);
- ds.send(dp);
- dp = new DatagramPacket(new byte[1024],1024);
-
- System.out.println("Trying to recieve on port:"+
- ds.getLocalPort());
- ds.receive(dp);
- System.out.print("Recieved:\n"+
- "From:"+dp.getAddress()+":"+dp.getPort()+
- "\n\n"+
- new String(dp.getData(),dp.getOffset(),dp.getLength())+"\n"
- );
- System.out.print("Enter line:");
- s = in.readLine();
-
- }
- ds.close();
- System.exit(1);
-
- }catch(SocksException s_ex){
- System.err.println("SocksException:"+s_ex);
- s_ex.printStackTrace();
- System.exit(1);
- }catch(IOException io_ex){
- io_ex.printStackTrace();
- System.exit(1);
- }catch(NumberFormatException num_ex){
- usage();
- num_ex.printStackTrace();
- System.exit(1);
- }
-
- }else{
- usage();
- }
- }
-*/
-
-}
diff --git a/app/src/main/java/net/sourceforge/jsocks/Socks5Message.java b/app/src/main/java/net/sourceforge/jsocks/Socks5Message.java
deleted file mode 100644
index ea2a321..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/Socks5Message.java
+++ /dev/null
@@ -1,292 +0,0 @@
-package net.sourceforge.jsocks;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- SOCKS5 request/response message.
-*/
-
-public class Socks5Message extends ProxyMessage{
- /** Address type of given message*/
- public int addrType;
-
- byte[] data;
-
- /**
- Server error response.
- @param cmd Error code.
- */
- public Socks5Message(int cmd){
- super(cmd,null,0);
- data = new byte[3];
- data[0] = SOCKS_VERSION; //Version.
- data[1] = (byte)cmd; //Reply code for some kind of failure.
- data[2] = 0; //Reserved byte.
- }
-
- /**
- Construct client request or server response.
- @param cmd - Request/Response code.
- @param ip - IP field.
- @paarm port - port field.
- */
- public Socks5Message(int cmd,InetAddress ip,int port){
- super(cmd,ip,port);
- this.host = ip==null?"0.0.0.0":ip.getHostName();
- this.version = SOCKS_VERSION;
-
- byte[] addr;
-
- if(ip == null){
- addr = new byte[4];
- addr[0]=addr[1]=addr[2]=addr[3]=0;
- }else
- addr = ip.getAddress();
-
- addrType = addr.length == 4 ? SOCKS_ATYP_IPV4
- : SOCKS_ATYP_IPV6;
-
- data = new byte[6+addr.length];
- data[0] = (byte) SOCKS_VERSION; //Version
- data[1] = (byte) command; //Command
- data[2] = (byte) 0; //Reserved byte
- data[3] = (byte) addrType; //Address type
-
- //Put Address
- System.arraycopy(addr,0,data,4,addr.length);
- //Put port
- data[data.length-2] = (byte)(port>>8);
- data[data.length-1] = (byte)(port);
- }
-
-
- /**
- Construct client request or server response.
- @param cmd - Request/Response code.
- @param hostName - IP field as hostName, uses ADDR_TYPE of HOSTNAME.
- @paarm port - port field.
- */
- public Socks5Message(int cmd,String hostName,int port){
- super(cmd,null,port);
- this.host = hostName;
- this.version = SOCKS_VERSION;
-
- //System.out.println("Doing ATYP_DOMAINNAME");
-
- addrType = SOCKS_ATYP_DOMAINNAME;
- byte addr[] = hostName.getBytes();
-
- data =new byte[7+addr.length];
- data[0] = (byte) SOCKS_VERSION; //Version
- data[1] = (byte) command; //Command
- data[2] = (byte) 0; //Reserved byte
- data[3] = (byte) SOCKS_ATYP_DOMAINNAME; //Address type
- data[4] = (byte) addr.length; //Length of the address
-
- //Put Address
- System.arraycopy(addr,0,data,5,addr.length);
- //Put port
- data[data.length-2] = (byte)(port >>8);
- data[data.length-1] = (byte)(port);
- }
-
- /**
- Initialises Message from the stream. Reads server response from
- given stream.
- @param in Input stream to read response from.
- @throws SocksException If server response code is not SOCKS_SUCCESS(0), or
- if any error with protocol occurs.
- @throws IOException If any error happens with I/O.
- */
- public Socks5Message(InputStream in) throws SocksException,
- IOException{
- this(in,true);
- }
-
- /**
- Initialises Message from the stream. Reads server response or client
- request from given stream.
-
- @param in Input stream to read response from.
- @param clinetMode If true read server response, else read client request.
- @throws SocksException If server response code is not SOCKS_SUCCESS(0) and
- reading in client mode, or if any error with protocol occurs.
- @throws IOException If any error happens with I/O.
- */
- public Socks5Message(InputStream in,boolean clientMode)throws SocksException,
- IOException{
- read(in,clientMode);
- }
-
-
- /**
- Initialises Message from the stream. Reads server response from
- given stream.
- @param in Input stream to read response from.
- @throws SocksException If server response code is not SOCKS_SUCCESS(0), or
- if any error with protocol occurs.
- @throws IOException If any error happens with I/O.
- */
- public void read(InputStream in) throws SocksException,
- IOException{
- read(in,true);
- }
-
-
- /**
- Initialises Message from the stream. Reads server response or client
- request from given stream.
-
- @param in Input stream to read response from.
- @param clinetMode If true read server response, else read client request.
- @throws SocksException If server response code is not SOCKS_SUCCESS(0) and
- reading in client mode, or if any error with protocol occurs.
- @throws IOException If any error happens with I/O.
- */
- public void read(InputStream in,boolean clientMode) throws SocksException,
- IOException{
- data = null;
- ip = null;
-
- DataInputStream di = new DataInputStream(in);
-
- version = di.readUnsignedByte();
- command = di.readUnsignedByte();
- if(clientMode && command != 0)
- throw new SocksException(command);
-
- @SuppressWarnings("unused")
- int reserved = di.readUnsignedByte();
- addrType = di.readUnsignedByte();
-
- byte addr[];
-
- switch(addrType){
- case SOCKS_ATYP_IPV4:
- addr = new byte[4];
- di.readFully(addr);
- host = bytes2IPV4(addr,0);
- break;
- case SOCKS_ATYP_IPV6:
- addr = new byte[SOCKS_IPV6_LENGTH];//I believe it is 16 bytes,huge!
- di.readFully(addr);
- host = bytes2IPV6(addr,0);
- break;
- case SOCKS_ATYP_DOMAINNAME:
- //System.out.println("Reading ATYP_DOMAINNAME");
- addr = new byte[di.readUnsignedByte()];//Next byte shows the length
- di.readFully(addr);
- host = new String(addr);
- break;
- default:
- throw(new SocksException(Proxy.SOCKS_JUST_ERROR));
- }
-
- port = di.readUnsignedShort();
-
- if(addrType != SOCKS_ATYP_DOMAINNAME && doResolveIP){
- try{
- ip = InetAddress.getByName(host);
- }catch(UnknownHostException uh_ex){
- }
- }
- }
-
- /**
- Writes the message to the stream.
- @param out Output stream to which message should be written.
- */
- public void write(OutputStream out)throws SocksException,
- IOException{
- if(data == null){
- Socks5Message msg;
-
- if(addrType == SOCKS_ATYP_DOMAINNAME)
- msg = new Socks5Message(command,host,port);
- else{
- if(ip == null){
- try{
- ip = InetAddress.getByName(host);
- }catch(UnknownHostException uh_ex){
- throw new SocksException(Proxy.SOCKS_JUST_ERROR);
- }
- }
- msg = new Socks5Message(command,ip,port);
- }
- data = msg.data;
- }
- out.write(data);
- }
-
- /**
- Returns IP field of the message as IP, if the message was created
- with ATYP of HOSTNAME, it will attempt to resolve the hostname,
- which might fail.
- @throws UnknownHostException if host can't be resolved.
- */
- public InetAddress getInetAddress() throws UnknownHostException{
- if(ip!=null) return ip;
-
- return (ip=InetAddress.getByName(host));
- }
-
- /**
- Returns string representation of the message.
- */
- public String toString(){
- String s=
- "Socks5Message:"+"\n"+
- "VN "+version+"\n"+
- "CMD "+command+"\n"+
- "ATYP "+addrType+"\n"+
- "ADDR "+host+"\n"+
- "PORT "+port+"\n";
- return s;
- }
-
-
- /**
- *Wether to resolve hostIP returned from SOCKS server
- *that is wether to create InetAddress object from the
- *hostName string
- */
- static public boolean resolveIP(){ return doResolveIP;}
-
- /**
- *Wether to resolve hostIP returned from SOCKS server
- *that is wether to create InetAddress object from the
- *hostName string
- *@param doResolve Wether to resolve hostIP from SOCKS server.
- *@return Previous value.
- */
- static public boolean resolveIP(boolean doResolve){
- boolean old = doResolveIP;
- doResolveIP = doResolve;
- return old;
- }
-
- /*
- private static final void debug(String s){
- if(DEBUG)
- System.out.print(s);
- }
- private static final boolean DEBUG = false;
- */
-
- //SOCKS5 constants
- public static final int SOCKS_VERSION =5;
-
- public static final int SOCKS_ATYP_IPV4 =0x1; //Where is 2??
- public static final int SOCKS_ATYP_DOMAINNAME =0x3; //!!!!rfc1928
- public static final int SOCKS_ATYP_IPV6 =0x4;
-
- public static final int SOCKS_IPV6_LENGTH =16;
-
- static boolean doResolveIP = true;
-
-}
diff --git a/app/src/main/java/net/sourceforge/jsocks/Socks5Proxy.java b/app/src/main/java/net/sourceforge/jsocks/Socks5Proxy.java
deleted file mode 100644
index aa9c643..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/Socks5Proxy.java
+++ /dev/null
@@ -1,231 +0,0 @@
-package net.sourceforge.jsocks;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.util.Enumeration;
-import java.util.Hashtable;
-
-/**
- SOCKS5 Proxy.
-*/
-
-public class Socks5Proxy extends Proxy implements Cloneable{
-
-//Data members
- private Hashtable<Integer, Authentication> authMethods = new Hashtable<Integer, Authentication>();
- private int selectedMethod;
-
- boolean resolveAddrLocally = true;
- UDPEncapsulation udp_encapsulation=null;
-
-
-//Public Constructors
-//====================
-
- /**
- Creates SOCKS5 proxy.
- @param proxyHost Host on which a Proxy server runs.
- @param proxyPort Port on which a Proxy server listens for connections.
- @throws UnknownHostException If proxyHost can't be resolved.
- */
- public Socks5Proxy(String proxyHost,int proxyPort)
- throws UnknownHostException{
- super(proxyHost,proxyPort);
- version = 5;
- setAuthenticationMethod(0,new AuthenticationNone());
- }
-
-
- /**
- Creates SOCKS5 proxy.
- @param proxyIP Host on which a Proxy server runs.
- @param proxyPort Port on which a Proxy server listens for connections.
- */
- public Socks5Proxy(InetAddress proxyIP,int proxyPort){
- super(proxyIP,proxyPort);
- version = 5;
- setAuthenticationMethod(0,new AuthenticationNone());
- }
-
-
-//Public instance methods
-//========================
-
-
- /**
- * Wether to resolve address locally or to let proxy do so.
- <p>
- SOCKS5 protocol allows to send host names rather then IPs in the
- requests, this option controls wether the hostnames should be send
- to the proxy server as names, or should they be resolved locally.
- @param doResolve Wether to perform resolution locally.
- @return Previous settings.
- */
- public boolean resolveAddrLocally(boolean doResolve){
- boolean old = resolveAddrLocally;
- resolveAddrLocally = doResolve;
- return old;
- }
- /**
- Get current setting on how the addresses should be handled.
- @return Current setting for address resolution.
- @see Socks5Proxy#resolveAddrLocally(boolean doResolve)
- */
- public boolean resolveAddrLocally(){
- return resolveAddrLocally;
- }
-
- /**
- Adds another authentication method.
- @param methodId Authentication method id, see rfc1928
- @param method Implementation of Authentication
- @see Authentication
- */
- public boolean setAuthenticationMethod(int methodId,
- Authentication method){
- if(methodId<0 || methodId > 255)
- return false;
- if(method == null){
- //Want to remove a particular method
- return (authMethods.remove(new Integer(methodId)) != null);
- }else{//Add the method, or rewrite old one
- authMethods.put(new Integer(methodId),method);
- }
- return true;
- }
-
- /**
- Get authentication method, which corresponds to given method id
- @param methodId Authentication method id.
- @return Implementation for given method or null, if one was not set.
- */
- public Authentication getAuthenticationMethod(int methodId){
- Object method = authMethods.get(new Integer(methodId));
- if(method == null) return null;
- return (Authentication)method;
- }
-
- /**
- Creates a clone of this Proxy.
- */
- @SuppressWarnings("unchecked")
-public Object clone(){
- Socks5Proxy newProxy = new Socks5Proxy(proxyIP,proxyPort);
- newProxy.authMethods = (Hashtable<Integer, Authentication>) this.authMethods.clone();
- newProxy.resolveAddrLocally = resolveAddrLocally;
- newProxy.chainProxy = chainProxy;
- return newProxy;
- }
-
-//Public Static(Class) Methods
-//==============================
-
-
-//Protected Methods
-//=================
-
- protected Proxy copy(){
- Socks5Proxy copy = new Socks5Proxy(proxyIP,proxyPort);
- copy.authMethods = this.authMethods; //same Hash, no copy
- copy.chainProxy = this.chainProxy;
- copy.resolveAddrLocally = this.resolveAddrLocally;
- return copy;
- }
- /**
- *
- *
- */
- protected void startSession()throws SocksException{
- super.startSession();
- Authentication auth;
- Socket ps = proxySocket; //The name is too long
-
- try{
-
- byte nMethods = (byte) authMethods.size(); //Number of methods
-
- byte[] buf = new byte[2+nMethods]; //2 is for VER,NMETHODS
- buf[0] = (byte) version;
- buf[1] = nMethods; //Number of methods
- int i=2;
-
- Enumeration<Integer> ids = authMethods.keys();
- while(ids.hasMoreElements())
- buf[i++] = (byte)((Integer)ids.nextElement()).intValue();
-
- out.write(buf);
- out.flush();
-
- int versionNumber = in.read();
- selectedMethod = in.read();
-
- if(versionNumber < 0 || selectedMethod < 0){
- //EOF condition was reached
- endSession();
- throw(new SocksException(SOCKS_PROXY_IO_ERROR,
- "Connection to proxy lost."));
- }
- if(versionNumber < version){
- //What should we do??
- }
- if(selectedMethod == 0xFF){ //No method selected
- ps.close();
- throw ( new SocksException(SOCKS_AUTH_NOT_SUPPORTED));
- }
-
- auth = getAuthenticationMethod(selectedMethod);
- if(auth == null){
- //This shouldn't happen, unless method was removed by other
- //thread, or the server stuffed up
- throw(new SocksException(SOCKS_JUST_ERROR,
- "Speciefied Authentication not found!"));
- }
- Object[] in_out = auth.doSocksAuthentication(selectedMethod,ps);
- if(in_out == null){
- //Authentication failed by some reason
- throw(new SocksException(SOCKS_AUTH_FAILURE));
- }
- //Most authentication methods are expected to return
- //simply the input/output streams associated with
- //the socket. However if the auth. method requires
- //some kind of encryption/decryption being done on the
- //connection it should provide classes to handle I/O.
-
- in = (InputStream) in_out[0];
- out = (OutputStream) in_out[1];
- if(in_out.length > 2)
- udp_encapsulation = (UDPEncapsulation) in_out[2];
-
- }catch(SocksException s_ex){
- throw s_ex;
- }catch(UnknownHostException uh_ex){
- throw(new SocksException(SOCKS_PROXY_NO_CONNECT));
- }catch(SocketException so_ex){
- throw(new SocksException(SOCKS_PROXY_NO_CONNECT));
- }catch(IOException io_ex){
- //System.err.println(io_ex);
- throw(new SocksException(SOCKS_PROXY_IO_ERROR,""+io_ex));
- }
- }
-
- protected ProxyMessage formMessage(int cmd,InetAddress ip,int port){
- return new Socks5Message(cmd,ip,port);
- }
- protected ProxyMessage formMessage(int cmd,String host,int port)
- throws UnknownHostException{
- if(resolveAddrLocally)
- return formMessage(cmd,InetAddress.getByName(host),port);
- else
- return new Socks5Message(cmd,host,port);
- }
- protected ProxyMessage formMessage(InputStream in)
- throws SocksException,
- IOException{
- return new Socks5Message(in);
- }
-
-}
diff --git a/app/src/main/java/net/sourceforge/jsocks/SocksException.java b/app/src/main/java/net/sourceforge/jsocks/SocksException.java
deleted file mode 100644
index 764587f..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/SocksException.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package net.sourceforge.jsocks;
-
-/**
- Exception thrown by various socks classes to indicate errors
- with protocol or unsuccessful server responses.
-*/
-public class SocksException extends java.io.IOException{
- private static final long serialVersionUID = 6141184566248512277L;
-
- /**
- Construct a SocksException with given error code.
- <p>
- Tries to look up message which corresponds to this error code.
- @param errCode Error code for this exception.
- */
- public SocksException(int errCode){
- this.errCode = errCode;
- if((errCode >> 16) == 0){
- //Server reply error message
- errString = errCode <= serverReplyMessage.length ?
- serverReplyMessage[errCode] :
- UNASSIGNED_ERROR_MESSAGE;
- }else{
- //Local error
- errCode = (errCode >> 16) -1;
- errString = errCode <= localErrorMessage.length ?
- localErrorMessage[errCode] :
- UNASSIGNED_ERROR_MESSAGE;
- }
- }
- /**
- Constructs a SocksException with given error code and message.
- @param errCode Error code.
- @param errString Error Message.
- */
- public SocksException(int errCode,String errString){
- this.errCode = errCode;
- this.errString = errString;
- }
- /**
- Get the error code associated with this exception.
- @return Error code associated with this exception.
- */
- public int getErrorCode(){
- return errCode;
- }
- /**
- Get human readable representation of this exception.
- @return String represntation of this exception.
- */
- public String toString(){
- return errString;
- }
-
- static final String UNASSIGNED_ERROR_MESSAGE =
- "Unknown error message";
- static final String serverReplyMessage[] = {
- "Succeeded",
- "General SOCKS server failure",
- "Connection not allowed by ruleset",
- "Network unreachable",
- "Host unreachable",
- "Connection refused",
- "TTL expired",
- "Command not supported",
- "Address type not supported" };
-
- static final String localErrorMessage[] ={
- "SOCKS server not specified",
- "Unable to contact SOCKS server",
- "IO error",
- "None of Authentication methods are supported",
- "Authentication failed",
- "General SOCKS fault" };
-
- String errString;
- public int errCode;
-
-}//End of SocksException class
-
diff --git a/app/src/main/java/net/sourceforge/jsocks/SocksServerSocket.java b/app/src/main/java/net/sourceforge/jsocks/SocksServerSocket.java
deleted file mode 100644
index 179e9c4..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/SocksServerSocket.java
+++ /dev/null
@@ -1,164 +0,0 @@
-package net.sourceforge.jsocks;
-
-import java.net.*;
-import java.io.*;
-
-/**
- SocksServerSocket allows to accept connections from one particular
- host through the SOCKS4 or SOCKS5 proxy.
-*/
-public class SocksServerSocket extends ServerSocket{
- //Data members
- protected Proxy proxy;
- protected String localHost;
- protected InetAddress localIP;
- protected int localPort;
-
- boolean doing_direct = false;
- InetAddress remoteAddr;
-
- /**
- *Creates ServerSocket capable of accepting one connection
- *through the firewall, uses given proxy.
- *@param host Host from which the connection should be recieved.
- *@param port Port number of the primary connection.
- */
- public SocksServerSocket(String host, int port) throws SocksException,
- UnknownHostException, IOException {
-
- super(0);
- remoteAddr = InetAddress.getByName(host);
- doDirect();
- }
-
- /**
- * Creates ServerSocket capable of accepting one connection
- * through the firewall, uses default Proxy.
- *@param ip Host from which the connection should be recieved.
- *@param port Port number of the primary connection.
- */
- public SocksServerSocket(InetAddress ip, int port) throws SocksException,
- IOException{
- this(Proxy.defaultProxy,ip,port);
- }
-
- /**
- *Creates ServerSocket capable of accepting one connection
- *through the firewall, uses given proxy.
- *@param ip Host from which the connection should be recieved.
- *@param port Port number of the primary connection.
- */
- public SocksServerSocket(Proxy p, InetAddress ip, int port)
- throws SocksException, IOException {
- super(0);
-
- remoteAddr = ip;
- doDirect();
- }
-
-
- /**
- * Accepts the incoming connection.
- */
- public Socket accept() throws IOException{
- Socket s;
-
- if(!doing_direct){
- if(proxy == null) return null;
-
- ProxyMessage msg = proxy.accept();
- s = msg.ip == null? new SocksSocket(msg.host,msg.port,proxy)
- : new SocksSocket(msg.ip,msg.port,proxy);
- //Set timeout back to 0
- proxy.proxySocket.setSoTimeout(0);
- }else{ //Direct Connection
-
- //Mimic the proxy behaviour,
- //only accept connections from the speciefed host.
- while(true){
- s = super.accept();
- if(s.getInetAddress().equals(remoteAddr)){
- //got the connection from the right host
- //Close listenning socket.
- break;
- }else
- s.close(); //Drop all connections from other hosts
- }
-
- }
- proxy = null;
- //Return accepted socket
- return s;
- }
-
- /**
- * Closes the connection to proxy if socket have not been accepted, if
- * the direct connection is used, closes direct ServerSocket. If the
- * client socket have been allready accepted, does nothing.
- */
- public void close() throws IOException{
- super.close();
- if(proxy != null) proxy.endSession();
- proxy = null;
- }
-
- /**
- Get the name of the host proxy is using to listen for incoming
- connection.
- <P>
- Usefull when address is returned by proxy as the hostname.
- @return the hostname of the address proxy is using to listen
- for incoming connection.
- */
- public String getHost(){
- return localHost;
- }
-
- /**
- * Get address assigned by proxy to listen for incomming
- * connections, or the local machine address if doing direct
- * connection.
- */
- public InetAddress getInetAddress(){
- if(localIP == null){
- try{
- localIP = InetAddress.getByName(localHost);
- }catch(UnknownHostException e){
- return null;
- }
- }
- return localIP;
- }
-
- /**
- * Get port assigned by proxy to listen for incoming connections, or
- the port chosen by local system, if accepting directly.
- */
- public int getLocalPort(){
- return localPort;
- }
-
- /**
- Set Timeout.
-
- @param timeout Amount of time in milliseconds, accept should wait for
- incoming connection before failing with exception.
- Zero timeout implies infinity.
- */
- public void setSoTimeout(int timeout) throws SocketException{
- super.setSoTimeout(timeout);
- if(!doing_direct) proxy.proxySocket.setSoTimeout(timeout);
- }
-
-
-//Private Methods
-//////////////////
-
- private void doDirect(){
- doing_direct = true;
- localPort = super.getLocalPort();
- localIP = super.getInetAddress();
- localHost = localIP.getHostName();
- }
-
-}
diff --git a/app/src/main/java/net/sourceforge/jsocks/SocksSocket.java b/app/src/main/java/net/sourceforge/jsocks/SocksSocket.java
deleted file mode 100644
index cf9ff65..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/SocksSocket.java
+++ /dev/null
@@ -1,291 +0,0 @@
-package net.sourceforge.jsocks;
-
-import java.net.*;
-import java.io.*;
-
-/**
- * SocksSocket tryies to look very similar to normal Socket,
- * while allowing connections through the SOCKS4 or 5 proxy.
- * To use this class you will have to identify proxy you need
- * to use, Proxy class allows you to set default proxy, which
- * will be used by all Socks aware sockets. You can also create
- * either Socks4Proxy or Socks5Proxy, and use them by passing to the
- * appropriate constructors.
- * <P>
- * Using Socks package can be as easy as that:
- *
- * <pre><tt>
- *
- * import Socks.*;
- * ....
- *
- * try{
- * //Specify SOCKS5 proxy
- * Proxy.setDefaultProxy("socks-proxy",1080);
- *
- * //OR you still use SOCKS4
- * //Code below uses SOCKS4 proxy
- * //Proxy.setDefaultProxy("socks-proxy",1080,userName);
- *
- * Socket s = SocksSocket("some.host.of.mine",13);
- * readTimeFromSock(s);
- * }catch(SocksException sock_ex){
- * //Usually it will turn in more or less meaningfull message
- * System.err.println("SocksException:"+sock_ex);
- * }
- *
- * </tt></pre>
- *<P>
- * However if the need exist for more control, like resolving addresses
- * remotely, or using some non-trivial authentication schemes, it can be done.
- */
-
-public class SocksSocket extends Socket{
- //Data members
- protected Proxy proxy;
- protected String localHost, remoteHost;
- protected InetAddress localIP, remoteIP;
- protected int localPort,remotePort;
-
- private Socket directSock = null;
-
- /**
- * Tryies to connect to given host and port
- * using default proxy. If no default proxy speciefied
- * it throws SocksException with error code SOCKS_NO_PROXY.
- @param host Machine to connect to.
- @param port Port to which to connect.
- * @see SocksSocket#SocksSocket(Proxy,String,int)
- * @see Socks5Proxy#resolveAddrLocally
- */
- public SocksSocket(String host,int port)
- throws SocksException,UnknownHostException{
- this(Proxy.defaultProxy,host,port);
- }
- /**
- * Connects to host port using given proxy server.
- @param p Proxy to use.
- @param host Machine to connect to.
- @param port Port to which to connect.
- @throws UnknownHostException
- If one of the following happens:
- <ol>
-
- <li> Proxy settings say that address should be resolved locally, but
- this fails.
- <li> Proxy settings say that the host should be contacted directly but
- host name can't be resolved.
- </ol>
- @throws SocksException
- If one of the following happens:
- <ul>
- <li> Proxy is is null.
- <li> Proxy settings say that the host should be contacted directly but
- this fails.
- <li> Socks Server can't be contacted.
- <li> Authentication fails.
- <li> Connection is not allowed by the SOCKS proxy.
- <li> SOCKS proxy can't establish the connection.
- <li> Any IO error occured.
- <li> Any protocol error occured.
- </ul>
- @throws IOexception if anything is wrong with I/O.
- @see Socks5Proxy#resolveAddrLocally
- */
- public SocksSocket(Proxy p, String host, int port) throws SocksException,
- UnknownHostException {
- remoteHost = host;
- remotePort = port;
- remoteIP = InetAddress.getByName(host);
- doDirect();
- }
-
- /**
- Connects to given ip and port using given Proxy server.
- @param p Proxy to use.
- @param ip Machine to connect to.
- @param port Port to which to connect.
-
- */
- public SocksSocket(InetAddress ip, int port) throws SocksException{
- this.remoteIP = ip;
- this.remotePort = port;
- this.remoteHost = ip.getHostName();
- doDirect();
- }
-
-
- /**
- * These 2 constructors are used by the SocksServerSocket.
- * This socket simply overrides remoteHost, remotePort
- */
- protected SocksSocket(String host,int port,Proxy proxy){
- this.remotePort = port;
- this.proxy = proxy;
- this.localIP = proxy.proxySocket.getLocalAddress();
- this.localPort = proxy.proxySocket.getLocalPort();
- this.remoteHost = host;
- }
- protected SocksSocket(InetAddress ip,int port,Proxy proxy){
- remoteIP = ip;
- remotePort = port;
- this.proxy = proxy;
- this.localIP = proxy.proxySocket.getLocalAddress();
- this.localPort = proxy.proxySocket.getLocalPort();
- remoteHost = remoteIP.getHostName();
- }
-
- /**
- * Same as Socket
- */
- public void close() throws IOException{
- if(proxy!= null)proxy.endSession();
- proxy = null;
- }
- /**
- * Same as Socket
- */
- public InputStream getInputStream(){
- return proxy.in;
- }
- /**
- * Same as Socket
- */
- public OutputStream getOutputStream(){
- return proxy.out;
- }
- /**
- * Same as Socket
- */
- public int getPort(){
- return remotePort;
- }
- /**
- * Returns remote host name, it is usefull in cases when addresses
- * are resolved by proxy, and we can't create InetAddress object.
- @return The name of the host this socket is connected to.
- */
- public String getHost(){
- return remoteHost;
- }
- /**
- * Get remote host as InetAddress object, might return null if
- * addresses are resolved by proxy, and it is not possible to resolve
- * it locally
- @return Ip address of the host this socket is connected to, or null
- if address was returned by the proxy as DOMAINNAME and can't be
- resolved locally.
- */
- public InetAddress getInetAddress(){
- if(remoteIP == null){
- try{
- remoteIP = InetAddress.getByName(remoteHost);
- }catch(UnknownHostException e){
- return null;
- }
- }
- return remoteIP;
- }
-
- /**
- * Get the port assigned by the proxy for the socket, not
- * the port on locall machine as in Socket.
- @return Port of the socket used on the proxy server.
- */
- public int getLocalPort(){
- return localPort;
- }
-
- /**
- * Get address assigned by proxy to make a remote connection,
- * it might be different from the host specified for the proxy.
- * Can return null if socks server returned this address as hostname
- * and it can't be resolved locally, use getLocalHost() then.
- @return Address proxy is using to make a connection.
- */
- public InetAddress getLocalAddress(){
- if(localIP == null){
- try{
- localIP = InetAddress.getByName(localHost);
- }catch(UnknownHostException e){
- return null;
- }
- }
- return localIP;
- }
- /**
- Get name of the host, proxy has assigned to make a remote connection
- for this socket. This method is usefull when proxy have returned
- address as hostname, and we can't resolve it on this machine.
- @return The name of the host proxy is using to make a connection.
- */
- public String getLocalHost(){
- return localHost;
- }
-
- /**
- Same as socket.
- */
- public void setSoLinger(boolean on,int val) throws SocketException{
- proxy.proxySocket.setSoLinger(on,val);
- }
- /**
- Same as socket.
- */
- public int getSoLinger(int timeout) throws SocketException{
- return proxy.proxySocket.getSoLinger();
- }
- /**
- Same as socket.
- */
- public void setSoTimeout(int timeout) throws SocketException{
- proxy.proxySocket.setSoTimeout(timeout);
- }
- /**
- Same as socket.
- */
- public int getSoTimeout(int timeout) throws SocketException{
- return proxy.proxySocket.getSoTimeout();
- }
- /**
- Same as socket.
- */
- public void setTcpNoDelay(boolean on) throws SocketException{
- proxy.proxySocket.setTcpNoDelay(on);
- }
- /**
- Same as socket.
- */
- public boolean getTcpNoDelay() throws SocketException{
- return proxy.proxySocket.getTcpNoDelay();
- }
-
- /**
- Get string representation of the socket.
- */
- public String toString(){
- if(directSock!=null) return "Direct connection:"+directSock;
- return ("Proxy:"+proxy+";"+"addr:"+remoteHost+",port:"+remotePort
- +",localport:"+localPort);
-
- }
-
-//Private Methods
-//////////////////
-
- private void doDirect()throws SocksException{
- try{
- //System.out.println("IP:"+remoteIP+":"+remotePort);
- directSock = new Socket(remoteIP,remotePort);
- proxy.out = directSock.getOutputStream();
- proxy.in = directSock.getInputStream();
- proxy.proxySocket = directSock;
- localIP = directSock.getLocalAddress();
- localPort = directSock.getLocalPort();
- }catch(IOException io_ex){
- throw new SocksException(Proxy.SOCKS_DIRECT_FAILED,
- "Direct connect failed:"+io_ex);
- }
- }
-
-}
diff --git a/app/src/main/java/net/sourceforge/jsocks/UDPEncapsulation.java b/app/src/main/java/net/sourceforge/jsocks/UDPEncapsulation.java
deleted file mode 100644
index e965942..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/UDPEncapsulation.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package net.sourceforge.jsocks;
-/**
- This interface provides for datagram encapsulation for SOCKSv5 protocol.
- <p>
- SOCKSv5 allows for datagrams to be encapsulated for purposes of integrity
- and/or authenticity. How it should be done is aggreed during the
- authentication stage, and is authentication dependent. This interface is
- provided to allow this encapsulation.
- @see Authentication
-*/
-public interface UDPEncapsulation{
-
- /**
- This method should provide any authentication depended transformation
- on datagrams being send from/to the client.
-
- @param data Datagram data (including any SOCKS related bytes), to be
- encapsulated/decapsulated.
- @param out Wether the data is being send out. If true method should
- encapsulate/encrypt data, otherwise it should decapsulate/
- decrypt data.
- @throw IOException if for some reason data can be transformed correctly.
- @return Should return byte array containing data after transformation.
- It is possible to return same array as input, if transformation
- only involves bit mangling, and no additional data is being
- added or removed.
- */
- byte[] udpEncapsulate(byte[] data, boolean out) throws java.io.IOException;
-}
diff --git a/app/src/main/java/net/sourceforge/jsocks/UDPRelayServer.java b/app/src/main/java/net/sourceforge/jsocks/UDPRelayServer.java
deleted file mode 100644
index dfa6016..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/UDPRelayServer.java
+++ /dev/null
@@ -1,212 +0,0 @@
-package net.sourceforge.jsocks;
-import net.sourceforge.jsocks.server.*;
-import java.net.*;
-import java.io.*;
-
-/**
- UDP Relay server, used by ProxyServer to perform udp forwarding.
-*/
-class UDPRelayServer implements Runnable{
-
-
- DatagramSocket client_sock;
- DatagramSocket remote_sock;
-
- Socket controlConnection;
-
- int relayPort;
- InetAddress relayIP;
-
- Thread pipe_thread1,pipe_thread2;
- Thread master_thread;
-
- ServerAuthenticator auth;
-
- long lastReadTime;
-
- static PrintStream log = null;
- static Proxy proxy = null;
- static int datagramSize = 0xFFFF;//64K, a bit more than max udp size
- static int iddleTimeout = 180000;//3 minutes
-
-
- /**
- Constructs UDP relay server to communicate with client
- on given ip and port.
- @param clientIP Address of the client from whom datagrams
- will be recieved and to whom they will be forwarded.
- @param clientPort Clients port.
- @param master_thread Thread which will be interrupted, when
- UDP relay server stoppes for some reason.
- @param controlConnection Socket which will be closed, before
- interrupting the master thread, it is introduced due to a bug
- in windows JVM which does not throw InterruptedIOException in
- threads which block in I/O operation.
- */
- public UDPRelayServer(InetAddress clientIP,int clientPort,
- Thread master_thread,
- Socket controlConnection,
- ServerAuthenticator auth)
- throws IOException{
- this.master_thread = master_thread;
- this.controlConnection = controlConnection;
- this.auth = auth;
-
- client_sock = new Socks5DatagramSocket(true,auth.getUdpEncapsulation(),
- clientIP,clientPort);
- relayPort = client_sock.getLocalPort();
- relayIP = client_sock.getLocalAddress();
-
- if(relayIP.getHostAddress().equals("0.0.0.0"))
- relayIP = InetAddress.getLocalHost();
-
- if(proxy == null)
- remote_sock = new DatagramSocket();
- else
- remote_sock = new Socks5DatagramSocket(proxy,0,null);
- }
-
-
-//Public methods
-/////////////////
-
-
- /**
- Sets the timeout for UDPRelay server.<br>
- Zero timeout implies infinity.<br>
- Default timeout is 3 minutes.
- */
-
- static public void setTimeout(int timeout){
- iddleTimeout = timeout;
- }
-
-
- /**
- Sets the size of the datagrams used in the UDPRelayServer.<br>
- Default size is 64K, a bit more than maximum possible size of the
- datagram.
- */
- static public void setDatagramSize(int size){
- datagramSize = size;
- }
-
- /**
- Port to which client should send datagram for association.
- */
- public int getRelayPort(){
- return relayPort;
- }
- /**
- IP address to which client should send datagrams for association.
- */
- public InetAddress getRelayIP(){
- return relayIP;
- }
-
- /**
- Starts udp relay server.
- Spawns two threads of execution and returns.
- */
- public void start() throws IOException{
- remote_sock.setSoTimeout(iddleTimeout);
- client_sock.setSoTimeout(iddleTimeout);
-
- log("Starting UDP relay server on "+relayIP+":"+relayPort);
- log("Remote socket "+remote_sock.getLocalAddress()+":"+
- remote_sock.getLocalPort());
-
- pipe_thread1 = new Thread(this,"pipe1");
- pipe_thread2 = new Thread(this,"pipe2");
-
- lastReadTime = System.currentTimeMillis();
-
- pipe_thread1.start();
- pipe_thread2.start();
- }
-
- /**
- Stops Relay server.
- <p>
- Does not close control connection, does not interrupt master_thread.
- */
- public synchronized void stop(){
- master_thread = null;
- controlConnection = null;
- abort();
- }
-
-//Runnable interface
-////////////////////
- public void run(){
- try{
- if(Thread.currentThread().getName().equals("pipe1"))
- pipe(remote_sock,client_sock,false);
- else
- pipe(client_sock,remote_sock,true);
- }catch(IOException ioe){
- }finally{
- abort();
- log("UDP Pipe thread "+Thread.currentThread().getName()+" stopped.");
- }
-
- }
-
-//Private methods
-/////////////////
- private synchronized void abort(){
- if(pipe_thread1 == null) return;
-
- log("Aborting UDP Relay Server");
-
- remote_sock.close();
- client_sock.close();
-
- if(controlConnection != null)
- try{ controlConnection.close();} catch(IOException ioe){}
-
- if(master_thread!=null) master_thread.interrupt();
-
- pipe_thread1.interrupt();
- pipe_thread2.interrupt();
-
- pipe_thread1 = null;
- }
-
-
- static private void log(String s){
- if(log != null){
- log.println(s);
- log.flush();
- }
- }
-
- private void pipe(DatagramSocket from,DatagramSocket to,boolean out)
- throws IOException{
- byte[] data = new byte[datagramSize];
- DatagramPacket dp = new DatagramPacket(data,data.length);
-
- while(true){
- try{
- from.receive(dp);
- lastReadTime = System.currentTimeMillis();
-
- if(auth.checkRequest(dp,out))
- to.send(dp);
-
- }catch(UnknownHostException uhe){
- log("Dropping datagram for unknown host");
- }catch(InterruptedIOException iioe){
- //log("Interrupted: "+iioe);
- //If we were interrupted by other thread.
- if(iddleTimeout == 0) return;
-
- //If last datagram was received, long time ago, return.
- long timeSinceRead = System.currentTimeMillis() - lastReadTime;
- if(timeSinceRead >= iddleTimeout -100) //-100 for adjustment
- return;
- }
- dp.setLength(data.length);
- }
- }
-}
diff --git a/app/src/main/java/net/sourceforge/jsocks/server/ServerAuthenticator.java b/app/src/main/java/net/sourceforge/jsocks/server/ServerAuthenticator.java
deleted file mode 100644
index cb7f0af..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/server/ServerAuthenticator.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package net.sourceforge.jsocks.server;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.DatagramPacket;
-import java.net.Socket;
-
-import net.sourceforge.jsocks.ProxyMessage;
-import net.sourceforge.jsocks.UDPEncapsulation;
-
-/**
- Classes implementing this interface should provide socks server with
- authentication and authorization of users.
-**/
-public interface ServerAuthenticator{
-
- /**
- This method is called when a new connection accepted by the server.
- <p>
- At this point no data have been extracted from the connection. It is
- responsibility of this method to ensure that the next byte in the
- stream after this method have been called is the first byte of the
- socks request message. For SOCKSv4 there is no authentication data and
- the first byte in the stream is part of the request. With SOCKSv5 however
- there is an authentication data first. It is expected that implementaions
- will process this authentication data.
- <p>
- If authentication was successful an instance of ServerAuthentication
- should be returned, it later will be used by the server to perform
- authorization and some other things. If authentication fails null should
- be returned, or an exception may be thrown.
-
- @param s Accepted Socket.
- @return An instance of ServerAuthenticator to be used for this connection
- or null
- */
- ServerAuthenticator startSession(Socket s) throws IOException;
-
- /**
- This method should return input stream which should be used on the
- accepted socket.
- <p>
- SOCKSv5 allows to have multiple authentication methods, and these methods
- might require some kind of transformations being made on the data.
- <p>
- This method is called on the object returned from the startSession
- function.
- */
- InputStream getInputStream();
- /**
- This method should return output stream to use to write to the accepted
- socket.
- <p>
- SOCKSv5 allows to have multiple authentication methods, and these methods
- might require some kind of transformations being made on the data.
- <p>
- This method is called on the object returned from the startSession
- function.
- */
- OutputStream getOutputStream();
-
- /**
- This method should return UDPEncapsulation, which should be used
- on the datagrams being send in/out.
- <p>
- If no transformation should be done on the datagrams, this method
- should return null.
- <p>
- This method is called on the object returned from the startSession
- function.
- */
-
- UDPEncapsulation getUdpEncapsulation();
-
- /**
- This method is called when a request have been read.
- <p>
- Implementation should decide wether to grant request or not. Returning
- true implies granting the request, false means request should be rejected.
- <p>
- This method is called on the object returned from the startSession
- function.
- @param msg Request message.
- @return true to grant request, false to reject it.
- */
- boolean checkRequest(ProxyMessage msg);
-
- /**
- This method is called when datagram is received by the server.
- <p>
- Implementaions should decide wether it should be forwarded or dropped.
- It is expecteed that implementation will use datagram address and port
- information to make a decision, as well as anything else. Address and
- port of the datagram are always correspond to remote machine. It is
- either destination or source address. If out is true address is destination
- address, else it is a source address, address of the machine from which
- datagram have been received for the client.
- <p>
- Implementaions should return true if the datagram is to be forwarded, and
- false if the datagram should be dropped.
- <p>
- This method is called on the object returned from the startSession
- function.
-
- @param out If true the datagram is being send out(from the client),
- otherwise it is an incoming datagram.
- @return True to forward datagram false drop it silently.
- */
- boolean checkRequest(DatagramPacket dp, boolean out);
-
- /**
- This method is called when session is completed. Either due to normal
- termination or due to any error condition.
- <p>
- This method is called on the object returned from the startSession
- function.
- */
- void endSession();
-}
diff --git a/app/src/main/java/net/sourceforge/jsocks/server/ServerAuthenticatorNone.java b/app/src/main/java/net/sourceforge/jsocks/server/ServerAuthenticatorNone.java
deleted file mode 100644
index e4edbe7..0000000
--- a/app/src/main/java/net/sourceforge/jsocks/server/ServerAuthenticatorNone.java
+++ /dev/null
@@ -1,169 +0,0 @@
-package net.sourceforge.jsocks.server;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PushbackInputStream;
-import java.net.Socket;
-
-import net.sourceforge.jsocks.ProxyMessage;
-import net.sourceforge.jsocks.UDPEncapsulation;
-
-/**
- An implementation of ServerAuthenticator, which does <b>not</b> do
- any authentication.
-<P>
-<FONT size="+3" color ="FF0000"> Warning!!</font><br> Should not be
-used on machines which are not behind the firewall.
-<p>
-It is only provided to make implementing other authentication schemes
-easier.<br>
-For Example: <tt><pre>
- class MyAuth extends socks.server.ServerAuthenticator{
- ...
- public ServerAuthenticator startSession(java.net.Socket s){
- if(!checkHost(s.getInetAddress()) return null;
- return super.startSession(s);
- }
-
- boolean checkHost(java.net.Inetaddress addr){
- boolean allow;
- //Do it somehow
- return allow;
- }
- }
-</pre></tt>
-*/
-public class ServerAuthenticatorNone implements ServerAuthenticator{
-
- static final byte[] socks5response = {5,0};
-
- InputStream in;
- OutputStream out;
-
- /**
- Creates new instance of the ServerAuthenticatorNone.
- */
- public ServerAuthenticatorNone(){
- this.in = null;
- this.out = null;
- }
- /**
- Constructs new ServerAuthenticatorNone object suitable for returning
- from the startSession function.
- @param in Input stream to return from getInputStream method.
- @param out Output stream to return from getOutputStream method.
- */
- public ServerAuthenticatorNone(InputStream in, OutputStream out){
- this.in = in;
- this.out = out;
- }
- /**
- Grants access to everyone.Removes authentication related bytes from
- the stream, when a SOCKS5 connection is being made, selects an
- authentication NONE.
- */
- public ServerAuthenticator startSession(Socket s)
- throws IOException{
-
- PushbackInputStream in = new PushbackInputStream(s.getInputStream());
- OutputStream out = s.getOutputStream();
-
- int version = in.read();
- if(version == 5){
- if(!selectSocks5Authentication(in,out,0))
- return null;
- }else if(version == 4){
- //Else it is the request message allready, version 4
- in.unread(version);
- }else
- return null;
-
-
- return new ServerAuthenticatorNone(in,out);
- }
-
- /**
- Get input stream.
- @return Input stream speciefied in the constructor.
- */
- public InputStream getInputStream(){
- return in;
- }
- /**
- Get output stream.
- @return Output stream speciefied in the constructor.
- */
- public OutputStream getOutputStream(){
- return out;
- }
- /**
- Allways returns null.
- @return null
- */
- public UDPEncapsulation getUdpEncapsulation(){
- return null;
- }
-
- /**
- Allways returns true.
- */
- public boolean checkRequest(ProxyMessage msg){
- return true;
- }
-
- /**
- Allways returns true.
- */
- public boolean checkRequest(java.net.DatagramPacket dp, boolean out){
- return true;
- }
-
- /**
- Does nothing.
- */
- public void endSession(){
- }
-
- /**
- Convinience routine for selecting SOCKSv5 authentication.
- <p>
- This method reads in authentication methods that client supports,
- checks wether it supports given method. If it does, the notification
- method is written back to client, that this method have been chosen
- for authentication. If given method was not found, authentication
- failure message is send to client ([5,FF]).
- @param in Input stream, version byte should be removed from the stream
- before calling this method.
- @param out Output stream.
- @param methodId Method which should be selected.
- @return true if methodId was found, false otherwise.
- */
- static public boolean selectSocks5Authentication(InputStream in,
- OutputStream out,
- int methodId)
- throws IOException{
-
- int num_methods = in.read();
- if (num_methods <= 0) return false;
- byte method_ids[] = new byte[num_methods];
- byte response[] = new byte[2];
- boolean found = false;
-
- response[0] = (byte) 5; //SOCKS version
- response[1] = (byte) 0xFF; //Not found, we are pessimistic
-
- int bread = 0; //bytes read so far
- while(bread < num_methods)
- bread += in.read(method_ids,bread,num_methods-bread);
-
- for(int i=0;i<num_methods;++i)
- if(method_ids[i] == methodId){
- found = true;
- response[1] = (byte) methodId;
- break;
- }
-
- out.write(response);
- return found;
- }
-}