Ubuntu

Merge lp:~veger/ubuntu/quantal/jsch/fix-for-803492-v2 into lp:ubuntu/quantal/jsch

Proposed by Maarten Bezemer on 2012-05-04
Status: Merged
Merge reported by: James Page
Merged at revision: not available
Proposed branch: lp:~veger/ubuntu/quantal/jsch/fix-for-803492-v2
Merge into: lp:ubuntu/quantal/jsch
Diff against target: 7636 lines (+2809/-994) 141 files modified
To merge this branch: bzr merge lp:~veger/ubuntu/quantal/jsch/fix-for-803492-v2
Reviewer Review Type Date Requested Status
James Page Approve on 2012-06-15
Ubuntu branches 2012-05-04 Pending
Review via email: mp+104706@code.launchpad.net

Description of the Change

Changes from 0.1.42 to 0.1.48 can be found at: http://www.jcraft.com/jsch/ChangeLog

To post a comment you must log in.
11. By Maarten Bezemer on 2012-05-04

Reverted removal (and refreshed) jsch-build-xml.patch as it still is required

James Page (james-page) wrote :

Hi Maarten

Thanks for preparing this update; I have two bits of feedback

1) The Merge proposal looks a little odd (removal of files in the .pc directory) because you have not applied all patched and added the .pc directory. This is a little counter intuitive but makes it easier to review

2) d/manifest.mf needed an update as well for the new version.

I've fixed both of these issues and uploaded - thanks for your contribution!

Cheers

James

review: Approve
James Page (james-page) wrote :

Oh - I missed this last point as well - you should really reference the bug report in the changelog entry with a (LP: #xxxxx) reference - that way the bug report gets closed as well.

I obviously still need more coffee...

Preview Diff

1=== removed directory '.pc'
2=== removed file '.pc/.version'
3--- .pc/.version 2010-06-27 23:17:34 +0000
4+++ .pc/.version 1970-01-01 00:00:00 +0000
5@@ -1,1 +0,0 @@
6-2
7
8=== removed file '.pc/applied-patches'
9--- .pc/applied-patches 2010-06-27 23:17:34 +0000
10+++ .pc/applied-patches 1970-01-01 00:00:00 +0000
11@@ -1,1 +0,0 @@
12-jsch-build-xml.patch
13
14=== removed directory '.pc/jsch-build-xml.patch'
15=== removed file '.pc/jsch-build-xml.patch/build.xml'
16--- .pc/jsch-build-xml.patch/build.xml 2010-06-27 23:17:34 +0000
17+++ .pc/jsch-build-xml.patch/build.xml 1970-01-01 00:00:00 +0000
18@@ -1,77 +0,0 @@
19-<project name="Jsch" default="dist" basedir=".">
20- <description>
21-JSch is a pure Java implementation of SSH2. JSch allows you to connect to an
22-sshd server and use port forwarding, X11 forwarding, file transfer, etc., and
23-you can integrate its functionality into your own Java programs
24- </description>
25- <!-- set global properties for this build -->
26- <property name="version" location="0.1.40"/>
27- <property name="src" location="src"/>
28- <property name="exasrc" location="examples"/>
29- <property name="build" location="build"/>
30- <property name="exabuild" location="examples"/>
31- <property name="dist" location="dist"/>
32- <property name="javadoc" location="javadoc"/>
33- <property name="javac.debug" value="true"/>
34- <path id="project.cp">
35- <pathelement location="${build}"/>
36- </path>
37- <target name="init">
38- <!-- Create the time stamp -->
39- <tstamp/>
40- <!-- Create the build directory structure used by compile -->
41- <mkdir dir="${build}"/>
42- </target>
43-
44- <target name="compile" depends="init"
45- description="compile the source " >
46- <!-- Compile the java code from ${src} into ${build} -->
47- <available property="jzlib.available"
48- classname="com.jcraft.jzlib.ZStream"/>
49- <javac srcdir="${src}" destdir="${build}" debug="${javac.debug}">
50- <exclude name="com/jcraft/jsch/jcraft/Compression.java"
51- unless="jzlib.available"/>
52- </javac>
53- </target>
54- <target name="run" depends="compile">
55- <java classname="Login" classpathref="project.cp"/>
56- </target>
57- <target name="dist" depends="compile"
58- description="generate the distribution" >
59- <!-- Create the distribution directory -->
60- <mkdir dir="${dist}/lib"/>
61-
62- <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
63- <jar jarfile="${dist}/lib/jsch-${DSTAMP}.jar" basedir="${build}"/>
64- </target>
65-
66- <target name="examples"
67- description="compiles the examples"
68- depends="compile">
69-
70- <path id="compile.classpath">
71- <pathelement location="${build}" />
72- </path>
73-
74- <javac srcdir="${exasrc}" destdir="${exabuild}">
75- <classpath refid="compile.classpath"/>
76- </javac>
77-
78- </target>
79-
80- <target name="clean"
81- description="clean up" >
82- <!-- Delete the ${build} and ${dist} directory trees -->
83- <delete dir="${build}"/>
84- <delete dir="${dist}"/>
85- <delete dir="${javadoc}"/>
86- </target>
87-
88- <target name="javadoc">
89- <javadoc sourcepath="${src}"
90- destdir="${javadoc}"
91- >
92- <packageset dir="${src}"/>
93- </javadoc>
94- </target>
95-</project>
96
97=== modified file 'ChangeLog'
98--- ChangeLog 2010-06-27 23:17:34 +0000
99+++ ChangeLog 2012-05-04 10:23:17 +0000
100@@ -1,6 +1,99 @@
101 ChangeLog of JSch
102 ====================================================================
103-Last modified: Tue Jul 14 02:29:29 UTC 2009
104+Last modified: Fri Apr 20 06:44:50 UTC 2012
105+
106+
107+Changes since version 0.1.47:
108+- change: the file transfer speed with ChannelSftp#get(String src) has been
109+ improved; sending multiple requests at any one time.
110+- change: by the default, at most, 16 requests will be sent at any one time
111+ in ChannelSftp.
112+- feature: added Session#{setIdentityRepository(),getIdentityRepository()}
113+
114+
115+Changes since version 0.1.46:
116+- bugfix: failed to initialize channels for the stream forwarding. FIXED
117+- change: Session#getHostKey() will return the given hostkey
118+ even if session is not established.
119+- change: Logger will record additional messages about algorithm negotiations.
120+- feature: added ChannelSftp#ls(String path, LsEntrySelector selector) method.
121+- feature: added IdentityRepository#{getName(),getStatus()} methods.
122+
123+
124+Changes since version 0.1.45:
125+- bugfix: in the agent forwarding mode, "ssh-add -l" on the remote
126+ will freeze. FIXED
127+- bugfix: requests should not be sent to the closed channel. FIXED
128+- bugfix: ChannelShell#setAgentForwarding(true) will cause
129+ resource leaks. FIXED
130+- change: for the efficiency, channel opening will be delayed
131+ in local port forwarding.
132+- change: added examples/Sudo.java to demonstrate sudo on exec channel.
133+- change: authentication trials will be failed at 6 failures by the default.
134+- change: updating copyright messages; 2011 -> 2012
135+- feature: added JSch#setIdentityRepository(IdentityRepository irepo) to
136+ integrate with jsch-agent-proxy.
137+
138+
139+Changes since version 0.1.44:
140+- bugfix: fields referred by multiple threads simultaneously should be
141+ volatile. FIXED
142+- bugfix: use local window size offered by the remote in sftp put.
143+ FIXED
144+- bugfix: SftpProgressMonitor#init was not invoked in sftp-put
145+ for input-stream. FIXED
146+- bugfix: sftp protocol version 3, 4 and 5 should allow only
147+ UTF-8 encoding. FIXED
148+- bugfix: Channel Subsystem had failed to set X forwarding flag.
149+ FIXED
150+- bugfix: Channel X11 had leaked some resources.
151+ FIXED
152+- bugfix: packet compression may break sessions
153+ in some case(transferring deflated data). FIXED
154+- bugfix: failed to set dev-null for logger
155+ FIXED
156+- bugfix: even in sftp protocol version 3 session, some sftpd sends data
157+ packets defined in sftp protocol 6 ;-( working around it. FIXED
158+- bugfix: ChannelSftp file globbing logic had missed
159+ the string "foo\\\*bar" as a pattern. FIXED
160+- bugfix: sequential accesses to ChannelSftp by multiple threads may
161+ break its I/O channel.
162+ https://bugs.eclipse.org/bugs/show_bug.cgi?id=359184 FIXED
163+- bugfix: KeyPair.load can not handle private keys cyphered with AES. FIXED
164+- change: to improve sftp-put performance, send multiple packet at one time.
165+- change: wait/notify will be used instead of sleep loop
166+ in establishing channel connections.
167+- change: increasing local window size for sftp get.
168+- change: updating copyright messages; 2010 -> 2011
169+- change: src/com -> src/main/java/com
170+- feature: key-exchange method "diffie-hellman-group14-sha1"
171+ (RFC4253#section-8.2)
172+- feature: KeyPair#getPlulicKeyCommment() is added.
173+
174+
175+Changes since version 0.1.43:
176+- bugfix: hmac-md5-96 and hmac-sha1-96 are broken. FIXED.
177+- bugfix: working around OOME in parsing broken data from the remote. FIXED.
178+- bugfix: failed to send very long command for exec channels. FIXED.
179+- bugfix: in some case, failed to get the response
180+ for remote port-forwarding request. FIXED.
181+- feature: support for private keys ciphered with aes192-cbc and aes128-cbc.
182+
183+
184+Changes since version 0.1.42:
185+- bugfix: the remote window size must be in unsigned int. FIXED.
186+- bugfix: support for EBCDIC environment. FIXED.
187+- bugfix: data may be written to the closed channel. FIXED.
188+- bugfix: NPE in closing channels. FIXED.
189+- bugfix: the private key file may include garbage data before its header. FIXED.
190+- bugfix: the session down may not be detected during the re-keying process. FIXED.
191+- change: try keyboard-interactive auth with the given password if UserInfo is not given.
192+- change: working around the wrong auth method list sent by some SSHD
193+ in the partial auth success.
194+- change: working around the CPNI-957037 Plain-text Recovery Attack.
195+- change: in searching for [host]:non-default port in known_hosts,
196+ host:22 should be also checked.
197+- change: updating copyright messages; 2009 -> 2010
198
199
200 Changes since version 0.1.41:
201
202=== modified file 'LICENSE.txt'
203--- LICENSE.txt 2010-06-27 23:17:34 +0000
204+++ LICENSE.txt 2012-05-04 10:23:17 +0000
205@@ -2,7 +2,7 @@
206 over to a BSD-style license.
207
208 ------------------------------------------------------------------------------
209-Copyright (c) 2002,2003,2004,2005,2006,2007,2008,2009 Atsuhiko Yamanaka, JCraft,Inc.
210+Copyright (c) 2002-2012 Atsuhiko Yamanaka, JCraft,Inc.
211 All rights reserved.
212
213 Redistribution and use in source and binary forms, with or without
214
215=== modified file 'build.xml'
216--- build.xml 2010-06-27 23:17:34 +0000
217+++ build.xml 2012-05-04 10:23:17 +0000
218@@ -5,14 +5,17 @@
219 you can integrate its functionality into your own Java programs
220 </description>
221 <!-- set global properties for this build -->
222- <property name="version" location="0.1.40"/>
223- <property name="src" location="src"/>
224+ <property name="version" value="0.1.48"/>
225+ <property name="src" location="src/main/java/"/>
226 <property name="exasrc" location="examples"/>
227 <property name="build" location="build"/>
228 <property name="exabuild" location="examples"/>
229 <property name="dist" location="dist"/>
230 <property name="javadoc" location="javadoc"/>
231 <property name="javac.debug" value="true"/>
232+ <path id="lib.path.ref">
233+ <fileset dir="lib" includes="*.jar"/>
234+ </path>
235 <path id="project.cp">
236 <pathelement location="${build}"/>
237 </path>
238@@ -27,22 +30,39 @@
239 description="compile the source " >
240 <!-- Compile the java code from ${src} into ${build} -->
241 <available property="jzlib.available"
242- classname="com.jcraft.jzlib.ZStream"/>
243- <javac srcdir="${src}" destdir="${build}" debug="${javac.debug}">
244+ classname="com.jcraft.jzlib.ZStream">
245+ <classpath refid="lib.path.ref"/>
246+ </available>
247+ <javac srcdir="${src}"
248+ destdir="${build}"
249+ target="1.4"
250+ source="1.4"
251+ debug="${javac.debug}">
252+ <classpath refid="lib.path.ref"/>
253 <exclude name="com/jcraft/jsch/jcraft/Compression.java"
254 unless="jzlib.available"/>
255 </javac>
256 </target>
257- <target name="run" depends="compile">
258- <java classname="Login" classpathref="project.cp"/>
259- </target>
260 <target name="dist" depends="compile"
261 description="generate the distribution" >
262 <!-- Create the distribution directory -->
263 <mkdir dir="${dist}/lib"/>
264
265- <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
266- <jar jarfile="${dist}/lib/jsch.jar" basedir="${build}" manifest="debian/manifest.mf" />
267+ <!-- Put everything in ${build} into the MyProject-${version}.jar file -->
268+ <jar jarfile="${dist}/lib/jsch-${version}.jar" basedir="${build}">
269+ <!--
270+ <manifest>
271+ <attribute name="Bundle-ClassPath" value="."/>
272+ <attribute name="Bundle-Vendor" value="JCraft, Inc."/>
273+ <attribute name="Bundle-Name" value="com.jcraft.jsch"/>
274+ <attribute name="Bundle-ManifestVersion" value="2"/>
275+ <attribute name="Bundle-SymbolicName" value="com.jcraft.jsch"/>
276+ <attribute name="Bundle-Version" value="${version}"/>
277+ <attribute name="Export-Package" value='com.jcraft.jsch;version="${version}",com.jcraft.jsch.jce;version="${version}";x-internal:=true,com.jcraft.jsch.jcraft;version="${version}";x-internal:=true,com.jcraft.jsch.jgss;version="${version}";x-internal:=true'/>
278+ <attribute name="Import-Package" value="javax.crypto,javax.crypto.spec,javax.crypto.interfaces,org.ietf.jgss,com.jcraft.jzlib"/>
279+ </manifest>
280+ -->
281+ </jar>
282 </target>
283
284 <target name="examples"
285
286=== modified file 'debian/changelog'
287--- debian/changelog 2010-06-27 23:17:34 +0000
288+++ debian/changelog 2012-05-04 10:23:17 +0000
289@@ -1,3 +1,12 @@
290+jsch (0.1.48-0ubuntu1) quantal; urgency=low
291+
292+ * New upstream release.
293+ - Updated debian/pom.xml
294+ - Refreshed jsch-build-xml.patch
295+ * Bumped Standards-Version to 3.9.3 - no changes required.
296+
297+ -- Maarten Bezemer <maarten.bezemer@gmail.com> Fri, 04 May 2012 10:39:23 +0200
298+
299 jsch (0.1.42-2fakesync1) maverick; urgency=low
300
301 * Fake sync due to mismatching orig tarball.
302
303=== modified file 'debian/control'
304--- debian/control 2010-06-27 23:17:34 +0000
305+++ debian/control 2012-05-04 10:23:17 +0000
306@@ -8,7 +8,7 @@
307 Niels Thykier <niels@thykier.net>
308 Build-Depends: debhelper (>= 7), cdbs, default-jdk
309 Build-Depends-Indep: maven-repo-helper, ant (>= 1.6.5)
310-Standards-Version: 3.8.4
311+Standards-Version: 3.9.3
312 Vcs-Svn: svn://svn.debian.org/svn/pkg-java/trunk/jsch
313 Vcs-Browser: http://svn.debian.org/wsvn/pkg-java/trunk/jsch
314 Homepage: http://www.jcraft.com/jsch/
315
316=== modified file 'debian/patches/jsch-build-xml.patch'
317--- debian/patches/jsch-build-xml.patch 2010-06-27 23:17:34 +0000
318+++ debian/patches/jsch-build-xml.patch 2012-05-04 10:23:17 +0000
319@@ -7,9 +7,9 @@
320 @@ -42,7 +42,7 @@
321 <mkdir dir="${dist}/lib"/>
322
323- <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
324-- <jar jarfile="${dist}/lib/jsch-${DSTAMP}.jar" basedir="${build}"/>
325-+ <jar jarfile="${dist}/lib/jsch.jar" basedir="${build}" manifest="debian/manifest.mf" />
326- </target>
327-
328- <target name="examples"
329+ <!-- Put everything in ${build} into the MyProject-${version}.jar file -->
330+- <jar jarfile="${dist}/lib/jsch-${version}.jar" basedir="${build}">
331++ <jar jarfile="${dist}/lib/jsch.jar" basedir="${build}" manifest="debian/manifest.mf">
332+ <!--
333+ <manifest>
334+ <attribute name="Bundle-ClassPath" value="."/>
335
336=== modified file 'debian/pom.xml'
337--- debian/pom.xml 2009-09-22 20:01:52 +0000
338+++ debian/pom.xml 2012-05-04 10:23:17 +0000
339@@ -6,7 +6,7 @@
340 <modelVersion>4.0.0</modelVersion>
341 <groupId>com.jcraft</groupId>
342 <artifactId>jsch</artifactId>
343- <version>0.1.42</version>
344+ <version>0.1.48</version>
345 <name>JSch</name>
346
347 <description>JSch is a pure Java implementation of SSH2</description>
348
349=== removed directory 'dist'
350=== removed directory 'dist/lib'
351=== modified file 'examples/AES.java'
352--- examples/AES.java 2008-02-06 23:23:19 +0000
353+++ examples/AES.java 2012-05-04 10:23:17 +0000
354@@ -1,4 +1,8 @@
355 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
356+/**
357+ * This program will demonstrate how to use "aes128-cbc".
358+ *
359+ */
360 import com.jcraft.jsch.*;
361 import java.awt.*;
362 import javax.swing.*;
363
364=== modified file 'examples/ChangePassphrase.java'
365--- examples/ChangePassphrase.java 2007-09-09 20:32:32 +0000
366+++ examples/ChangePassphrase.java 2012-05-04 10:23:17 +0000
367@@ -1,4 +1,15 @@
368 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
369+/**
370+ * This program will demonstrate to change the passphrase for a
371+ * private key file instead of creating a new private key.
372+ * $ CLASSPATH=.:../build javac ChangePassphrase.java
373+ * $ CLASSPATH=.:../build java ChangePassphrase private-key
374+ * A passphrase will be prompted if the given private-key has been
375+ * encrypted. After successfully loading the content of the
376+ * private-key, the new passphrase will be prompted and the given
377+ * private-key will be re-encrypted with that new passphrase.
378+ *
379+ */
380 import com.jcraft.jsch.*;
381 import javax.swing.*;
382
383
384=== modified file 'examples/Compression.java'
385--- examples/Compression.java 2008-02-06 23:23:19 +0000
386+++ examples/Compression.java 2012-05-04 10:23:17 +0000
387@@ -1,4 +1,13 @@
388 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
389+/**
390+ * This program will demonstrate the packet compression.
391+ * $ CLASSPATH=.:../build javac Compression.java
392+ * $ CLASSPATH=.:../build java Compression
393+ * You will be asked username, hostname and passwd.
394+ * If everything works fine, you will get the shell prompt.
395+ * In this program, all data from sshd server to jsch will be compressed.
396+ *
397+ */
398 import com.jcraft.jsch.*;
399 import java.awt.*;
400 import javax.swing.*;
401
402=== modified file 'examples/Daemon.java'
403--- examples/Daemon.java 2008-02-06 23:23:19 +0000
404+++ examples/Daemon.java 2012-05-04 10:23:17 +0000
405@@ -1,4 +1,9 @@
406 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
407+/**
408+ * This program will demonstrate how to provide a network service like
409+ * inetd by using remote port-forwarding functionality.
410+ *
411+ */
412 import com.jcraft.jsch.*;
413 import java.io.*;
414 import java.awt.*;
415@@ -58,10 +63,10 @@
416 }
417 public void setArg(Object[] arg){this.arg=arg;}
418 public void run(){
419- System.out.println("remote port: "+channel.getRemotePort());
420- System.out.println("remote host: "+channel.getSession().getHost());
421 try{
422 byte[] buf=new byte[1024];
423+ System.out.println("remote port: "+channel.getRemotePort());
424+ System.out.println("remote host: "+channel.getSession().getHost());
425 while(true){
426 int i=in.read(buf, 0, buf.length);
427 if(i<=0)break;
428@@ -70,6 +75,9 @@
429 if(buf[0]=='.')break;
430 }
431 }
432+ catch(JSchException e){
433+ System.out.println("session is down.");
434+ }
435 catch(IOException e){
436 }
437 }
438
439=== modified file 'examples/Exec.java'
440--- examples/Exec.java 2008-02-06 23:23:19 +0000
441+++ examples/Exec.java 2012-05-04 10:23:17 +0000
442@@ -1,4 +1,13 @@
443 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
444+/**
445+ * This program will demonstrate remote exec.
446+ * $ CLASSPATH=.:../build javac Exec.java
447+ * $ CLASSPATH=.:../build java Exec
448+ * You will be asked username, hostname, displayname, passwd and command.
449+ * If everything works fine, given command will be invoked
450+ * on the remote side and outputs will be printed out.
451+ *
452+ */
453 import com.jcraft.jsch.*;
454 import java.awt.*;
455 import javax.swing.*;
456
457=== modified file 'examples/KeyGen.java'
458--- examples/KeyGen.java 2007-09-09 20:32:32 +0000
459+++ examples/KeyGen.java 2012-05-04 10:23:17 +0000
460@@ -1,4 +1,16 @@
461 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
462+/**
463+ * This progam will demonstrate the DSA keypair generation.
464+ * $ CLASSPATH=.:../build javac KeyGen.java
465+ * $ CLASSPATH=.:../build java KeyGen rsa output_keyfile comment
466+ * or
467+ * $ CLASSPATH=.:../build java KeyGen dsa output_keyfile comment
468+ * You will be asked a passphrase for output_keyfile.
469+ * If everything works fine, you will get the DSA or RSA keypair,
470+ * output_keyfile and output_keyfile+".pub".
471+ * The private key and public key are in the OpenSSH format.
472+ *
473+ */
474 import com.jcraft.jsch.*;
475 import javax.swing.*;
476
477
478=== modified file 'examples/KnownHosts.java'
479--- examples/KnownHosts.java 2008-02-06 23:23:19 +0000
480+++ examples/KnownHosts.java 2012-05-04 10:23:17 +0000
481@@ -1,4 +1,14 @@
482 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
483+/**
484+ * This program will demonstrate the 'known_hosts' file handling.
485+ * $ CLASSPATH=.:../build javac KnownHosts.java
486+ * $ CLASSPATH=.:../build java KnownHosts
487+ * You will be asked username, hostname, a path for 'known_hosts' and passwd.
488+ * If everything works fine, you will get the shell prompt.
489+ * In current implementation, jsch only reads 'known_hosts' for checking
490+ * and does not modify it.
491+ *
492+ */
493 import com.jcraft.jsch.*;
494 import java.awt.*;
495 import javax.swing.*;
496
497=== modified file 'examples/Logger.java'
498--- examples/Logger.java 2008-02-06 23:23:19 +0000
499+++ examples/Logger.java 2012-05-04 10:23:17 +0000
500@@ -1,4 +1,8 @@
501 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
502+/**
503+ * This program will demonstrate how to enable logging mechanism and
504+ * get logging messages.
505+ */
506 import com.jcraft.jsch.*;
507 import java.awt.*;
508 import javax.swing.*;
509
510=== modified file 'examples/PortForwardingL.java'
511--- examples/PortForwardingL.java 2008-02-06 23:23:19 +0000
512+++ examples/PortForwardingL.java 2012-05-04 10:23:17 +0000
513@@ -1,4 +1,15 @@
514 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
515+/**
516+ * This program will demonstrate the port forwarding like option -L of
517+ * ssh command; the given port on the local host will be forwarded to
518+ * the given remote host and port on the remote side.
519+ * $ CLASSPATH=.:../build javac PortForwardingL.java
520+ * $ CLASSPATH=.:../build java PortForwardingL
521+ * You will be asked username, hostname, port:host:hostport and passwd.
522+ * If everything works fine, you will get the shell prompt.
523+ * Try the port on localhost.
524+ *
525+ */
526 import com.jcraft.jsch.*;
527 import java.awt.*;
528 import javax.swing.*;
529
530=== modified file 'examples/PortForwardingR.java'
531--- examples/PortForwardingR.java 2008-02-06 23:23:19 +0000
532+++ examples/PortForwardingR.java 2012-05-04 10:23:17 +0000
533@@ -1,4 +1,15 @@
534 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
535+/**
536+ * This program will demonstrate the port forwarding like option -R of
537+ * ssh command; the given port on the remote host will be forwarded to
538+ * the given host and port on the local side.
539+ * $ CLASSPATH=.:../build javac PortForwardingR.java
540+ * $ CLASSPATH=.:../build java PortForwardingR
541+ * You will be asked username, hostname, port:host:hostport and passwd.
542+ * If everything works fine, you will get the shell prompt.
543+ * Try the port on remote host.
544+ *
545+ */
546 import com.jcraft.jsch.*;
547 import java.awt.*;
548 import javax.swing.*;
549
550=== modified file 'examples/README'
551--- examples/README 2007-09-09 20:32:32 +0000
552+++ examples/README 2012-05-04 10:23:17 +0000
553@@ -38,6 +38,13 @@
554 You will be asked username, hostname, proxy-server and passwd.
555 If everything works fine, you will get the shell prompt.
556
557+- ViaSOCKS.java
558+ This program will demonstrate the ssh session via SOCKS proxy.
559+ $ CLASSPATH=.:../build javac ViaSOCKS.java
560+ $ CLASSPATH=.:../build java ViaSOCKS
561+ You will be asked username, hostname, proxy-server and passwd.
562+ If everything works fine, you will get the shell prompt.
563+
564 - PortForwardingR.java
565 This program will demonstrate the port forwarding like option -R of
566 ssh command; the given port on the remote host will be forwarded to
567@@ -158,3 +165,12 @@
568 - Logger.java
569 This program will demonstrate how to enable logging mechanism and
570 get logging messages.
571+
572+- Subsystem.java
573+ This program will demonstrate how to use the Subsystem channel.
574+
575+- Sudo.java
576+ This program will demonstrate how to exec 'sudo' on the remote.
577+
578+- ScpToNoneCipher.java
579+ This program will demonstrate how to enable none cipher.
580
581=== modified file 'examples/ScpFrom.java'
582--- examples/ScpFrom.java 2007-09-09 20:32:32 +0000
583+++ examples/ScpFrom.java 2012-05-04 10:23:17 +0000
584@@ -1,4 +1,13 @@
585 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
586+/**
587+ * This program will demonstrate the file transfer from remote to local
588+ * $ CLASSPATH=.:../build javac ScpFrom.java
589+ * $ CLASSPATH=.:../build java ScpFrom user@remotehost:file1 file2
590+ * You will be asked passwd.
591+ * If everything works fine, a file 'file1' on 'remotehost' will copied to
592+ * local 'file1'.
593+ *
594+ */
595 import com.jcraft.jsch.*;
596 import java.awt.*;
597 import javax.swing.*;
598
599=== modified file 'examples/ScpTo.java'
600--- examples/ScpTo.java 2007-09-09 20:32:32 +0000
601+++ examples/ScpTo.java 2012-05-04 10:23:17 +0000
602@@ -1,4 +1,13 @@
603 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
604+/**
605+ * This program will demonstrate the file transfer from local to remote.
606+ * $ CLASSPATH=.:../build javac ScpTo.java
607+ * $ CLASSPATH=.:../build java ScpTo file1 user@remotehost:file2
608+ * You will be asked passwd.
609+ * If everything works fine, a local file 'file1' will copied to
610+ * 'file2' on 'remotehost'.
611+ *
612+ */
613 import com.jcraft.jsch.*;
614 import java.awt.*;
615 import javax.swing.*;
616@@ -28,9 +37,10 @@
617 session.setUserInfo(ui);
618 session.connect();
619
620+ boolean ptimestamp = true;
621
622 // exec 'scp -t rfile' remotely
623- String command="scp -p -t "+rfile;
624+ String command="scp " + (ptimestamp ? "-p" :"") +" -t "+rfile;
625 Channel channel=session.openChannel("exec");
626 ((ChannelExec)channel).setCommand(command);
627
628@@ -44,8 +54,21 @@
629 System.exit(0);
630 }
631
632+ File _lfile = new File(lfile);
633+
634+ if(ptimestamp){
635+ command="T "+(_lfile.lastModified()/1000)+" 0";
636+ // The access time should be sent here,
637+ // but it is not accessible with JavaAPI ;-<
638+ command+=(" "+(_lfile.lastModified()/1000)+" 0\n");
639+ out.write(command.getBytes()); out.flush();
640+ if(checkAck(in)!=0){
641+ System.exit(0);
642+ }
643+ }
644+
645 // send "C0644 filesize filename", where filename should not include '/'
646- long filesize=(new File(lfile)).length();
647+ long filesize=_lfile.length();
648 command="C0644 "+filesize+" ";
649 if(lfile.lastIndexOf('/')>0){
650 command+=lfile.substring(lfile.lastIndexOf('/')+1);
651
652=== modified file 'examples/ScpToNoneCipher.java'
653--- examples/ScpToNoneCipher.java 2007-09-09 20:32:32 +0000
654+++ examples/ScpToNoneCipher.java 2012-05-04 10:23:17 +0000
655@@ -1,4 +1,8 @@
656 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
657+/**
658+ * This program will demonstrate how to enable none cipher.
659+ *
660+ */
661 import com.jcraft.jsch.*;
662 import java.awt.*;
663 import javax.swing.*;
664
665=== modified file 'examples/Sftp.java'
666--- examples/Sftp.java 2009-10-19 15:08:16 +0000
667+++ examples/Sftp.java 2012-05-04 10:23:17 +0000
668@@ -1,4 +1,15 @@
669 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
670+/**
671+ * This program will demonstrate the sftp protocol support.
672+ * $ CLASSPATH=.:../build javac Sftp.java
673+ * $ CLASSPATH=.:../build java Sftp
674+ * You will be asked username, host and passwd.
675+ * If everything works fine, you will get a prompt 'sftp>'.
676+ * 'help' command will show available command.
677+ * In current implementation, the destination path for 'get' and 'put'
678+ * commands must be a file, not a directory.
679+ *
680+ */
681 import com.jcraft.jsch.*;
682 import java.awt.*;
683 import javax.swing.*;
684
685=== modified file 'examples/Shell.java'
686--- examples/Shell.java 2009-10-19 15:08:16 +0000
687+++ examples/Shell.java 2012-05-04 10:23:17 +0000
688@@ -1,4 +1,13 @@
689 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
690+/**
691+ * This program enables you to connect to sshd server and get the shell prompt.
692+ * $ CLASSPATH=.:../build javac Shell.java
693+ * $ CLASSPATH=.:../build java Shell
694+ * You will be asked username, hostname and passwd.
695+ * If everything works fine, you will get the shell prompt. Output will
696+ * be ugly because of lacks of terminal-emulation, but you can issue commands.
697+ *
698+ */
699 import com.jcraft.jsch.*;
700 import java.awt.*;
701 import javax.swing.*;
702@@ -25,12 +34,36 @@
703
704 Session session=jsch.getSession(user, host, 22);
705
706- //session.setPassword("your password");
707-
708- // username and password will be given via UserInfo interface.
709- UserInfo ui=new MyUserInfo();
710+ String passwd = JOptionPane.showInputDialog("Enter password");
711+ session.setPassword(passwd);
712+
713+ UserInfo ui = new MyUserInfo(){
714+ public void showMessage(String message){
715+ JOptionPane.showMessageDialog(null, message);
716+ }
717+ public boolean promptYesNo(String message){
718+ Object[] options={ "yes", "no" };
719+ int foo=JOptionPane.showOptionDialog(null,
720+ message,
721+ "Warning",
722+ JOptionPane.DEFAULT_OPTION,
723+ JOptionPane.WARNING_MESSAGE,
724+ null, options, options[0]);
725+ return foo==0;
726+ }
727+
728+ // If password is not given before the invocation of Session#connect(),
729+ // implement also following methods,
730+ // * UserInfo#getPassword(),
731+ // * UserInfo#promptPassword(String message) and
732+ // * UIKeyboardInteractive#promptKeyboardInteractive()
733+
734+ };
735+
736 session.setUserInfo(ui);
737
738+ // It must not be recommended, but if you want to skip host-key check,
739+ // invoke following,
740 // session.setConfig("StrictHostKeyChecking", "no");
741
742 //session.connect();
743@@ -71,97 +104,20 @@
744 }
745 }
746
747- public static class MyUserInfo implements UserInfo, UIKeyboardInteractive{
748- public String getPassword(){ return passwd; }
749- public boolean promptYesNo(String str){
750- Object[] options={ "yes", "no" };
751- int foo=JOptionPane.showOptionDialog(null,
752- str,
753- "Warning",
754- JOptionPane.DEFAULT_OPTION,
755- JOptionPane.WARNING_MESSAGE,
756- null, options, options[0]);
757- return foo==0;
758- }
759-
760- String passwd;
761- JTextField passwordField=(JTextField)new JPasswordField(20);
762-
763+ public static abstract class MyUserInfo
764+ implements UserInfo, UIKeyboardInteractive{
765+ public String getPassword(){ return null; }
766+ public boolean promptYesNo(String str){ return false; }
767 public String getPassphrase(){ return null; }
768- public boolean promptPassphrase(String message){ return true; }
769- public boolean promptPassword(String message){
770- Object[] ob={passwordField};
771- int result=JOptionPane.showConfirmDialog(null, ob, message,
772- JOptionPane.OK_CANCEL_OPTION);
773- if(result==JOptionPane.OK_OPTION){
774- passwd=passwordField.getText();
775- return true;
776- }
777- else{
778- return false;
779- }
780- }
781- public void showMessage(String message){
782- JOptionPane.showMessageDialog(null, message);
783- }
784- final GridBagConstraints gbc =
785- new GridBagConstraints(0,0,1,1,1,1,
786- GridBagConstraints.NORTHWEST,
787- GridBagConstraints.NONE,
788- new Insets(0,0,0,0),0,0);
789- private Container panel;
790+ public boolean promptPassphrase(String message){ return false; }
791+ public boolean promptPassword(String message){ return false; }
792+ public void showMessage(String message){ }
793 public String[] promptKeyboardInteractive(String destination,
794 String name,
795 String instruction,
796 String[] prompt,
797 boolean[] echo){
798- panel = new JPanel();
799- panel.setLayout(new GridBagLayout());
800-
801- gbc.weightx = 1.0;
802- gbc.gridwidth = GridBagConstraints.REMAINDER;
803- gbc.gridx = 0;
804- panel.add(new JLabel(instruction), gbc);
805- gbc.gridy++;
806-
807- gbc.gridwidth = GridBagConstraints.RELATIVE;
808-
809- JTextField[] texts=new JTextField[prompt.length];
810- for(int i=0; i<prompt.length; i++){
811- gbc.fill = GridBagConstraints.NONE;
812- gbc.gridx = 0;
813- gbc.weightx = 1;
814- panel.add(new JLabel(prompt[i]),gbc);
815-
816- gbc.gridx = 1;
817- gbc.fill = GridBagConstraints.HORIZONTAL;
818- gbc.weighty = 1;
819- if(echo[i]){
820- texts[i]=new JTextField(20);
821- }
822- else{
823- texts[i]=new JPasswordField(20);
824- }
825- panel.add(texts[i], gbc);
826- gbc.gridy++;
827- }
828-
829- if(JOptionPane.showConfirmDialog(null, panel,
830- destination+": "+name,
831- JOptionPane.OK_CANCEL_OPTION,
832- JOptionPane.QUESTION_MESSAGE)
833- ==JOptionPane.OK_OPTION){
834- String[] response=new String[prompt.length];
835- for(int i=0; i<prompt.length; i++){
836- response[i]=texts[i].getText();
837- }
838- return response;
839- }
840- else{
841- return null; // cancel
842- }
843+ return null;
844 }
845 }
846 }
847-
848-
849
850=== modified file 'examples/StreamForwarding.java'
851--- examples/StreamForwarding.java 2008-02-06 23:23:19 +0000
852+++ examples/StreamForwarding.java 2012-05-04 10:23:17 +0000
853@@ -1,4 +1,16 @@
854 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
855+/**
856+ * This program will demonstrate the stream forwarding. The given Java
857+ * I/O streams will be forwared to the given remote host and port on
858+ * the remote side. It is simmilar to the -L option of ssh command,
859+ * but you don't have to assign and open a local tcp port.
860+ * $ CLASSPATH=.:../build javac StreamForwarding.java
861+ * $ CLASSPATH=.:../build java StreamForwarding
862+ * You will be asked username, hostname, host:hostport and passwd.
863+ * If everything works fine, System.in and System.out streams will be
864+ * forwared to remote port and you can send messages from command line.
865+ *
866+ */
867 import com.jcraft.jsch.*;
868 import java.awt.*;
869 import javax.swing.*;
870
871=== modified file 'examples/Subsystem.java'
872--- examples/Subsystem.java 2008-02-06 23:23:19 +0000
873+++ examples/Subsystem.java 2012-05-04 10:23:17 +0000
874@@ -1,4 +1,8 @@
875 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
876+/**
877+ * This program will demonstrate how to use the Subsystem channel.
878+ *
879+ */
880 import com.jcraft.jsch.*;
881 import java.awt.*;
882 import javax.swing.*;
883
884=== added file 'examples/Sudo.java'
885--- examples/Sudo.java 1970-01-01 00:00:00 +0000
886+++ examples/Sudo.java 2012-05-04 10:23:17 +0000
887@@ -0,0 +1,184 @@
888+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
889+/**
890+ * This program will demonstrate how to exec 'sudo' on the remote.
891+ *
892+ */
893+import com.jcraft.jsch.*;
894+import java.awt.*;
895+import javax.swing.*;
896+import java.io.*;
897+
898+public class Sudo{
899+ public static void main(String[] arg){
900+ try{
901+ JSch jsch=new JSch();
902+
903+ String host=null;
904+ if(arg.length>0){
905+ host=arg[0];
906+ }
907+ else{
908+ host=JOptionPane.showInputDialog("Enter username@hostname",
909+ System.getProperty("user.name")+
910+ "@localhost");
911+ }
912+ String user=host.substring(0, host.indexOf('@'));
913+ host=host.substring(host.indexOf('@')+1);
914+
915+ Session session=jsch.getSession(user, host, 22);
916+
917+ UserInfo ui=new MyUserInfo();
918+ session.setUserInfo(ui);
919+ session.connect();
920+
921+ String command=JOptionPane.showInputDialog("Enter command, execed with sudo",
922+ "printenv SUDO_USER");
923+
924+ String sudo_pass=null;
925+ {
926+ JTextField passwordField=(JTextField)new JPasswordField(8);
927+ Object[] ob={passwordField};
928+ int result=
929+ JOptionPane.showConfirmDialog(null,
930+ ob,
931+ "Enter password for sudo",
932+ JOptionPane.OK_CANCEL_OPTION);
933+ if(result!=JOptionPane.OK_OPTION){
934+ System.exit(-1);
935+ }
936+ sudo_pass=passwordField.getText();
937+ }
938+
939+ Channel channel=session.openChannel("exec");
940+
941+ // man sudo
942+ // -S The -S (stdin) option causes sudo to read the password from the
943+ // standard input instead of the terminal device.
944+ // -p The -p (prompt) option allows you to override the default
945+ // password prompt and use a custom one.
946+ ((ChannelExec)channel).setCommand("sudo -S -p '' "+command);
947+
948+
949+ InputStream in=channel.getInputStream();
950+ OutputStream out=channel.getOutputStream();
951+ ((ChannelExec)channel).setErrStream(System.err);
952+
953+ channel.connect();
954+
955+ out.write((sudo_pass+"\n").getBytes());
956+ out.flush();
957+
958+ byte[] tmp=new byte[1024];
959+ while(true){
960+ while(in.available()>0){
961+ int i=in.read(tmp, 0, 1024);
962+ if(i<0)break;
963+ System.out.print(new String(tmp, 0, i));
964+ }
965+ if(channel.isClosed()){
966+ System.out.println("exit-status: "+channel.getExitStatus());
967+ break;
968+ }
969+ try{Thread.sleep(1000);}catch(Exception ee){}
970+ }
971+ channel.disconnect();
972+ session.disconnect();
973+ }
974+ catch(Exception e){
975+ System.out.println(e);
976+ }
977+ }
978+
979+ public static class MyUserInfo implements UserInfo, UIKeyboardInteractive{
980+ public String getPassword(){ return passwd; }
981+ public boolean promptYesNo(String str){
982+ Object[] options={ "yes", "no" };
983+ int foo=JOptionPane.showOptionDialog(null,
984+ str,
985+ "Warning",
986+ JOptionPane.DEFAULT_OPTION,
987+ JOptionPane.WARNING_MESSAGE,
988+ null, options, options[0]);
989+ return foo==0;
990+ }
991+
992+ String passwd;
993+ JTextField passwordField=(JTextField)new JPasswordField(20);
994+
995+ public String getPassphrase(){ return null; }
996+ public boolean promptPassphrase(String message){ return true; }
997+ public boolean promptPassword(String message){
998+ Object[] ob={passwordField};
999+ int result=
1000+ JOptionPane.showConfirmDialog(null, ob, message,
1001+ JOptionPane.OK_CANCEL_OPTION);
1002+ if(result==JOptionPane.OK_OPTION){
1003+ passwd=passwordField.getText();
1004+ return true;
1005+ }
1006+ else{
1007+ return false;
1008+ }
1009+ }
1010+ public void showMessage(String message){
1011+ JOptionPane.showMessageDialog(null, message);
1012+ }
1013+ final GridBagConstraints gbc =
1014+ new GridBagConstraints(0,0,1,1,1,1,
1015+ GridBagConstraints.NORTHWEST,
1016+ GridBagConstraints.NONE,
1017+ new Insets(0,0,0,0),0,0);
1018+ private Container panel;
1019+ public String[] promptKeyboardInteractive(String destination,
1020+ String name,
1021+ String instruction,
1022+ String[] prompt,
1023+ boolean[] echo){
1024+ panel = new JPanel();
1025+ panel.setLayout(new GridBagLayout());
1026+
1027+ gbc.weightx = 1.0;
1028+ gbc.gridwidth = GridBagConstraints.REMAINDER;
1029+ gbc.gridx = 0;
1030+ panel.add(new JLabel(instruction), gbc);
1031+ gbc.gridy++;
1032+
1033+ gbc.gridwidth = GridBagConstraints.RELATIVE;
1034+
1035+ JTextField[] texts=new JTextField[prompt.length];
1036+ for(int i=0; i<prompt.length; i++){
1037+ gbc.fill = GridBagConstraints.NONE;
1038+ gbc.gridx = 0;
1039+ gbc.weightx = 1;
1040+ panel.add(new JLabel(prompt[i]),gbc);
1041+
1042+ gbc.gridx = 1;
1043+ gbc.fill = GridBagConstraints.HORIZONTAL;
1044+ gbc.weighty = 1;
1045+ if(echo[i]){
1046+ texts[i]=new JTextField(20);
1047+ }
1048+ else{
1049+ texts[i]=new JPasswordField(20);
1050+ }
1051+ panel.add(texts[i], gbc);
1052+ gbc.gridy++;
1053+ }
1054+
1055+ if(JOptionPane.showConfirmDialog(null, panel,
1056+ destination+": "+name,
1057+ JOptionPane.OK_CANCEL_OPTION,
1058+ JOptionPane.QUESTION_MESSAGE)
1059+ ==JOptionPane.OK_OPTION){
1060+ String[] response=new String[prompt.length];
1061+ for(int i=0; i<prompt.length; i++){
1062+ response[i]=texts[i].getText();
1063+ }
1064+ return response;
1065+ }
1066+ else{
1067+ return null; // cancel
1068+ }
1069+ }
1070+ }
1071+}
1072
1073=== modified file 'examples/UserAuthKI.java'
1074--- examples/UserAuthKI.java 2008-02-06 23:23:19 +0000
1075+++ examples/UserAuthKI.java 2012-05-04 10:23:17 +0000
1076@@ -1,4 +1,12 @@
1077 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
1078+/**
1079+ * This program will demonstrate the keyboard-interactive authentication.
1080+ * $ CLASSPATH=.:../build javac UserAuthKI.java
1081+ * $ CLASSPATH=.:../build java UserAuthKI
1082+ * If the remote sshd supports keyboard-interactive authentication,
1083+ * you will be prompted.
1084+ *
1085+ */
1086 import com.jcraft.jsch.*;
1087 import java.awt.*;
1088 import javax.swing.*;
1089
1090=== modified file 'examples/UserAuthPubKey.java'
1091--- examples/UserAuthPubKey.java 2008-02-06 23:23:19 +0000
1092+++ examples/UserAuthPubKey.java 2012-05-04 10:23:17 +0000
1093@@ -1,4 +1,12 @@
1094 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
1095+/**
1096+ * This program will demonstrate the user authentification by public key.
1097+ * $ CLASSPATH=.:../build javac UserAuthPubKey.java
1098+ * $ CLASSPATH=.:../build java UserAuthPubKey
1099+ * You will be asked username, hostname, privatekey(id_dsa) and passphrase.
1100+ * If everything works fine, you will get the shell prompt
1101+ *
1102+ */
1103 import com.jcraft.jsch.*;
1104 import java.awt.*;
1105 import javax.swing.*;
1106
1107=== modified file 'examples/ViaHTTP.java'
1108--- examples/ViaHTTP.java 2008-02-06 23:23:19 +0000
1109+++ examples/ViaHTTP.java 2012-05-04 10:23:17 +0000
1110@@ -1,4 +1,12 @@
1111 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
1112+/**
1113+ * This program will demonstrate the ssh session via HTTP proxy.
1114+ * $ CLASSPATH=.:../build javac ViaHTTP.java
1115+ * $ CLASSPATH=.:../build java ViaHTTP
1116+ * You will be asked username, hostname, proxy-server and passwd.
1117+ * If everything works fine, you will get the shell prompt.
1118+ *
1119+ */
1120 import com.jcraft.jsch.*;
1121 import java.awt.*;
1122 import javax.swing.*;
1123
1124=== modified file 'examples/ViaSOCKS5.java'
1125--- examples/ViaSOCKS5.java 2008-02-06 23:23:19 +0000
1126+++ examples/ViaSOCKS5.java 2012-05-04 10:23:17 +0000
1127@@ -1,4 +1,12 @@
1128 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
1129+/**
1130+ * This program will demonstrate the ssh session via SOCKS proxy.
1131+ * $ CLASSPATH=.:../build javac ViaSOCKS.java
1132+ * $ CLASSPATH=.:../build java ViaSOCKS
1133+ * You will be asked username, hostname, proxy-server and passwd.
1134+ * If everything works fine, you will get the shell prompt.
1135+ *
1136+ */
1137 import com.jcraft.jsch.*;
1138 import java.awt.*;
1139 import javax.swing.*;
1140
1141=== modified file 'examples/X11Forwarding.java'
1142--- examples/X11Forwarding.java 2008-02-06 23:23:19 +0000
1143+++ examples/X11Forwarding.java 2012-05-04 10:23:17 +0000
1144@@ -1,4 +1,14 @@
1145 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
1146+/**
1147+ * This program will demonstrate X11 forwarding.
1148+ * $ CLASSPATH=.:../build javac X11Forwarding.java
1149+ * $ CLASSPATH=.:../build java X11Forwarding
1150+ * You will be asked username, hostname, displayname and passwd.
1151+ * If your X server does not run at 127.0.0.1, please enter correct
1152+ * displayname. If everything works fine, you will get the shell prompt.
1153+ * Try X applications; for example, xlogo.
1154+ *
1155+ */
1156 import com.jcraft.jsch.*;
1157 import java.awt.*;
1158 import javax.swing.*;
1159
1160=== added directory 'lib'
1161=== added directory 'src/main'
1162=== added directory 'src/main/java'
1163=== renamed directory 'src/com' => 'src/main/java/com'
1164=== modified file 'src/main/java/com/jcraft/jsch/Buffer.java'
1165--- src/com/jcraft/jsch/Buffer.java 2010-06-27 23:17:34 +0000
1166+++ src/main/java/com/jcraft/jsch/Buffer.java 2012-05-04 10:23:17 +0000
1167@@ -1,6 +1,6 @@
1168 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
1169 /*
1170-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
1171+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
1172
1173 Redistribution and use in source and binary forms, with or without
1174 modification, are permitted provided that the following conditions are met:
1175@@ -123,6 +123,16 @@
1176 foo = ((foo<<16)&0xffff0000) | (getShort()&0xffff);
1177 return foo;
1178 }
1179+ public long getUInt(){
1180+ long foo = 0L;
1181+ long bar = 0L;
1182+ foo = getByte();
1183+ foo = ((foo<<8)&0xff00)|(getByte()&0xff);
1184+ bar = getByte();
1185+ bar = ((bar<<8)&0xff00)|(getByte()&0xff);
1186+ foo = ((foo<<16)&0xffff0000) | (bar&0xffff);
1187+ return foo;
1188+ }
1189 int getShort() {
1190 int foo = getByte();
1191 foo = ((foo<<8)&0xff00)|(getByte()&0xff);
1192@@ -144,7 +154,12 @@
1193 return foo;
1194 }
1195 public byte[] getMPInt() {
1196- int i=getInt();
1197+ int i=getInt(); // uint32
1198+ if(i<0 || // bigger than 0x7fffffff
1199+ i>8*1024){
1200+ // TODO: an exception should be thrown.
1201+ i = 8*1024; // the session will be broken, but working around OOME.
1202+ }
1203 byte[] foo=new byte[i];
1204 getByte(foo, 0, i);
1205 return foo;
1206@@ -163,7 +178,12 @@
1207 return foo;
1208 }
1209 public byte[] getString() {
1210- int i=getInt();
1211+ int i = getInt(); // uint32
1212+ if(i<0 || // bigger than 0x7fffffff
1213+ i>256*1024){
1214+ // TODO: an exception should be thrown.
1215+ i = 256*1024; // the session will be broken, but working around OOME.
1216+ }
1217 byte[] foo=new byte[i];
1218 getByte(foo, 0, i);
1219 return foo;
1220@@ -192,6 +212,14 @@
1221 return buffer[5];
1222 }
1223
1224+ void checkFreeSize(int n){
1225+ if(buffer.length<index+n){
1226+ byte[] tmp = new byte[buffer.length*2];
1227+ System.arraycopy(buffer, 0, tmp, 0, index);
1228+ buffer = tmp;
1229+ }
1230+ }
1231+
1232 /*
1233 static String[] chars={
1234 "0","1","2","3","4","5","6","7","8","9", "a","b","c","d","e","f"
1235
1236=== modified file 'src/main/java/com/jcraft/jsch/Channel.java'
1237--- src/com/jcraft/jsch/Channel.java 2010-06-27 23:17:34 +0000
1238+++ src/main/java/com/jcraft/jsch/Channel.java 2012-05-04 10:23:17 +0000
1239@@ -1,6 +1,6 @@
1240 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
1241 /*
1242-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
1243+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
1244
1245 Redistribution and use in source and binary forms, with or without
1246 modification, are permitted provided that the following conditions are met:
1247@@ -95,30 +95,29 @@
1248 }
1249
1250 int id;
1251- int recipient=-1;
1252- byte[] type="foo".getBytes();
1253- int lwsize_max=0x100000;
1254-//int lwsize_max=0x20000; // 32*1024*4
1255- int lwsize=lwsize_max; // local initial window size
1256- int lmpsize=0x4000; // local maximum packet size
1257-//int lmpsize=0x8000; // local maximum packet size
1258+ volatile int recipient=-1;
1259+ protected byte[] type=Util.str2byte("foo");
1260+ volatile int lwsize_max=0x100000;
1261+ volatile int lwsize=lwsize_max; // local initial window size
1262+ volatile int lmpsize=0x4000; // local maximum packet size
1263
1264- int rwsize=0; // remote initial window size
1265- int rmpsize=0; // remote maximum packet size
1266+ volatile long rwsize=0; // remote initial window size
1267+ volatile int rmpsize=0; // remote maximum packet size
1268
1269 IO io=null;
1270 Thread thread=null;
1271
1272- boolean eof_local=false;
1273- boolean eof_remote=false;
1274-
1275- boolean close=false;
1276- boolean connected=false;
1277-
1278- int exitstatus=-1;
1279-
1280- int reply=0;
1281- int connectTimeout=0;
1282+ volatile boolean eof_local=false;
1283+ volatile boolean eof_remote=false;
1284+
1285+ volatile boolean close=false;
1286+ volatile boolean connected=false;
1287+ volatile boolean open_confirmation=false;
1288+
1289+ volatile int exitstatus=-1;
1290+
1291+ volatile int reply=0;
1292+ volatile int connectTimeout=0;
1293
1294 private Session session;
1295
1296@@ -130,8 +129,10 @@
1297 pool.addElement(this);
1298 }
1299 }
1300- void setRecipient(int foo){
1301+ synchronized void setRecipient(int foo){
1302 this.recipient=foo;
1303+ if(notifyme>0)
1304+ notifyAll();
1305 }
1306 int getRecipient(){
1307 return recipient;
1308@@ -145,62 +146,14 @@
1309 }
1310
1311 public void connect(int connectTimeout) throws JSchException{
1312- Session _session=getSession();
1313- if(!_session.isConnected()){
1314- throw new JSchException("session is down");
1315- }
1316 this.connectTimeout=connectTimeout;
1317 try{
1318- Buffer buf=new Buffer(100);
1319- Packet packet=new Packet(buf);
1320- // send
1321- // byte SSH_MSG_CHANNEL_OPEN(90)
1322- // string channel type //
1323- // uint32 sender channel // 0
1324- // uint32 initial window size // 0x100000(65536)
1325- // uint32 maxmum packet size // 0x4000(16384)
1326- packet.reset();
1327- buf.putByte((byte)90);
1328- buf.putString(this.type);
1329- buf.putInt(this.id);
1330- buf.putInt(this.lwsize);
1331- buf.putInt(this.lmpsize);
1332- _session.write(packet);
1333- int retry=1000;
1334- long start=System.currentTimeMillis();
1335- long timeout=connectTimeout;
1336- while(this.getRecipient()==-1 &&
1337- _session.isConnected() &&
1338- retry>0){
1339- if(timeout>0L){
1340- if((System.currentTimeMillis()-start)>timeout){
1341- retry=0;
1342- continue;
1343- }
1344- }
1345- try{Thread.sleep(50);}catch(Exception ee){}
1346- retry--;
1347- }
1348- if(!_session.isConnected()){
1349- throw new JSchException("session is down");
1350- }
1351- if(retry==0){
1352- throw new JSchException("channel is not opened.");
1353- }
1354-
1355- /*
1356- * At the failure in opening the channel on the sshd,
1357- * 'SSH_MSG_CHANNEL_OPEN_FAILURE' will be sent from sshd and it will
1358- * be processed in Session#run().
1359- */
1360- if(this.isClosed()){
1361- throw new JSchException("channel is not opened.");
1362- }
1363- connected=true;
1364+ sendChannelOpen();
1365 start();
1366 }
1367 catch(Exception e){
1368 connected=false;
1369+ disconnect();
1370 if(e instanceof JSchException)
1371 throw (JSchException)e;
1372 throw new JSchException(e.toString(), e);
1373@@ -216,7 +169,7 @@
1374
1375 void getData(Buffer buf){
1376 setRecipient(buf.getInt());
1377- setRemoteWindowSize(buf.getInt());
1378+ setRemoteWindowSize(buf.getUInt());
1379 setRemotePacketSize(buf.getInt());
1380 }
1381
1382@@ -274,7 +227,7 @@
1383 packet=new Packet(buffer);
1384
1385 byte[] _buf=buffer.buffer;
1386- if(_buf.length-(14+0)-32-20<=0){
1387+ if(_buf.length-(14+0)-Session.buffer_margin<=0){
1388 buffer=null;
1389 packet=null;
1390 throw new IOException("failed to initialize the channel.");
1391@@ -299,8 +252,8 @@
1392 int _bufl=_buf.length;
1393 while(l>0){
1394 int _l=l;
1395- if(l>_bufl-(14+dataLen)-32-20){
1396- _l=_bufl-(14+dataLen)-32-20;
1397+ if(l>_bufl-(14+dataLen)-Session.buffer_margin){
1398+ _l=_bufl-(14+dataLen)-Session.buffer_margin;
1399 }
1400
1401 if(_l<=0){
1402@@ -329,7 +282,10 @@
1403 try{
1404 int foo=dataLen;
1405 dataLen=0;
1406- getSession().write(packet, channel, foo);
1407+ synchronized(channel){
1408+ if(!channel.close)
1409+ getSession().write(packet, channel, foo);
1410+ }
1411 }
1412 catch(Exception e){
1413 close();
1414@@ -371,11 +327,27 @@
1415 super(out);
1416 buffer=new byte[size];
1417 }
1418+
1419+ /*
1420+ * TODO: We should have our own Piped[I/O]Stream implementation.
1421+ * Before accepting data, JDK's PipedInputStream will check the existence of
1422+ * reader thread, and if it is not alive, the stream will be closed.
1423+ * That behavior may cause the problem if multiple threads make access to it.
1424+ */
1425+ public synchronized void updateReadSide() throws IOException {
1426+ if(available() != 0){ // not empty
1427+ return;
1428+ }
1429+ in = 0;
1430+ out = 0;
1431+ buffer[in++] = 0;
1432+ read();
1433+ }
1434 }
1435 void setLocalWindowSizeMax(int foo){ this.lwsize_max=foo; }
1436 void setLocalWindowSize(int foo){ this.lwsize=foo; }
1437 void setLocalPacketSize(int foo){ this.lmpsize=foo; }
1438- synchronized void setRemoteWindowSize(int foo){ this.rwsize=foo; }
1439+ synchronized void setRemoteWindowSize(long foo){ this.rwsize=foo; }
1440 synchronized void addRemoteWindowSize(int foo){
1441 this.rwsize+=foo;
1442 if(notifyme>0)
1443@@ -409,18 +381,19 @@
1444 }
1445
1446 void eof(){
1447- //System.err.println("EOF!!!! "+this);
1448- if(close)return;
1449 if(eof_local)return;
1450 eof_local=true;
1451- //close=eof;
1452+
1453 try{
1454 Buffer buf=new Buffer(100);
1455 Packet packet=new Packet(buf);
1456 packet.reset();
1457 buf.putByte((byte)Session.SSH_MSG_CHANNEL_EOF);
1458 buf.putInt(getRecipient());
1459- getSession().write(packet);
1460+ synchronized(this){
1461+ if(!close)
1462+ getSession().write(packet);
1463+ }
1464 }
1465 catch(Exception e){
1466 //System.err.println("Channel.eof");
1467@@ -468,10 +441,8 @@
1468 */
1469
1470 void close(){
1471- //System.err.println("close!!!!");
1472 if(close)return;
1473 close=true;
1474-
1475 eof_local=eof_remote=true;
1476
1477 try{
1478@@ -480,7 +451,9 @@
1479 packet.reset();
1480 buf.putByte((byte)Session.SSH_MSG_CHANNEL_CLOSE);
1481 buf.putInt(getRecipient());
1482- getSession().write(packet);
1483+ synchronized(this){
1484+ getSession().write(packet);
1485+ }
1486 }
1487 catch(Exception e){
1488 //e.printStackTrace();
1489@@ -514,14 +487,15 @@
1490 //System.err.println(this+":disconnect "+io+" "+connected);
1491 //Thread.dumpStack();
1492
1493- synchronized(this){
1494- if(!connected){
1495- return;
1496+ try{
1497+
1498+ synchronized(this){
1499+ if(!connected){
1500+ return;
1501+ }
1502+ connected=false;
1503 }
1504- connected=false;
1505- }
1506
1507- try{
1508 close();
1509
1510 eof_remote=eof_local=true;
1511@@ -628,11 +602,76 @@
1512 buf.putByte((byte)SSH_MSG_CHANNEL_OPEN_FAILURE);
1513 buf.putInt(getRecipient());
1514 buf.putInt(reasoncode);
1515- buf.putString("open failed".getBytes());
1516- buf.putString("".getBytes());
1517+ buf.putString(Util.str2byte("open failed"));
1518+ buf.putString(Util.empty);
1519 getSession().write(packet);
1520 }
1521 catch(Exception e){
1522 }
1523 }
1524+
1525+ protected Packet genChannelOpenPacket(){
1526+ Buffer buf=new Buffer(100);
1527+ Packet packet=new Packet(buf);
1528+ // byte SSH_MSG_CHANNEL_OPEN(90)
1529+ // string channel type //
1530+ // uint32 sender channel // 0
1531+ // uint32 initial window size // 0x100000(65536)
1532+ // uint32 maxmum packet size // 0x4000(16384)
1533+ packet.reset();
1534+ buf.putByte((byte)90);
1535+ buf.putString(this.type);
1536+ buf.putInt(this.id);
1537+ buf.putInt(this.lwsize);
1538+ buf.putInt(this.lmpsize);
1539+ return packet;
1540+ }
1541+
1542+ protected void sendChannelOpen() throws Exception {
1543+ Session _session=getSession();
1544+ if(!_session.isConnected()){
1545+ throw new JSchException("session is down");
1546+ }
1547+
1548+ Packet packet = genChannelOpenPacket();
1549+ _session.write(packet);
1550+
1551+ int retry=10;
1552+ long start=System.currentTimeMillis();
1553+ long timeout=connectTimeout;
1554+ if(timeout!=0L) retry = 1;
1555+ synchronized(this){
1556+ while(this.getRecipient()==-1 &&
1557+ _session.isConnected() &&
1558+ retry>0){
1559+ if(timeout>0L){
1560+ if((System.currentTimeMillis()-start)>timeout){
1561+ retry=0;
1562+ continue;
1563+ }
1564+ }
1565+ try{
1566+ long t = timeout==0L ? 5000L : timeout;
1567+ this.notifyme=1;
1568+ wait(t);
1569+ }
1570+ catch(java.lang.InterruptedException e){
1571+ }
1572+ finally{
1573+ this.notifyme=0;
1574+ }
1575+ retry--;
1576+ }
1577+ }
1578+ if(!_session.isConnected()){
1579+ throw new JSchException("session is down");
1580+ }
1581+ if(this.getRecipient()==-1){ // timeout
1582+ throw new JSchException("channel is not opened.");
1583+ }
1584+ if(this.open_confirmation==false){ // SSH_MSG_CHANNEL_OPEN_FAILURE
1585+ throw new JSchException("channel is not opened.");
1586+ }
1587+ connected=true;
1588+ }
1589 }
1590
1591=== modified file 'src/main/java/com/jcraft/jsch/ChannelAgentForwarding.java'
1592--- src/com/jcraft/jsch/ChannelAgentForwarding.java 2010-06-27 23:17:34 +0000
1593+++ src/main/java/com/jcraft/jsch/ChannelAgentForwarding.java 2012-05-04 10:23:17 +0000
1594@@ -1,6 +1,6 @@
1595 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
1596 /*
1597-Copyright (c) 2006-2009 ymnk, JCraft,Inc. All rights reserved.
1598+Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved.
1599
1600 Redistribution and use in source and binary forms, with or without
1601 modification, are permitted provided that the following conditions are met:
1602@@ -37,14 +37,24 @@
1603 static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
1604 static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
1605
1606- private final int SSH2_AGENTC_REQUEST_IDENTITIES=11;
1607- private final int SSH2_AGENT_IDENTITIES_ANSWER=12;
1608- private final int SSH2_AGENTC_SIGN_REQUEST=13;
1609- private final int SSH2_AGENT_SIGN_RESPONSE=14;
1610- private final int SSH2_AGENTC_ADD_IDENTITY=17;
1611- private final int SSH2_AGENTC_REMOVE_IDENTITY=18;
1612- private final int SSH2_AGENTC_REMOVE_ALL_IDENTITIES=19;
1613- private final int SSH2_AGENT_FAILURE=30;
1614+ private final byte SSH_AGENTC_REQUEST_RSA_IDENTITIES = 1;
1615+ private final byte SSH_AGENT_RSA_IDENTITIES_ANSWER = 2;
1616+ private final byte SSH_AGENTC_RSA_CHALLENGE = 3;
1617+ private final byte SSH_AGENT_RSA_RESPONSE = 4;
1618+ private final byte SSH_AGENT_FAILURE = 5;
1619+ private final byte SSH_AGENT_SUCCESS = 6;
1620+ private final byte SSH_AGENTC_ADD_RSA_IDENTITY = 7;
1621+ private final byte SSH_AGENTC_REMOVE_RSA_IDENTITY = 8;
1622+ private final byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9;
1623+
1624+ private final byte SSH2_AGENTC_REQUEST_IDENTITIES=11;
1625+ private final byte SSH2_AGENT_IDENTITIES_ANSWER=12;
1626+ private final byte SSH2_AGENTC_SIGN_REQUEST=13;
1627+ private final byte SSH2_AGENT_SIGN_RESPONSE=14;
1628+ private final byte SSH2_AGENTC_ADD_IDENTITY=17;
1629+ private final byte SSH2_AGENTC_REMOVE_IDENTITY=18;
1630+ private final byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES=19;
1631+ private final byte SSH2_AGENT_FAILURE=30;
1632
1633 boolean init=true;
1634
1635@@ -60,7 +70,7 @@
1636 setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
1637 setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
1638
1639- type="auth-agent@openssh.com".getBytes();
1640+ type=Util.str2byte("auth-agent@openssh.com");
1641 rbuf=new Buffer();
1642 rbuf.reset();
1643 //wbuf=new Buffer(rmpsize);
1644@@ -111,12 +121,14 @@
1645 throw new java.io.IOException(e.toString());
1646 }
1647
1648- Vector identities=_session.jsch.identities;
1649+ IdentityRepository irepo = _session.getIdentityRepository();
1650 UserInfo userinfo=_session.getUserInfo();
1651
1652+ mbuf.reset();
1653+
1654 if(typ==SSH2_AGENTC_REQUEST_IDENTITIES){
1655- mbuf.reset();
1656- mbuf.putByte((byte)SSH2_AGENT_IDENTITIES_ANSWER);
1657+ mbuf.putByte(SSH2_AGENT_IDENTITIES_ANSWER);
1658+ Vector identities = irepo.getIdentities();
1659 synchronized(identities){
1660 int count=0;
1661 for(int i=0; i<identities.size(); i++){
1662@@ -131,13 +143,13 @@
1663 if(pubkeyblob==null)
1664 continue;
1665 mbuf.putString(pubkeyblob);
1666- mbuf.putString("".getBytes());
1667+ mbuf.putString(Util.empty);
1668 }
1669 }
1670- byte[] bar=new byte[mbuf.getLength()];
1671- mbuf.getByte(bar);
1672-
1673- send(bar);
1674+ }
1675+ else if(typ==SSH_AGENTC_REQUEST_RSA_IDENTITIES) {
1676+ mbuf.putByte(SSH_AGENT_RSA_IDENTITIES_ANSWER);
1677+ mbuf.putInt(0);
1678 }
1679 else if(typ==SSH2_AGENTC_SIGN_REQUEST){
1680 byte[] blob=rbuf.getString();
1681@@ -148,7 +160,8 @@
1682 // datafellows = SSH_BUG_SIGBLOB;
1683 // }
1684
1685- Identity identity=null;
1686+ Vector identities = irepo.getIdentities();
1687+ Identity identity = null;
1688 synchronized(identities){
1689 for(int i=0; i<identities.size(); i++){
1690 Identity _identity=(Identity)(identities.elementAt(i));
1691@@ -195,20 +208,41 @@
1692 signature=identity.getSignature(data);
1693 }
1694
1695- mbuf.reset();
1696 if(signature==null){
1697- mbuf.putByte((byte)SSH2_AGENT_FAILURE);
1698+ mbuf.putByte(SSH2_AGENT_FAILURE);
1699 }
1700 else{
1701- mbuf.putByte((byte)SSH2_AGENT_SIGN_RESPONSE);
1702+ mbuf.putByte(SSH2_AGENT_SIGN_RESPONSE);
1703 mbuf.putString(signature);
1704 }
1705-
1706- byte[] bar=new byte[mbuf.getLength()];
1707- mbuf.getByte(bar);
1708-
1709- send(bar);
1710- }
1711+ }
1712+ else if(typ==SSH2_AGENTC_REMOVE_IDENTITY){
1713+ byte[] blob=rbuf.getString();
1714+ irepo.remove(blob);
1715+ mbuf.putByte(SSH_AGENT_SUCCESS);
1716+ }
1717+ else if(typ==SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES){
1718+ mbuf.putByte(SSH_AGENT_SUCCESS);
1719+ }
1720+ else if(typ==SSH2_AGENTC_REMOVE_ALL_IDENTITIES){
1721+ irepo.removeAll();
1722+ mbuf.putByte(SSH_AGENT_SUCCESS);
1723+ }
1724+ else if(typ==SSH2_AGENTC_ADD_IDENTITY){
1725+ int fooo = rbuf.getLength();
1726+ byte[] tmp = new byte[fooo];
1727+ rbuf.getByte(tmp);
1728+ boolean result = irepo.add(tmp);
1729+ mbuf.putByte(result ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
1730+ }
1731+ else {
1732+ rbuf.skip(rbuf.getLength()-1);
1733+ mbuf.putByte(SSH_AGENT_FAILURE);
1734+ }
1735+
1736+ byte[] response = new byte[mbuf.getLength()];
1737+ mbuf.getByte(response);
1738+ send(response);
1739 }
1740
1741 private void send(byte[] message){
1742@@ -224,4 +258,9 @@
1743 catch(Exception e){
1744 }
1745 }
1746+
1747+ void eof_remote(){
1748+ super.eof_remote();
1749+ eof();
1750+ }
1751 }
1752
1753=== modified file 'src/main/java/com/jcraft/jsch/ChannelDirectTCPIP.java'
1754--- src/com/jcraft/jsch/ChannelDirectTCPIP.java 2010-06-27 23:17:34 +0000
1755+++ src/main/java/com/jcraft/jsch/ChannelDirectTCPIP.java 2012-05-04 10:23:17 +0000
1756@@ -1,6 +1,6 @@
1757 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
1758 /*
1759-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
1760+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
1761
1762 Redistribution and use in source and binary forms, with or without
1763 modification, are permitted provided that the following conditions are met:
1764@@ -35,7 +35,7 @@
1765
1766 static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
1767 static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
1768-
1769+ static private final byte[] _type = Util.str2byte("direct-tcpip");
1770 String host;
1771 int port;
1772
1773@@ -44,18 +44,14 @@
1774
1775 ChannelDirectTCPIP(){
1776 super();
1777+ type = _type;
1778 setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
1779 setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
1780 setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
1781 }
1782
1783 void init (){
1784- try{
1785- io=new IO();
1786- }
1787- catch(Exception e){
1788- System.err.println(e);
1789- }
1790+ io=new IO();
1791 }
1792
1793 public void connect() throws JSchException{
1794@@ -64,54 +60,6 @@
1795 if(!_session.isConnected()){
1796 throw new JSchException("session is down");
1797 }
1798- Buffer buf=new Buffer(150);
1799- Packet packet=new Packet(buf);
1800- // send
1801- // byte SSH_MSG_CHANNEL_OPEN(90)
1802- // string channel type //
1803- // uint32 sender channel // 0
1804- // uint32 initial window size // 0x100000(65536)
1805- // uint32 maxmum packet size // 0x4000(16384)
1806-
1807- packet.reset();
1808- buf.putByte((byte)90);
1809- buf.putString("direct-tcpip".getBytes());
1810- buf.putInt(id);
1811- buf.putInt(lwsize);
1812- buf.putInt(lmpsize);
1813- buf.putString(host.getBytes());
1814- buf.putInt(port);
1815- buf.putString(originator_IP_address.getBytes());
1816- buf.putInt(originator_port);
1817- _session.write(packet);
1818-
1819- int retry=1000;
1820- try{
1821- while(this.getRecipient()==-1 &&
1822- _session.isConnected() &&
1823- retry>0 &&
1824- !eof_remote){
1825- //Thread.sleep(500);
1826- Thread.sleep(50);
1827- retry--;
1828- }
1829- }
1830- catch(Exception ee){
1831- }
1832- if(!_session.isConnected()){
1833- throw new JSchException("session is down");
1834- }
1835- if(retry==0 || this.eof_remote){
1836- throw new JSchException("channel is not opened.");
1837- }
1838- /*
1839- if(this.eof_remote){ // failed to open
1840- disconnect();
1841- return;
1842- }
1843- */
1844-
1845- connected=true;
1846
1847 if(io.in!=null){
1848 thread=new Thread(this);
1849@@ -121,6 +69,9 @@
1850 }
1851 thread.start();
1852 }
1853+ else {
1854+ sendChannelOpen();
1855+ }
1856 }
1857 catch(Exception e){
1858 io.close();
1859@@ -134,12 +85,14 @@
1860
1861 public void run(){
1862
1863- Buffer buf=new Buffer(rmpsize);
1864- Packet packet=new Packet(buf);
1865- int i=0;
1866-
1867 try{
1868+ sendChannelOpen();
1869+
1870+ Buffer buf=new Buffer(rmpsize);
1871+ Packet packet=new Packet(buf);
1872 Session _session=getSession();
1873+ int i=0;
1874+
1875 while(isConnected() &&
1876 thread!=null &&
1877 io!=null &&
1878@@ -147,26 +100,27 @@
1879 i=io.in.read(buf.buffer,
1880 14,
1881 buf.buffer.length-14
1882- -32 -20 // padding and mac
1883+ -Session.buffer_margin
1884 );
1885-
1886 if(i<=0){
1887 eof();
1888 break;
1889 }
1890- if(close)break;
1891 packet.reset();
1892 buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
1893 buf.putInt(recipient);
1894 buf.putInt(i);
1895 buf.skip(i);
1896- _session.write(packet, this, i);
1897+ synchronized(this){
1898+ if(close)
1899+ break;
1900+ _session.write(packet, this, i);
1901+ }
1902 }
1903 }
1904 catch(Exception e){
1905 }
1906 disconnect();
1907- //System.err.println("connect end");
1908 }
1909
1910 public void setInputStream(InputStream in){
1911@@ -180,4 +134,25 @@
1912 public void setPort(int port){this.port=port;}
1913 public void setOrgIPAddress(String foo){this.originator_IP_address=foo;}
1914 public void setOrgPort(int foo){this.originator_port=foo;}
1915+
1916+ protected Packet genChannelOpenPacket(){
1917+ Buffer buf = new Buffer(150);
1918+ Packet packet = new Packet(buf);
1919+ // byte SSH_MSG_CHANNEL_OPEN(90)
1920+ // string channel type //
1921+ // uint32 sender channel // 0
1922+ // uint32 initial window size // 0x100000(65536)
1923+ // uint32 maxmum packet size // 0x4000(16384)
1924+ packet.reset();
1925+ buf.putByte((byte)90);
1926+ buf.putString(this.type);
1927+ buf.putInt(id);
1928+ buf.putInt(lwsize);
1929+ buf.putInt(lmpsize);
1930+ buf.putString(Util.str2byte(host));
1931+ buf.putInt(port);
1932+ buf.putString(Util.str2byte(originator_IP_address));
1933+ buf.putInt(originator_port);
1934+ return packet;
1935+ }
1936 }
1937
1938=== modified file 'src/main/java/com/jcraft/jsch/ChannelExec.java'
1939--- src/com/jcraft/jsch/ChannelExec.java 2010-06-27 23:17:34 +0000
1940+++ src/main/java/com/jcraft/jsch/ChannelExec.java 2012-05-04 10:23:17 +0000
1941@@ -1,6 +1,6 @@
1942 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
1943 /*
1944-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
1945+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
1946
1947 Redistribution and use in source and binary forms, with or without
1948 modification, are permitted provided that the following conditions are met:
1949@@ -60,7 +60,7 @@
1950 }
1951
1952 public void setCommand(String command){
1953- this.command=command.getBytes();
1954+ this.command=Util.str2byte(command);
1955 }
1956 public void setCommand(byte[] command){
1957 this.command=command;
1958
1959=== modified file 'src/main/java/com/jcraft/jsch/ChannelForwardedTCPIP.java'
1960--- src/com/jcraft/jsch/ChannelForwardedTCPIP.java 2010-06-27 23:17:34 +0000
1961+++ src/main/java/com/jcraft/jsch/ChannelForwardedTCPIP.java 2012-05-04 10:23:17 +0000
1962@@ -1,6 +1,6 @@
1963 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
1964 /*
1965-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
1966+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
1967
1968 Redistribution and use in source and binary forms, with or without
1969 modification, are permitted provided that the following conditions are met:
1970@@ -97,25 +97,29 @@
1971 Packet packet=new Packet(buf);
1972 int i=0;
1973 try{
1974+ Session _session = getSession();
1975 while(thread!=null &&
1976 io!=null &&
1977 io.in!=null){
1978 i=io.in.read(buf.buffer,
1979 14,
1980 buf.buffer.length-14
1981- -32 -20 // padding and mac
1982+ -Session.buffer_margin
1983 );
1984 if(i<=0){
1985 eof();
1986 break;
1987 }
1988 packet.reset();
1989- if(close)break;
1990 buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
1991 buf.putInt(recipient);
1992 buf.putInt(i);
1993 buf.skip(i);
1994- getSession().write(packet, this, i);
1995+ synchronized(this){
1996+ if(close)
1997+ break;
1998+ _session.write(packet, this, i);
1999+ }
2000 }
2001 }
2002 catch(Exception e){
2003@@ -128,7 +132,7 @@
2004
2005 void getData(Buffer buf){
2006 setRecipient(buf.getInt());
2007- setRemoteWindowSize(buf.getInt());
2008+ setRemoteWindowSize(buf.getUInt());
2009 setRemotePacketSize(buf.getInt());
2010 byte[] addr=buf.getString();
2011 int port=buf.getInt();
2012@@ -136,9 +140,9 @@
2013 int orgport=buf.getInt();
2014
2015 /*
2016- System.err.println("addr: "+new String(addr));
2017+ System.err.println("addr: "+Util.byte2str(addr));
2018 System.err.println("port: "+port);
2019- System.err.println("orgaddr: "+new String(orgaddr));
2020+ System.err.println("orgaddr: "+Util.byte2str(orgaddr));
2021 System.err.println("orgport: "+orgport);
2022 */
2023
2024@@ -277,9 +281,9 @@
2025 // uint32 port number to bind
2026 packet.reset();
2027 buf.putByte((byte) 80/*SSH_MSG_GLOBAL_REQUEST*/);
2028- buf.putString("cancel-tcpip-forward".getBytes());
2029+ buf.putString(Util.str2byte("cancel-tcpip-forward"));
2030 buf.putByte((byte)0);
2031- buf.putString(address_to_bind.getBytes());
2032+ buf.putString(Util.str2byte(address_to_bind));
2033 buf.putInt(rport);
2034 session.write(packet);
2035 }
2036
2037=== modified file 'src/main/java/com/jcraft/jsch/ChannelSession.java'
2038--- src/com/jcraft/jsch/ChannelSession.java 2010-06-27 23:17:34 +0000
2039+++ src/main/java/com/jcraft/jsch/ChannelSession.java 2012-05-04 10:23:17 +0000
2040@@ -1,6 +1,6 @@
2041 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
2042 /*
2043-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
2044+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
2045
2046 Redistribution and use in source and binary forms, with or without
2047 modification, are permitted provided that the following conditions are met:
2048@@ -32,7 +32,7 @@
2049 import java.util.*;
2050
2051 class ChannelSession extends Channel{
2052- private static byte[] _session="session".getBytes();
2053+ private static byte[] _session=Util.str2byte("session");
2054
2055 protected boolean agent_forwarding=false;
2056 protected boolean xforwading=false;
2057@@ -94,7 +94,7 @@
2058 * @see RFC4254 6.4 Environment Variable Passing
2059 */
2060 public void setEnv(String name, String value){
2061- setEnv(name.getBytes(), value.getBytes());
2062+ setEnv(Util.str2byte(name), Util.str2byte(value));
2063 }
2064
2065 /**
2066@@ -226,7 +226,7 @@
2067
2068 private byte[] toByteArray(Object o){
2069 if(o instanceof String){
2070- return ((String)o).getBytes();
2071+ return Util.str2byte((String)o);
2072 }
2073 return (byte[])o;
2074 }
2075@@ -245,7 +245,7 @@
2076 i=io.in.read(buf.buffer,
2077 14,
2078 buf.buffer.length-14
2079- -32 -20 // padding and mac
2080+ -Session.buffer_margin
2081 );
2082 if(i==0)continue;
2083 if(i==-1){
2084@@ -266,8 +266,9 @@
2085 //System.err.println("# ChannelExec.run");
2086 //e.printStackTrace();
2087 }
2088- if(thread!=null){
2089- synchronized(thread){ thread.notifyAll(); }
2090+ Thread _thread=thread;
2091+ if(_thread!=null){
2092+ synchronized(_thread){ _thread.notifyAll(); }
2093 }
2094 thread=null;
2095 //System.err.println(this+":run <");
2096
2097=== modified file 'src/main/java/com/jcraft/jsch/ChannelSftp.java'
2098--- src/com/jcraft/jsch/ChannelSftp.java 2010-06-27 23:17:34 +0000
2099+++ src/main/java/com/jcraft/jsch/ChannelSftp.java 2012-05-04 10:23:17 +0000
2100@@ -1,6 +1,6 @@
2101 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
2102 /*
2103-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
2104+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
2105
2106 Redistribution and use in source and binary forms, with or without
2107 modification, are permitted provided that the following conditions are met:
2108@@ -35,6 +35,9 @@
2109
2110 public class ChannelSftp extends ChannelSession{
2111
2112+ static private final int LOCAL_MAXIMUM_PACKET_SIZE=32*1024;
2113+ static private final int LOCAL_WINDOW_SIZE_MAX=(64*LOCAL_MAXIMUM_PACKET_SIZE);
2114+
2115 private static final byte SSH_FXP_INIT= 1;
2116 private static final byte SSH_FXP_VERSION= 2;
2117 private static final byte SSH_FXP_OPEN= 3;
2118@@ -131,8 +134,13 @@
2119 private boolean interactive=false;
2120 private int seq=1;
2121 private int[] ackid=new int[1];
2122+
2123 private Buffer buf;
2124- private Packet packet=new Packet(buf);
2125+ private Packet packet;
2126+
2127+ // The followings will be used in file uploading.
2128+ private Buffer obuf;
2129+ private Packet opacket;
2130
2131 private int client_version=3;
2132 private int server_version=3;
2133@@ -169,6 +177,40 @@
2134 private String fEncoding=UTF8;
2135 private boolean fEncoding_is_utf8=true;
2136
2137+ private RequestQueue rq = new RequestQueue(16);
2138+
2139+ /**
2140+ * Specify how many requests may be sent at any one time.
2141+ * Increasing this value may slightly improve file transfer speed but will
2142+ * increase memory usage. The default is 16 requests.
2143+ *
2144+ * @param bulk_requests how many requests may be outstanding at any one time.
2145+ */
2146+ public void setBulkRequests(int bulk_requests) throws JSchException {
2147+ if(bulk_requests>0)
2148+ rq = new RequestQueue(bulk_requests);
2149+ else
2150+ throw new JSchException("setBulkRequests: "+
2151+ bulk_requests+" must be greater than 0.");
2152+ }
2153+
2154+ /**
2155+ * This method will return the value how many requests may be
2156+ * sent at any one time.
2157+ *
2158+ * @return how many requests may be sent at any one time.
2159+ */
2160+ public int getBulkRequests(){
2161+ return rq.size();
2162+ }
2163+
2164+ ChannelSftp(){
2165+ super();
2166+ setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
2167+ setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
2168+ setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
2169+ }
2170+
2171 void init(){
2172 }
2173
2174@@ -177,7 +219,7 @@
2175
2176 PipedOutputStream pos=new PipedOutputStream();
2177 io.setOutputStream(pos);
2178- PipedInputStream pis=new MyPipedInputStream(pos, 32*1024);
2179+ PipedInputStream pis=new MyPipedInputStream(pos, rmpsize);
2180 io.setInputStream(pis);
2181
2182 io_in=io.in;
2183@@ -189,15 +231,19 @@
2184 Request request=new RequestSftp();
2185 request.request(getSession(), this);
2186
2187-/*
2188+ /*
2189 System.err.println("lmpsize: "+lmpsize);
2190 System.err.println("lwsize: "+lwsize);
2191 System.err.println("rmpsize: "+rmpsize);
2192 System.err.println("rwsize: "+rwsize);
2193-*/
2194+ */
2195
2196- buf=new Buffer(rmpsize);
2197+ buf=new Buffer(lmpsize);
2198 packet=new Packet(buf);
2199+
2200+ obuf=new Buffer(rmpsize);
2201+ opacket=new Packet(obuf);
2202+
2203 int i=0;
2204 int length;
2205 int type;
2206@@ -228,8 +274,8 @@
2207 length-=(4+extension_name.length);
2208 extension_data=buf.getString();
2209 length-=(4+extension_data.length);
2210- extensions.put(new String(extension_name),
2211- new String(extension_data));
2212+ extensions.put(Util.byte2str(extension_name),
2213+ Util.byte2str(extension_data));
2214 }
2215 }
2216
2217@@ -261,8 +307,9 @@
2218
2219 public void cd(String path) throws SftpException{
2220 try{
2221+ ((MyPipedInputStream)io_in).updateReadSide();
2222+
2223 path=remoteAbsolutePath(path);
2224-
2225 path=isUnique(path);
2226
2227 byte[] str=_realpath(path);
2228@@ -299,11 +346,12 @@
2229 }
2230 public void put(String src, String dst,
2231 SftpProgressMonitor monitor, int mode) throws SftpException{
2232- src=localAbsolutePath(src);
2233- dst=remoteAbsolutePath(dst);
2234
2235- //System.err.println("src: "+src+", "+dst);
2236 try{
2237+ ((MyPipedInputStream)io_in).updateReadSide();
2238+
2239+ src=localAbsolutePath(src);
2240+ dst=remoteAbsolutePath(dst);
2241
2242 Vector v=glob_remote(dst);
2243 int vsize=v.size();
2244@@ -415,6 +463,8 @@
2245 public void put(InputStream src, String dst,
2246 SftpProgressMonitor monitor, int mode) throws SftpException{
2247 try{
2248+ ((MyPipedInputStream)io_in).updateReadSide();
2249+
2250 dst=remoteAbsolutePath(dst);
2251
2252 Vector v=glob_remote(dst);
2253@@ -436,6 +486,12 @@
2254 throw new SftpException(SSH_FX_FAILURE, dst+" is a directory");
2255 }
2256
2257+ if(monitor!=null){
2258+ monitor.init(SftpProgressMonitor.PUT,
2259+ "-", dst,
2260+ SftpProgressMonitor.UNKNOWN_SIZE);
2261+ }
2262+
2263 _put(src, dst, monitor, mode);
2264 }
2265 catch(Exception e){
2266@@ -447,8 +503,10 @@
2267 }
2268
2269 public void _put(InputStream src, String dst,
2270- SftpProgressMonitor monitor, int mode) throws SftpException{
2271+ SftpProgressMonitor monitor, int mode) throws SftpException{
2272 try{
2273+ ((MyPipedInputStream)io_in).updateReadSide();
2274+
2275 byte[] dstb=Util.str2byte(dst, fEncoding);
2276 long skip=0;
2277 if(mode==RESUME || mode==APPEND){
2278@@ -489,10 +547,9 @@
2279
2280 boolean dontcopy=true;
2281
2282- if(!dontcopy){
2283- data=new byte[buf.buffer.length
2284- -(5+13+21+handle.length
2285- +32 +20 // padding and mac
2286+ if(!dontcopy){ // This case will not work anymore.
2287+ data=new byte[obuf.buffer.length
2288+ -(5+13+21+handle.length+Session.buffer_margin
2289 )
2290 ];
2291 }
2292@@ -503,23 +560,26 @@
2293 }
2294
2295 int startid=seq;
2296- int _ackid=seq;
2297 int ackcount=0;
2298+ int _s=0;
2299+ int _datalen=0;
2300+
2301+ if(!dontcopy){ // This case will not work anymore.
2302+ _datalen=data.length;
2303+ }
2304+ else{
2305+ data=obuf.buffer;
2306+ _s=5+13+21+handle.length;
2307+ _datalen=obuf.buffer.length-_s-Session.buffer_margin;
2308+ }
2309+
2310+ int bulk_requests = rq.size();
2311+
2312 while(true){
2313 int nread=0;
2314- int s=0;
2315- int datalen=0;
2316 int count=0;
2317-
2318- if(!dontcopy){
2319- datalen=data.length-s;
2320- }
2321- else{
2322- data=buf.buffer;
2323- s=5+13+21+handle.length;
2324- datalen=buf.buffer.length -s
2325- -32 -20; // padding and mac
2326- }
2327+ int s=_s;
2328+ int datalen=_datalen;
2329
2330 do{
2331 nread=src.read(data, s, datalen);
2332@@ -532,20 +592,19 @@
2333 while(datalen>0 && nread>0);
2334 if(count<=0)break;
2335
2336- int _i=count;
2337- while(_i>0){
2338- _i-=sendWRITE(handle, offset, data, 0, _i);
2339+ int foo=count;
2340+ while(foo>0){
2341 if((seq-1)==startid ||
2342- io_in.available()>=1024){
2343- while(io_in.available()>0){
2344+ ((seq-startid)-ackcount)>=bulk_requests){
2345+ while(((seq-startid)-ackcount)>=bulk_requests){
2346+ if(this.rwsize>=foo) break;
2347 if(checkStatus(ackid, header)){
2348- _ackid=ackid[0];
2349+ int _ackid = ackid[0];
2350 if(startid>_ackid || _ackid>seq-1){
2351 if(_ackid==seq){
2352 System.err.println("ack error: startid="+startid+" seq="+seq+" _ackid="+_ackid);
2353 }
2354 else{
2355- //throw new SftpException(SSH_FX_FAILURE, "ack error:");
2356 throw new SftpException(SSH_FX_FAILURE, "ack error: startid="+startid+" seq="+seq+" _ackid="+_ackid);
2357 }
2358 }
2359@@ -556,6 +615,7 @@
2360 }
2361 }
2362 }
2363+ foo-=sendWRITE(handle, offset, data, 0, foo);
2364 }
2365 offset+=count;
2366 if(monitor!=null && !monitor.count(count)){
2367@@ -590,9 +650,10 @@
2368 return put(dst, monitor, mode, 0);
2369 }
2370 public OutputStream put(String dst, final SftpProgressMonitor monitor, final int mode, long offset) throws SftpException{
2371- dst=remoteAbsolutePath(dst);
2372 try{
2373+ ((MyPipedInputStream)io_in).updateReadSide();
2374
2375+ dst=remoteAbsolutePath(dst);
2376 dst=isUnique(dst);
2377
2378 if(isRemoteDir(dst)){
2379@@ -757,10 +818,14 @@
2380 SftpProgressMonitor monitor, int mode) throws SftpException{
2381 // System.out.println("get: "+src+" "+dst);
2382
2383- src=remoteAbsolutePath(src);
2384- dst=localAbsolutePath(dst);
2385-
2386+ boolean _dstExist = false;
2387+ String _dst=null;
2388 try{
2389+ ((MyPipedInputStream)io_in).updateReadSide();
2390+
2391+ src=remoteAbsolutePath(src);
2392+ dst=localAbsolutePath(dst);
2393+
2394 Vector v=glob_remote(src);
2395 int vsize=v.size();
2396 if(vsize==0){
2397@@ -789,7 +854,7 @@
2398 "not supported to get directory "+_src);
2399 }
2400
2401- String _dst=null;
2402+ _dst=null;
2403 if(isDstDir){
2404 int i=_src.lastIndexOf('/');
2405 if(i==-1) dstsb.append(_src);
2406@@ -801,9 +866,10 @@
2407 _dst=dst;
2408 }
2409
2410+ File _dstFile=new File(_dst);
2411 if(mode==RESUME){
2412 long size_of_src=attr.getSize();
2413- long size_of_dst=new File(_dst).length();
2414+ long size_of_dst=_dstFile.length();
2415 if(size_of_dst>size_of_src){
2416 throw new SftpException(SSH_FX_FAILURE,
2417 "failed to resume for "+_dst);
2418@@ -816,11 +882,12 @@
2419 if(monitor!=null){
2420 monitor.init(SftpProgressMonitor.GET, _src, _dst, attr.getSize());
2421 if(mode==RESUME){
2422- monitor.count(new File(_dst).length());
2423+ monitor.count(_dstFile.length());
2424 }
2425 }
2426
2427- FileOutputStream fos=null;
2428+ FileOutputStream fos=null;
2429+ _dstExist = _dstFile.exists();
2430 try{
2431 if(mode==OVERWRITE){
2432 fos=new FileOutputStream(_dst);
2433@@ -839,6 +906,12 @@
2434 }
2435 }
2436 catch(Exception e){
2437+ if(!_dstExist && _dst!=null){
2438+ File _dstFile = new File(_dst);
2439+ if(_dstFile.exists() && _dstFile.length()==0){
2440+ _dstFile.delete();
2441+ }
2442+ }
2443 if(e instanceof SftpException) throw (SftpException)e;
2444 if(e instanceof Throwable)
2445 throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e);
2446@@ -856,8 +929,9 @@
2447 SftpProgressMonitor monitor, int mode, long skip) throws SftpException{
2448 //System.err.println("get: "+src+", "+dst);
2449 try{
2450+ ((MyPipedInputStream)io_in).updateReadSide();
2451+
2452 src=remoteAbsolutePath(src);
2453-
2454 src=isUnique(src);
2455
2456 if(monitor!=null){
2457@@ -908,18 +982,27 @@
2458 offset+=skip;
2459 }
2460
2461- int request_len=0;
2462+ int request_max=1;
2463+ rq.init();
2464+ long request_offset=offset;
2465+
2466+ int request_len = buf.buffer.length-13;
2467+ if(server_version==0){ request_len=1024; }
2468+
2469 loop:
2470 while(true){
2471
2472- request_len=buf.buffer.length-13;
2473- if(server_version==0){ request_len=1024; }
2474- sendREAD(handle, offset, request_len);
2475+ while(rq.count() < request_max){
2476+ sendREAD(handle, request_offset, request_len, rq);
2477+ request_offset += request_len;
2478+ }
2479
2480 header=header(buf, header);
2481 length=header.length;
2482 type=header.type;
2483
2484+ RequestQueue.Request rr = rq.get(header.rid);
2485+
2486 if(type==SSH_FXP_STATUS){
2487 fill(buf, length);
2488 int i=buf.getInt();
2489@@ -935,19 +1018,31 @@
2490
2491 buf.rewind();
2492 fill(buf.buffer, 0, 4); length-=4;
2493- int i=buf.getInt(); // length of data
2494- int foo=i;
2495-
2496+ int length_of_data = buf.getInt(); // length of data
2497+
2498+ /**
2499+ Since sftp protocol version 6, "end-of-file" has been defined,
2500+
2501+ byte SSH_FXP_DATA
2502+ uint32 request-id
2503+ string data
2504+ bool end-of-file [optional]
2505+
2506+ but some sftpd server will send such a field in the sftp protocol 3 ;-(
2507+ */
2508+ int optional_data = length - length_of_data;
2509+
2510+ int foo = length_of_data;
2511 while(foo>0){
2512 int bar=foo;
2513 if(bar>buf.buffer.length){
2514 bar=buf.buffer.length;
2515 }
2516- i=io_in.read(buf.buffer, 0, bar);
2517- if(i<0){
2518+ int data_len = io_in.read(buf.buffer, 0, bar);
2519+ if(data_len<0){
2520 break loop;
2521 }
2522- int data_len=i;
2523+
2524 dst.write(buf.buffer, 0, data_len);
2525
2526 offset+=data_len;
2527@@ -955,12 +1050,9 @@
2528
2529 if(monitor!=null){
2530 if(!monitor.count(data_len)){
2531- while(foo>0){
2532- i=io_in.read(buf.buffer,
2533- 0,
2534- (buf.buffer.length<foo?buf.buffer.length:foo));
2535- if(i<=0) break;
2536- foo-=i;
2537+ skip(foo);
2538+ if(optional_data>0){
2539+ skip(optional_data);
2540 }
2541 break loop;
2542 }
2543@@ -968,10 +1060,27 @@
2544
2545 }
2546 //System.err.println("length: "+length); // length should be 0
2547+
2548+ if(optional_data>0){
2549+ skip(optional_data);
2550+ }
2551+
2552+ if(length_of_data<rr.length){ //
2553+ rq.cancel(header, buf);
2554+ sendREAD(handle, rr.offset+length_of_data, (int)(rr.length-length_of_data), rq);
2555+ request_offset=rr.offset+rr.length;
2556+ }
2557+
2558+ if(request_max < rq.size()){
2559+ request_max++;
2560+ }
2561 }
2562 dst.flush();
2563
2564 if(monitor!=null)monitor.end();
2565+
2566+ rq.cancel(header, buf);
2567+
2568 _sendCLOSE(handle, header);
2569 }
2570 catch(Exception e){
2571@@ -982,6 +1091,69 @@
2572 }
2573 }
2574
2575+
2576+ private class RequestQueue {
2577+ class Request {
2578+ int id;
2579+ long offset;
2580+ long length;
2581+ }
2582+
2583+ Request[] rrq=null;
2584+ int head, count;
2585+ RequestQueue(int size){
2586+ rrq = new Request[size];
2587+ for(int i=0; i<rrq.length; i++){
2588+ rrq[i]=new Request();
2589+ }
2590+ init();
2591+ }
2592+
2593+ void init(){
2594+ head=count=0;
2595+ }
2596+
2597+ void add(int id, long offset, int length){
2598+ if(count == 0) head = 0;
2599+ int tail = head + count;
2600+ if(tail>=rrq.length) tail -= rrq.length;
2601+ rrq[tail].id=id;
2602+ rrq[tail].offset=offset;
2603+ rrq[tail].length=length;
2604+ count++;
2605+ }
2606+
2607+ Request get(int id){
2608+ count -= 1;
2609+ int i=head;
2610+ head++;
2611+ if(head==rrq.length) head=0;
2612+ if(rrq[i].id!=id){
2613+ System.err.println("The request is not in order.");
2614+ }
2615+ rrq[i].id=0;
2616+ return rrq[i];
2617+ }
2618+
2619+ int count() {
2620+ return count;
2621+ }
2622+
2623+ int size() {
2624+ return rrq.length;
2625+ }
2626+
2627+ void cancel(Header header, Buffer buf) throws IOException {
2628+ int _count = count;
2629+ for(int i=0; i<_count; i++){
2630+ header=header(buf, header);
2631+ int length=header.length;
2632+ get(header.rid);
2633+ skip(length);
2634+ }
2635+ }
2636+ }
2637+
2638 public InputStream get(String src) throws SftpException{
2639 return get(src, null, 0L);
2640 }
2641@@ -1002,8 +1174,11 @@
2642 return get(src, monitor, 0L);
2643 }
2644 public InputStream get(String src, final SftpProgressMonitor monitor, final long skip) throws SftpException{
2645- src=remoteAbsolutePath(src);
2646+
2647 try{
2648+ ((MyPipedInputStream)io_in).updateReadSide();
2649+
2650+ src=remoteAbsolutePath(src);
2651 src=isUnique(src);
2652
2653 byte[] srcb=Util.str2byte(src, fEncoding);
2654@@ -1032,6 +1207,8 @@
2655
2656 final byte[] handle=buf.getString(); // handle
2657
2658+ rq.init();
2659+
2660 java.io.InputStream in=new java.io.InputStream(){
2661 long offset=skip;
2662 boolean closed=false;
2663@@ -1039,6 +1216,8 @@
2664 byte[] _data=new byte[1];
2665 byte[] rest_byte=new byte[1024];
2666 Header header=new Header();
2667+ int request_max=1;
2668+ long request_offset=offset;
2669
2670 public int read() throws java.io.IOException{
2671 if(closed)return -1;
2672@@ -1087,14 +1266,26 @@
2673 len=1024;
2674 }
2675
2676- try{sendREAD(handle, offset, len);}
2677- catch(Exception e){ throw new IOException("error"); }
2678+ if(rq.count()==0) {
2679+ int request_len = buf.buffer.length-13;
2680+ if(server_version==0){ request_len=1024; }
2681+
2682+ while(rq.count() < request_max){
2683+ try{
2684+ sendREAD(handle, request_offset, request_len, rq);
2685+ }
2686+ catch(Exception e){ throw new IOException("error"); }
2687+ request_offset += request_len;
2688+ }
2689+ }
2690
2691 header=header(buf, header);
2692 rest_length=header.length;
2693 int type=header.type;
2694 int id=header.rid;
2695
2696+ RequestQueue.Request rr = rq.get(header.rid);
2697+
2698 if(type!=SSH_FXP_STATUS && type!=SSH_FXP_DATA){
2699 throw new IOException("error");
2700 }
2701@@ -1109,29 +1300,43 @@
2702 //throwStatusError(buf, i);
2703 throw new IOException("error");
2704 }
2705+
2706 buf.rewind();
2707 fill(buf.buffer, 0, 4);
2708- int i=buf.getInt(); rest_length-=4;
2709-
2710- offset+=rest_length;
2711- int foo=i;
2712+ int length_of_data = buf.getInt(); rest_length-=4;
2713+
2714+ /**
2715+ Since sftp protocol version 6, "end-of-file" has been defined,
2716+
2717+ byte SSH_FXP_DATA
2718+ uint32 request-id
2719+ string data
2720+ bool end-of-file [optional]
2721+
2722+ but some sftpd server will send such a field in the sftp protocol 3 ;-(
2723+ */
2724+ int optional_data = rest_length - length_of_data;
2725+
2726+ offset += length_of_data;
2727+ int foo = length_of_data;
2728 if(foo>0){
2729- int bar=rest_length;
2730+ int bar=foo;
2731 if(bar>len){
2732 bar=len;
2733 }
2734- i=io_in.read(d, s, bar);
2735+ int i=io_in.read(d, s, bar);
2736 if(i<0){
2737 return -1;
2738 }
2739- rest_length-=i;
2740+ foo-=i;
2741+ rest_length=foo;
2742
2743- if(rest_length>0){
2744- if(rest_byte.length<rest_length){
2745- rest_byte=new byte[rest_length];
2746+ if(foo>0){
2747+ if(rest_byte.length<foo){
2748+ rest_byte=new byte[foo];
2749 }
2750 int _s=0;
2751- int _len=rest_length;
2752+ int _len=foo;
2753 int j;
2754 while(_len>0){
2755 j=io_in.read(rest_byte, _s, _len);
2756@@ -1141,6 +1346,25 @@
2757 }
2758 }
2759
2760+ if(optional_data>0){
2761+ io_in.skip(optional_data);
2762+ }
2763+
2764+ if(length_of_data<rr.length){ //
2765+ rq.cancel(header, buf);
2766+ try {
2767+ sendREAD(handle,
2768+ rr.offset+length_of_data,
2769+ (int)(rr.length-length_of_data), rq);
2770+ }
2771+ catch(Exception e){ throw new IOException("error"); }
2772+ request_offset=rr.offset+rr.length;
2773+ }
2774+
2775+ if(request_max < rq.size()){
2776+ request_max++;
2777+ }
2778+
2779 if(monitor!=null){
2780 if(!monitor.count(i)){
2781 close();
2782@@ -1156,6 +1380,7 @@
2783 if(closed)return;
2784 closed=true;
2785 if(monitor!=null)monitor.end();
2786+ rq.cancel(header, buf);
2787 try{_sendCLOSE(handle, header);}
2788 catch(Exception e){throw new IOException("error");}
2789 }
2790@@ -1171,8 +1396,32 @@
2791 }
2792
2793 public java.util.Vector ls(String path) throws SftpException{
2794+ final java.util.Vector v = new Vector();
2795+ LsEntrySelector selector = new LsEntrySelector(){
2796+ public int select(LsEntry entry){
2797+ v.addElement(entry);
2798+ return CONTINUE;
2799+ }
2800+ };
2801+ ls(path, selector);
2802+ return v;
2803+ }
2804+
2805+ /**
2806+ * List files specified by the remote <code>path</code>.
2807+ * Each files and directories will be passed to
2808+ * <code>LsEntrySelector#select(LsEntry)</code> method, and if that method
2809+ * returns <code>LsEntrySelector#BREAK</code>, the operation will be
2810+ * canceled immediately.
2811+ *
2812+ * @see #LsEntrySelector
2813+ * @since 0.1.47
2814+ */
2815+ public void ls(String path, LsEntrySelector selector) throws SftpException{
2816 //System.out.println("ls: "+path);
2817 try{
2818+ ((MyPipedInputStream)io_in).updateReadSide();
2819+
2820 path=remoteAbsolutePath(path);
2821 byte[] pattern=null;
2822 java.util.Vector v=new java.util.Vector();
2823@@ -1237,9 +1486,11 @@
2824 throwStatusError(buf, i);
2825 }
2826
2827+ int cancel = LsEntrySelector.CONTINUE;
2828 byte[] handle=buf.getString(); // handle
2829
2830- while(true){
2831+ while(cancel==LsEntrySelector.CONTINUE){
2832+
2833 sendREADDIR(handle);
2834
2835 header=header(buf, header);
2836@@ -1281,6 +1532,11 @@
2837 }
2838 SftpATTRS attrs=SftpATTRS.getATTR(buf);
2839
2840+ if(cancel==LsEntrySelector.BREAK){
2841+ count--;
2842+ continue;
2843+ }
2844+
2845 boolean find=false;
2846 String f=null;
2847 if(pattern==null){
2848@@ -1311,7 +1567,8 @@
2849 else{
2850 l=Util.byte2str(longname, fEncoding);
2851 }
2852- v.addElement(new LsEntry(f, l, attrs));
2853+
2854+ cancel = selector.select(new LsEntry(f, l, attrs));
2855 }
2856
2857 count--;
2858@@ -1336,7 +1593,6 @@
2859 }
2860 */
2861
2862- return v;
2863 }
2864 catch(Exception e){
2865 if(e instanceof SftpException) throw (SftpException)e;
2866@@ -1345,14 +1601,16 @@
2867 throw new SftpException(SSH_FX_FAILURE, "");
2868 }
2869 }
2870+
2871 public String readlink(String path) throws SftpException{
2872 try{
2873-
2874 if(server_version<3){
2875 throw new SftpException(SSH_FX_OP_UNSUPPORTED,
2876 "The remote sshd is too old to support symlink operation.");
2877 }
2878
2879+ ((MyPipedInputStream)io_in).updateReadSide();
2880+
2881 path=remoteAbsolutePath(path);
2882
2883 path=isUnique(path);
2884@@ -1400,6 +1658,8 @@
2885 }
2886
2887 try{
2888+ ((MyPipedInputStream)io_in).updateReadSide();
2889+
2890 oldpath=remoteAbsolutePath(oldpath);
2891 newpath=remoteAbsolutePath(newpath);
2892
2893@@ -1443,6 +1703,8 @@
2894 }
2895
2896 try{
2897+ ((MyPipedInputStream)io_in).updateReadSide();
2898+
2899 oldpath=remoteAbsolutePath(oldpath);
2900 newpath=remoteAbsolutePath(newpath);
2901
2902@@ -1489,6 +1751,8 @@
2903 }
2904 public void rm(String path) throws SftpException{
2905 try{
2906+ ((MyPipedInputStream)io_in).updateReadSide();
2907+
2908 path=remoteAbsolutePath(path);
2909
2910 Vector v=glob_remote(path);
2911@@ -1546,6 +1810,8 @@
2912
2913 public void chgrp(int gid, String path) throws SftpException{
2914 try{
2915+ ((MyPipedInputStream)io_in).updateReadSide();
2916+
2917 path=remoteAbsolutePath(path);
2918
2919 Vector v=glob_remote(path);
2920@@ -1570,6 +1836,8 @@
2921
2922 public void chown(int uid, String path) throws SftpException{
2923 try{
2924+ ((MyPipedInputStream)io_in).updateReadSide();
2925+
2926 path=remoteAbsolutePath(path);
2927
2928 Vector v=glob_remote(path);
2929@@ -1594,6 +1862,8 @@
2930
2931 public void chmod(int permissions, String path) throws SftpException{
2932 try{
2933+ ((MyPipedInputStream)io_in).updateReadSide();
2934+
2935 path=remoteAbsolutePath(path);
2936
2937 Vector v=glob_remote(path);
2938@@ -1618,6 +1888,8 @@
2939
2940 public void setMtime(String path, int mtime) throws SftpException{
2941 try{
2942+ ((MyPipedInputStream)io_in).updateReadSide();
2943+
2944 path=remoteAbsolutePath(path);
2945
2946 Vector v=glob_remote(path);
2947@@ -1642,6 +1914,8 @@
2948
2949 public void rmdir(String path) throws SftpException{
2950 try{
2951+ ((MyPipedInputStream)io_in).updateReadSide();
2952+
2953 path=remoteAbsolutePath(path);
2954
2955 Vector v=glob_remote(path);
2956@@ -1679,6 +1953,8 @@
2957
2958 public void mkdir(String path) throws SftpException{
2959 try{
2960+ ((MyPipedInputStream)io_in).updateReadSide();
2961+
2962 path=remoteAbsolutePath(path);
2963
2964 sendMKDIR(Util.str2byte(path, fEncoding), null);
2965@@ -1708,8 +1984,9 @@
2966
2967 public SftpATTRS stat(String path) throws SftpException{
2968 try{
2969+ ((MyPipedInputStream)io_in).updateReadSide();
2970+
2971 path=remoteAbsolutePath(path);
2972-
2973 path=isUnique(path);
2974
2975 return _stat(path);
2976@@ -1760,8 +2037,9 @@
2977
2978 public SftpATTRS lstat(String path) throws SftpException{
2979 try{
2980+ ((MyPipedInputStream)io_in).updateReadSide();
2981+
2982 path=remoteAbsolutePath(path);
2983-
2984 path=isUnique(path);
2985
2986 return _lstat(path);
2987@@ -1836,6 +2114,8 @@
2988
2989 public void setStat(String path, SftpATTRS attr) throws SftpException{
2990 try{
2991+ ((MyPipedInputStream)io_in).updateReadSide();
2992+
2993 path=remoteAbsolutePath(path);
2994
2995 Vector v=glob_remote(path);
2996@@ -1885,6 +2165,8 @@
2997 public String getHome() throws SftpException {
2998 if(home==null){
2999 try{
3000+ ((MyPipedInputStream)io_in).updateReadSide();
3001+
3002 byte[] _home=_realpath("");
3003 home=Util.byte2str(_home, fEncoding);
3004 }
3005@@ -2040,32 +2322,31 @@
3006 private int sendWRITE(byte[] handle, long offset,
3007 byte[] data, int start, int length) throws Exception{
3008 int _length=length;
3009- packet.reset();
3010- if(buf.buffer.length<buf.index+13+21+handle.length+length
3011- +32 +20 // padding and mac
3012-){
3013- _length=buf.buffer.length-(buf.index+13+21+handle.length
3014- +32 +20 // padding and mac
3015-);
3016- //System.err.println("_length="+_length+" length="+length);
3017+ opacket.reset();
3018+ if(obuf.buffer.length<obuf.index+13+21+handle.length+length+Session.buffer_margin){
3019+ _length=obuf.buffer.length-(obuf.index+13+21+handle.length+Session.buffer_margin);
3020+ // System.err.println("_length="+_length+" length="+length);
3021 }
3022
3023- putHEAD(SSH_FXP_WRITE, 21+handle.length+_length); // 14
3024- buf.putInt(seq++); // 4
3025- buf.putString(handle); // 4+handle.length
3026- buf.putLong(offset); // 8
3027- if(buf.buffer!=data){
3028- buf.putString(data, start, _length); // 4+_length
3029+ putHEAD(obuf, SSH_FXP_WRITE, 21+handle.length+_length); // 14
3030+ obuf.putInt(seq++); // 4
3031+ obuf.putString(handle); // 4+handle.length
3032+ obuf.putLong(offset); // 8
3033+ if(obuf.buffer!=data){
3034+ obuf.putString(data, start, _length); // 4+_length
3035 }
3036 else{
3037- buf.putInt(_length);
3038- buf.skip(_length);
3039+ obuf.putInt(_length);
3040+ obuf.skip(_length);
3041 }
3042- getSession().write(packet, this, 21+handle.length+_length+4);
3043+ getSession().write(opacket, this, 21+handle.length+_length+4);
3044 return _length;
3045 }
3046-
3047 private void sendREAD(byte[] handle, long offset, int length) throws Exception{
3048+ sendREAD(handle, offset, length, null);
3049+ }
3050+ private void sendREAD(byte[] handle, long offset, int length,
3051+ RequestQueue rrq) throws Exception{
3052 packet.reset();
3053 putHEAD(SSH_FXP_READ, 21+handle.length);
3054 buf.putInt(seq++);
3055@@ -2073,9 +2354,12 @@
3056 buf.putLong(offset);
3057 buf.putInt(length);
3058 getSession().write(packet, this, 21+handle.length+4);
3059+ if(rrq!=null){
3060+ rrq.add(seq-1, offset, length);
3061+ }
3062 }
3063
3064- private void putHEAD(byte type, int length) throws Exception{
3065+ private void putHEAD(Buffer buf, byte type, int length) throws Exception{
3066 buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
3067 buf.putInt(recipient);
3068 buf.putInt(length+4);
3069@@ -2083,8 +2367,11 @@
3070 buf.putByte(type);
3071 }
3072
3073+ private void putHEAD(byte type, int length) throws Exception{
3074+ putHEAD(buf, type, length);
3075+ }
3076+
3077 private Vector glob_remote(String _path) throws Exception{
3078-
3079 Vector v=new Vector();
3080 int i=0;
3081
3082@@ -2104,7 +2391,7 @@
3083 boolean pattern_has_wildcard=isPattern(_pattern, _pattern_utf8);
3084
3085 if(!pattern_has_wildcard){
3086- if(dir.length()!=1) // not equal to "/"
3087+ if(!dir.equals("/"))
3088 dir+="/";
3089 v.addElement(dir+Util.unquote(_pattern));
3090 return v;
3091@@ -2202,23 +2489,16 @@
3092 }
3093
3094 private boolean isPattern(byte[] path){
3095- int i=path.length-1;
3096- while(i>=0){
3097- if(path[i]=='*' || path[i]=='?'){
3098- if(i>0 && path[i-1]=='\\'){
3099- i--;
3100- if(i>0 && path[i-1]=='\\'){ // \\* or \\?
3101- break;
3102- }
3103- }
3104- else{
3105- break;
3106- }
3107- }
3108- i--;
3109+ int length=path.length;
3110+ int i=0;
3111+ while(i<length){
3112+ if(path[i]=='*' || path[i]=='?')
3113+ return true;
3114+ if(path[i]=='\\' && (i+1)<length)
3115+ i++;
3116+ i++;
3117 }
3118- // System.err.println("isPattern: ["+(new String(path))+"] "+(!(i<0)));
3119- return !(i<0);
3120+ return false;
3121 }
3122
3123 private Vector glob_local(String _path) throws Exception{
3124@@ -2358,6 +2638,7 @@
3125 private String remoteAbsolutePath(String path) throws SftpException{
3126 if(path.charAt(0)=='/') return path;
3127 String cwd=getCwd();
3128+// if(cwd.equals(getHome())) return path;
3129 if(cwd.endsWith("/")) return cwd+path;
3130 return cwd+"/"+path;
3131 }
3132@@ -2391,9 +2672,9 @@
3133
3134 public void setFilenameEncoding(String encoding) throws SftpException{
3135 int sversion=getServerVersion();
3136- if(sversion > 3 &&
3137+ if(3 <= sversion && sversion <= 5 &&
3138 !encoding.equals(UTF8)){
3139- throw new SftpException(SSH_FX_FAILURE,
3140+ throw new SftpException(SSH_FX_FAILURE,
3141 "The encoding can not be changed for this sftp server.");
3142 }
3143 if(encoding.equals(UTF8)){
3144@@ -2445,4 +2726,26 @@
3145 throw new ClassCastException("a decendent of LsEntry must be given.");
3146 }
3147 }
3148+
3149+ /**
3150+ * This interface will be passed as an arugment for <code>ls</code> method.
3151+ *
3152+ * @see #LsEntry
3153+ * @see #ls(String, LsEntrySelector)
3154+ * @since 0.1.47
3155+ */
3156+ public interface LsEntrySelector {
3157+ public final int CONTINUE = 0;
3158+ public final int BREAK = 1;
3159+
3160+ /**
3161+ * <p> The <code>select</code> method will be invoked in <code>ls</code>
3162+ * method for each file entry. If this method returns BREAK,
3163+ * <code>ls</code> will be canceled.
3164+ *
3165+ * @param entry one of entry from ls
3166+ * @return if BREAK is returned, the 'ls' operation will be canceled.
3167+ */
3168+ public int select(LsEntry entry);
3169+ }
3170 }
3171
3172=== modified file 'src/main/java/com/jcraft/jsch/ChannelShell.java'
3173--- src/com/jcraft/jsch/ChannelShell.java 2010-06-27 23:17:34 +0000
3174+++ src/main/java/com/jcraft/jsch/ChannelShell.java 2012-05-04 10:23:17 +0000
3175@@ -1,6 +1,6 @@
3176 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3177 /*
3178-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
3179+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
3180
3181 Redistribution and use in source and binary forms, with or without
3182 modification, are permitted provided that the following conditions are met:
3183
3184=== modified file 'src/main/java/com/jcraft/jsch/ChannelSubsystem.java'
3185--- src/com/jcraft/jsch/ChannelSubsystem.java 2010-06-27 23:17:34 +0000
3186+++ src/main/java/com/jcraft/jsch/ChannelSubsystem.java 2012-05-04 10:23:17 +0000
3187@@ -1,6 +1,6 @@
3188 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3189 /*
3190-Copyright (c) 2005-2009 ymnk, JCraft,Inc. All rights reserved.
3191+Copyright (c) 2005-2012 ymnk, JCraft,Inc. All rights reserved.
3192
3193 Redistribution and use in source and binary forms, with or without
3194 modification, are permitted provided that the following conditions are met:
3195@@ -34,7 +34,7 @@
3196 boolean pty=false;
3197 boolean want_reply=true;
3198 String subsystem="";
3199- public void setXForwarding(boolean foo){ xforwading=true; }
3200+ public void setXForwarding(boolean foo){ xforwading=foo; }
3201 public void setPty(boolean foo){ pty=foo; }
3202 public void setWantReply(boolean foo){ want_reply=foo; }
3203 public void setSubsystem(String foo){ subsystem=foo; }
3204
3205=== modified file 'src/main/java/com/jcraft/jsch/ChannelX11.java'
3206--- src/com/jcraft/jsch/ChannelX11.java 2010-06-27 23:17:34 +0000
3207+++ src/main/java/com/jcraft/jsch/ChannelX11.java 2012-05-04 10:23:17 +0000
3208@@ -1,6 +1,6 @@
3209 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3210 /*
3211-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
3212+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
3213
3214 Redistribution and use in source and binary forms, with or without
3215 modification, are permitted provided that the following conditions are met:
3216@@ -61,7 +61,7 @@
3217 return 0;
3218 }
3219 static void setCookie(String foo){
3220- cookie_hex=foo.getBytes();
3221+ cookie_hex=Util.str2byte(foo);
3222 cookie=new byte[16];
3223 for(int i=0; i<16; i++){
3224 cookie[i]=(byte)(((revtable(cookie_hex[i*2])<<4)&0xf0) |
3225@@ -99,6 +99,13 @@
3226 }
3227 }
3228
3229+ static void removeFakedCookie(Session session){
3230+ synchronized(faked_cookie_hex_pool){
3231+ faked_cookie_hex_pool.remove(session);
3232+ faked_cookie_pool.remove(session);
3233+ }
3234+ }
3235+
3236 ChannelX11(){
3237 super();
3238
3239@@ -106,7 +113,7 @@
3240 setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
3241 setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
3242
3243- type="x11".getBytes();
3244+ type=Util.str2byte("x11");
3245
3246 connected=true;
3247 /*
3248@@ -150,9 +157,7 @@
3249 io.in!=null){
3250 i=io.in.read(buf.buffer,
3251 14,
3252- buf.buffer.length-14
3253- -32 -20 // padding and mac
3254- );
3255+ buf.buffer.length-14-Session.buffer_margin);
3256 if(i<=0){
3257 eof();
3258 break;
3259
3260=== modified file 'src/main/java/com/jcraft/jsch/Cipher.java'
3261--- src/com/jcraft/jsch/Cipher.java 2010-06-27 23:17:34 +0000
3262+++ src/main/java/com/jcraft/jsch/Cipher.java 2012-05-04 10:23:17 +0000
3263@@ -1,6 +1,6 @@
3264 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3265 /*
3266-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
3267+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
3268
3269 Redistribution and use in source and binary forms, with or without
3270 modification, are permitted provided that the following conditions are met:
3271@@ -36,4 +36,5 @@
3272 int getBlockSize();
3273 void init(int mode, byte[] key, byte[] iv) throws Exception;
3274 void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception;
3275+ boolean isCBC();
3276 }
3277
3278=== modified file 'src/main/java/com/jcraft/jsch/CipherNone.java'
3279--- src/com/jcraft/jsch/CipherNone.java 2010-06-27 23:17:34 +0000
3280+++ src/main/java/com/jcraft/jsch/CipherNone.java 2012-05-04 10:23:17 +0000
3281@@ -1,6 +1,6 @@
3282 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3283 /*
3284-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
3285+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
3286
3287 Redistribution and use in source and binary forms, with or without
3288 modification, are permitted provided that the following conditions are met:
3289@@ -38,4 +38,5 @@
3290 }
3291 public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
3292 }
3293+ public boolean isCBC(){return false; }
3294 }
3295
3296=== modified file 'src/main/java/com/jcraft/jsch/Compression.java'
3297--- src/com/jcraft/jsch/Compression.java 2010-06-27 23:17:34 +0000
3298+++ src/main/java/com/jcraft/jsch/Compression.java 2012-05-04 10:23:17 +0000
3299@@ -1,6 +1,6 @@
3300 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3301 /*
3302-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
3303+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
3304
3305 Redistribution and use in source and binary forms, with or without
3306 modification, are permitted provided that the following conditions are met:
3307@@ -33,6 +33,6 @@
3308 static public final int INFLATER=0;
3309 static public final int DEFLATER=1;
3310 void init(int type, int level);
3311- int compress(byte[] buf, int start, int len);
3312+ byte[] compress(byte[] buf, int start, int[] len);
3313 byte[] uncompress(byte[] buf, int start, int[] len);
3314 }
3315
3316=== modified file 'src/main/java/com/jcraft/jsch/DH.java'
3317--- src/com/jcraft/jsch/DH.java 2010-06-27 23:17:34 +0000
3318+++ src/main/java/com/jcraft/jsch/DH.java 2012-05-04 10:23:17 +0000
3319@@ -1,6 +1,6 @@
3320 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3321 /*
3322-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
3323+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
3324
3325 Redistribution and use in source and binary forms, with or without
3326 modification, are permitted provided that the following conditions are met:
3327
3328=== modified file 'src/main/java/com/jcraft/jsch/DHG1.java'
3329--- src/com/jcraft/jsch/DHG1.java 2010-06-27 23:17:34 +0000
3330+++ src/main/java/com/jcraft/jsch/DHG1.java 2012-05-04 10:23:17 +0000
3331@@ -1,6 +1,6 @@
3332 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3333 /*
3334-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
3335+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
3336
3337 Redistribution and use in source and binary forms, with or without
3338 modification, are permitted provided that the following conditions are met:
3339@@ -203,7 +203,7 @@
3340 j=0;
3341 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
3342 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
3343- String alg=new String(K_S, i, j);
3344+ String alg=Util.byte2str(K_S, i, j);
3345 i+=j;
3346
3347 boolean result=false;
3348
3349=== added file 'src/main/java/com/jcraft/jsch/DHG14.java'
3350--- src/main/java/com/jcraft/jsch/DHG14.java 1970-01-01 00:00:00 +0000
3351+++ src/main/java/com/jcraft/jsch/DHG14.java 2012-05-04 10:23:17 +0000
3352@@ -0,0 +1,310 @@
3353+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3354+/*
3355+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
3356+
3357+Redistribution and use in source and binary forms, with or without
3358+modification, are permitted provided that the following conditions are met:
3359+
3360+ 1. Redistributions of source code must retain the above copyright notice,
3361+ this list of conditions and the following disclaimer.
3362+
3363+ 2. Redistributions in binary form must reproduce the above copyright
3364+ notice, this list of conditions and the following disclaimer in
3365+ the documentation and/or other materials provided with the distribution.
3366+
3367+ 3. The names of the authors may not be used to endorse or promote products
3368+ derived from this software without specific prior written permission.
3369+
3370+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
3371+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
3372+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
3373+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
3374+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3375+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
3376+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3377+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3378+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
3379+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3380+*/
3381+
3382+package com.jcraft.jsch;
3383+
3384+public class DHG14 extends KeyExchange{
3385+
3386+ static final byte[] g={ 2 };
3387+ static final byte[] p={
3388+(byte)0x00,
3389+(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
3390+(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
3391+(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
3392+(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
3393+(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
3394+(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
3395+(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
3396+(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
3397+(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
3398+(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
3399+(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
3400+(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
3401+(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
3402+(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
3403+(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D,
3404+(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05,
3405+(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A,
3406+(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F,
3407+(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96,
3408+(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB,
3409+(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D,
3410+(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04,
3411+(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C,
3412+(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B,
3413+(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03,
3414+(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F,
3415+(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9,
3416+(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18,
3417+(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5,
3418+(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10,
3419+(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAC,(byte)0xAA,(byte)0x68,
3420+(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
3421+};
3422+
3423+ private static final int SSH_MSG_KEXDH_INIT= 30;
3424+ private static final int SSH_MSG_KEXDH_REPLY= 31;
3425+
3426+ static final int RSA=0;
3427+ static final int DSS=1;
3428+ private int type=0;
3429+
3430+ private int state;
3431+
3432+ DH dh;
3433+
3434+ byte[] V_S;
3435+ byte[] V_C;
3436+ byte[] I_S;
3437+ byte[] I_C;
3438+
3439+ byte[] e;
3440+
3441+ private Buffer buf;
3442+ private Packet packet;
3443+
3444+ public void init(Session session,
3445+ byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
3446+ this.session=session;
3447+ this.V_S=V_S;
3448+ this.V_C=V_C;
3449+ this.I_S=I_S;
3450+ this.I_C=I_C;
3451+
3452+ try{
3453+ Class c=Class.forName(session.getConfig("sha-1"));
3454+ sha=(HASH)(c.newInstance());
3455+ sha.init();
3456+ }
3457+ catch(Exception e){
3458+ System.err.println(e);
3459+ }
3460+
3461+ buf=new Buffer();
3462+ packet=new Packet(buf);
3463+
3464+ try{
3465+ Class c=Class.forName(session.getConfig("dh"));
3466+ dh=(DH)(c.newInstance());
3467+ dh.init();
3468+ }
3469+ catch(Exception e){
3470+ //System.err.println(e);
3471+ throw e;
3472+ }
3473+
3474+ dh.setP(p);
3475+ dh.setG(g);
3476+ // The client responds with:
3477+ // byte SSH_MSG_KEXDH_INIT(30)
3478+ // mpint e <- g^x mod p
3479+ // x is a random number (1 < x < (p-1)/2)
3480+
3481+ e=dh.getE();
3482+ packet.reset();
3483+ buf.putByte((byte)SSH_MSG_KEXDH_INIT);
3484+ buf.putMPInt(e);
3485+
3486+ if(V_S==null){ // This is a really ugly hack for Session.checkKexes ;-(
3487+ return;
3488+ }
3489+
3490+ session.write(packet);
3491+
3492+ if(JSch.getLogger().isEnabled(Logger.INFO)){
3493+ JSch.getLogger().log(Logger.INFO,
3494+ "SSH_MSG_KEXDH_INIT sent");
3495+ JSch.getLogger().log(Logger.INFO,
3496+ "expecting SSH_MSG_KEXDH_REPLY");
3497+ }
3498+
3499+ state=SSH_MSG_KEXDH_REPLY;
3500+ }
3501+
3502+ public boolean next(Buffer _buf) throws Exception{
3503+ int i,j;
3504+
3505+ switch(state){
3506+ case SSH_MSG_KEXDH_REPLY:
3507+ // The server responds with:
3508+ // byte SSH_MSG_KEXDH_REPLY(31)
3509+ // string server public host key and certificates (K_S)
3510+ // mpint f
3511+ // string signature of H
3512+ j=_buf.getInt();
3513+ j=_buf.getByte();
3514+ j=_buf.getByte();
3515+ if(j!=31){
3516+ System.err.println("type: must be 31 "+j);
3517+ return false;
3518+ }
3519+
3520+ K_S=_buf.getString();
3521+ // K_S is server_key_blob, which includes ....
3522+ // string ssh-dss
3523+ // impint p of dsa
3524+ // impint q of dsa
3525+ // impint g of dsa
3526+ // impint pub_key of dsa
3527+ //System.err.print("K_S: "); //dump(K_S, 0, K_S.length);
3528+ byte[] f=_buf.getMPInt();
3529+ byte[] sig_of_H=_buf.getString();
3530+
3531+ dh.setF(f);
3532+ K=dh.getK();
3533+
3534+ //The hash H is computed as the HASH hash of the concatenation of the
3535+ //following:
3536+ // string V_C, the client's version string (CR and NL excluded)
3537+ // string V_S, the server's version string (CR and NL excluded)
3538+ // string I_C, the payload of the client's SSH_MSG_KEXINIT
3539+ // string I_S, the payload of the server's SSH_MSG_KEXINIT
3540+ // string K_S, the host key
3541+ // mpint e, exchange value sent by the client
3542+ // mpint f, exchange value sent by the server
3543+ // mpint K, the shared secret
3544+ // This value is called the exchange hash, and it is used to authenti-
3545+ // cate the key exchange.
3546+ buf.reset();
3547+ buf.putString(V_C); buf.putString(V_S);
3548+ buf.putString(I_C); buf.putString(I_S);
3549+ buf.putString(K_S);
3550+ buf.putMPInt(e); buf.putMPInt(f);
3551+ buf.putMPInt(K);
3552+ byte[] foo=new byte[buf.getLength()];
3553+ buf.getByte(foo);
3554+ sha.update(foo, 0, foo.length);
3555+ H=sha.digest();
3556+ //System.err.print("H -> "); //dump(H, 0, H.length);
3557+
3558+ i=0;
3559+ j=0;
3560+ j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
3561+ ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
3562+ String alg=Util.byte2str(K_S, i, j);
3563+ i+=j;
3564+
3565+ boolean result=false;
3566+
3567+ if(alg.equals("ssh-rsa")){
3568+ byte[] tmp;
3569+ byte[] ee;
3570+ byte[] n;
3571+
3572+ type=RSA;
3573+
3574+ j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
3575+ ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
3576+ tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
3577+ ee=tmp;
3578+ j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
3579+ ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
3580+ tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
3581+ n=tmp;
3582+
3583+ SignatureRSA sig=null;
3584+ try{
3585+ Class c=Class.forName(session.getConfig("signature.rsa"));
3586+ sig=(SignatureRSA)(c.newInstance());
3587+ sig.init();
3588+ }
3589+ catch(Exception e){
3590+ System.err.println(e);
3591+ }
3592+
3593+ sig.setPubKey(ee, n);
3594+ sig.update(H);
3595+ result=sig.verify(sig_of_H);
3596+
3597+ if(JSch.getLogger().isEnabled(Logger.INFO)){
3598+ JSch.getLogger().log(Logger.INFO,
3599+ "ssh_rsa_verify: signature "+result);
3600+ }
3601+
3602+ }
3603+ else if(alg.equals("ssh-dss")){
3604+ byte[] q=null;
3605+ byte[] tmp;
3606+ byte[] p;
3607+ byte[] g;
3608+
3609+ type=DSS;
3610+
3611+ j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
3612+ ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
3613+ tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
3614+ p=tmp;
3615+ j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
3616+ ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
3617+ tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
3618+ q=tmp;
3619+ j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
3620+ ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
3621+ tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
3622+ g=tmp;
3623+ j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
3624+ ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
3625+ tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
3626+ f=tmp;
3627+
3628+ SignatureDSA sig=null;
3629+ try{
3630+ Class c=Class.forName(session.getConfig("signature.dss"));
3631+ sig=(SignatureDSA)(c.newInstance());
3632+ sig.init();
3633+ }
3634+ catch(Exception e){
3635+ System.err.println(e);
3636+ }
3637+ sig.setPubKey(f, p, q, g);
3638+ sig.update(H);
3639+ result=sig.verify(sig_of_H);
3640+
3641+ if(JSch.getLogger().isEnabled(Logger.INFO)){
3642+ JSch.getLogger().log(Logger.INFO,
3643+ "ssh_dss_verify: signature "+result);
3644+ }
3645+
3646+ }
3647+ else{
3648+ System.err.println("unknown alg");
3649+ }
3650+ state=STATE_END;
3651+ return result;
3652+ }
3653+ return false;
3654+ }
3655+
3656+ public String getKeyType(){
3657+ if(type==DSS) return "DSA";
3658+ return "RSA";
3659+ }
3660+
3661+ public int getState(){return state; }
3662+}
3663
3664=== modified file 'src/main/java/com/jcraft/jsch/DHGEX.java'
3665--- src/com/jcraft/jsch/DHGEX.java 2010-06-27 23:17:34 +0000
3666+++ src/main/java/com/jcraft/jsch/DHGEX.java 2012-05-04 10:23:17 +0000
3667@@ -1,6 +1,6 @@
3668 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3669 /*
3670-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
3671+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
3672
3673 Redistribution and use in source and binary forms, with or without
3674 modification, are permitted provided that the following conditions are met:
3675@@ -233,7 +233,7 @@
3676 j=0;
3677 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
3678 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
3679- String alg=new String(K_S, i, j);
3680+ String alg=Util.byte2str(K_S, i, j);
3681 i+=j;
3682
3683 boolean result=false;
3684
3685=== modified file 'src/main/java/com/jcraft/jsch/ForwardedTCPIPDaemon.java'
3686--- src/com/jcraft/jsch/ForwardedTCPIPDaemon.java 2010-06-27 23:17:34 +0000
3687+++ src/main/java/com/jcraft/jsch/ForwardedTCPIPDaemon.java 2012-05-04 10:23:17 +0000
3688@@ -1,6 +1,6 @@
3689 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3690 /*
3691-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
3692+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
3693
3694 Redistribution and use in source and binary forms, with or without
3695 modification, are permitted provided that the following conditions are met:
3696
3697=== modified file 'src/main/java/com/jcraft/jsch/GSSContext.java'
3698--- src/com/jcraft/jsch/GSSContext.java 2010-06-27 23:17:34 +0000
3699+++ src/main/java/com/jcraft/jsch/GSSContext.java 2012-05-04 10:23:17 +0000
3700@@ -1,6 +1,6 @@
3701 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3702 /*
3703-Copyright (c) 2004-2009 ymnk, JCraft,Inc. All rights reserved.
3704+Copyright (c) 2004-2012 ymnk, JCraft,Inc. All rights reserved.
3705
3706 Redistribution and use in source and binary forms, with or without
3707 modification, are permitted provided that the following conditions are met:
3708
3709=== modified file 'src/main/java/com/jcraft/jsch/HASH.java'
3710--- src/com/jcraft/jsch/HASH.java 2010-06-27 23:17:34 +0000
3711+++ src/main/java/com/jcraft/jsch/HASH.java 2012-05-04 10:23:17 +0000
3712@@ -1,6 +1,6 @@
3713 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3714 /*
3715-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
3716+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
3717
3718 Redistribution and use in source and binary forms, with or without
3719 modification, are permitted provided that the following conditions are met:
3720
3721=== modified file 'src/main/java/com/jcraft/jsch/HostKey.java'
3722--- src/com/jcraft/jsch/HostKey.java 2010-06-27 23:17:34 +0000
3723+++ src/main/java/com/jcraft/jsch/HostKey.java 2012-05-04 10:23:17 +0000
3724@@ -1,6 +1,6 @@
3725 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3726 /*
3727-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
3728+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
3729
3730 Redistribution and use in source and binary forms, with or without
3731 modification, are permitted provided that the following conditions are met:
3732@@ -30,8 +30,8 @@
3733 package com.jcraft.jsch;
3734
3735 public class HostKey{
3736- private static final byte[] sshdss="ssh-dss".getBytes();
3737- private static final byte[] sshrsa="ssh-rsa".getBytes();
3738+ private static final byte[] sshdss=Util.str2byte("ssh-dss");
3739+ private static final byte[] sshrsa=Util.str2byte("ssh-rsa");
3740
3741 protected static final int GUESS=0;
3742 public static final int SSHDSS=1;
3743@@ -61,12 +61,12 @@
3744
3745 public String getHost(){ return host; }
3746 public String getType(){
3747- if(type==SSHDSS){ return new String(sshdss); }
3748- if(type==SSHRSA){ return new String(sshrsa);}
3749+ if(type==SSHDSS){ return Util.byte2str(sshdss); }
3750+ if(type==SSHRSA){ return Util.byte2str(sshrsa);}
3751 return "UNKNOWN";
3752 }
3753 public String getKey(){
3754- return new String(Util.toBase64(key, 0, key.length));
3755+ return Util.byte2str(Util.toBase64(key, 0, key.length));
3756 }
3757 public String getFingerPrint(JSch jsch){
3758 HASH hash=null;
3759
3760=== modified file 'src/main/java/com/jcraft/jsch/HostKeyRepository.java'
3761--- src/com/jcraft/jsch/HostKeyRepository.java 2010-06-27 23:17:34 +0000
3762+++ src/main/java/com/jcraft/jsch/HostKeyRepository.java 2012-05-04 10:23:17 +0000
3763@@ -1,6 +1,6 @@
3764 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3765 /*
3766-Copyright (c) 2004-2009 ymnk, JCraft,Inc. All rights reserved.
3767+Copyright (c) 2004-2012 ymnk, JCraft,Inc. All rights reserved.
3768
3769 Redistribution and use in source and binary forms, with or without
3770 modification, are permitted provided that the following conditions are met:
3771
3772=== modified file 'src/main/java/com/jcraft/jsch/IO.java'
3773--- src/com/jcraft/jsch/IO.java 2010-06-27 23:17:34 +0000
3774+++ src/main/java/com/jcraft/jsch/IO.java 2012-05-04 10:23:17 +0000
3775@@ -1,6 +1,6 @@
3776 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3777 /*
3778-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
3779+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
3780
3781 Redistribution and use in source and binary forms, with or without
3782 modification, are permitted provided that the following conditions are met:
3783
3784=== modified file 'src/main/java/com/jcraft/jsch/Identity.java'
3785--- src/com/jcraft/jsch/Identity.java 2010-06-27 23:17:34 +0000
3786+++ src/main/java/com/jcraft/jsch/Identity.java 2012-05-04 10:23:17 +0000
3787@@ -1,6 +1,6 @@
3788 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3789 /*
3790-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
3791+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
3792
3793 Redistribution and use in source and binary forms, with or without
3794 modification, are permitted provided that the following conditions are met:
3795
3796=== modified file 'src/main/java/com/jcraft/jsch/IdentityFile.java'
3797--- src/com/jcraft/jsch/IdentityFile.java 2010-06-27 23:17:34 +0000
3798+++ src/main/java/com/jcraft/jsch/IdentityFile.java 2012-05-04 10:23:17 +0000
3799@@ -1,6 +1,6 @@
3800 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3801 /*
3802-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
3803+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
3804
3805 Redistribution and use in source and binary forms, with or without
3806 modification, are permitted provided that the following conditions are met:
3807@@ -142,6 +142,47 @@
3808 private IdentityFile(String name, byte[] prvkey, byte[] pubkey, JSch jsch) throws JSchException{
3809 this.identity=name;
3810 this.jsch=jsch;
3811+
3812+ // prvkey from "ssh-add" command on the remote.
3813+ if(pubkey==null &&
3814+ prvkey!=null &&
3815+ (prvkey.length>11 &&
3816+ prvkey[0]==0 && prvkey[1]==0 && prvkey[2]==0 && prvkey[3]==7)){
3817+
3818+ Buffer buf=new Buffer(prvkey);
3819+ String _type = new String(buf.getString()); // ssh-rsa
3820+
3821+ if(_type.equals("ssh-rsa")){
3822+ type=RSA;
3823+ n_array=buf.getString();
3824+ e_array=buf.getString();
3825+ d_array=buf.getString();
3826+ buf.getString();
3827+ buf.getString();
3828+ buf.getString();
3829+ this.identity += new String(buf.getString());
3830+ }
3831+ else if(_type.equals("ssh-dss")){
3832+ type=DSS;
3833+ P_array=buf.getString();
3834+ Q_array=buf.getString();
3835+ G_array=buf.getString();
3836+ pub_array=buf.getString();
3837+ prv_array=buf.getString();
3838+ this.identity += new String(buf.getString());
3839+ }
3840+ else{
3841+ throw new JSchException("privatekey: invalid key "+new String(prvkey, 4, 7));
3842+ }
3843+ encoded_data=prvkey;
3844+ encrypted=false;
3845+ keytype=OPENSSH;
3846+ return;
3847+ }
3848+
3849+ /* TODO: IdentityFile should use KeyPair.
3850+ * The following logic exists also in KeyPair. It is redundant.
3851+ */
3852 try{
3853 Class c;
3854 c=Class.forName((String)jsch.getConfig("3des-cbc"));
3855@@ -156,8 +197,18 @@
3856 int len=buf.length;
3857
3858 int i=0;
3859- while(i<len){
3860- if(buf[i]=='B'&& buf[i+1]=='E'&& buf[i+2]=='G'&& buf[i+3]=='I'){
3861+
3862+ while(i<len){
3863+ if(buf[i] == '-' && i+4<len &&
3864+ buf[i+1] == '-' && buf[i+2] == '-' &&
3865+ buf[i+3] == '-' && buf[i+4] == '-'){
3866+ break;
3867+ }
3868+ i++;
3869+ }
3870+
3871+ while(i<len){
3872+ if(buf[i]=='B'&& i+3<len && buf[i+1]=='E'&& buf[i+2]=='G'&& buf[i+3]=='I'){
3873 i+=6;
3874 if(buf[i]=='D'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=DSS; }
3875 else if(buf[i]=='R'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=RSA; }
3876@@ -172,7 +223,7 @@
3877 i+=3;
3878 continue;
3879 }
3880- if(buf[i]=='A'&& buf[i+1]=='E'&& buf[i+2]=='S'&& buf[i+3]=='-' &&
3881+ if(buf[i]=='A'&& i+7<len && buf[i+1]=='E'&& buf[i+2]=='S'&& buf[i+3]=='-' &&
3882 buf[i+4]=='2'&& buf[i+5]=='5'&& buf[i+6]=='6'&& buf[i+7]=='-'){
3883 i+=8;
3884 if(Session.checkCipher((String)jsch.getConfig("aes256-cbc"))){
3885@@ -186,7 +237,35 @@
3886 }
3887 continue;
3888 }
3889- if(buf[i]=='C'&& buf[i+1]=='B'&& buf[i+2]=='C'&& buf[i+3]==','){
3890+ if(buf[i]=='A'&& i+7<len && buf[i+1]=='E'&& buf[i+2]=='S'&& buf[i+3]=='-' &&
3891+ buf[i+4]=='1'&& buf[i+5]=='9'&& buf[i+6]=='2'&& buf[i+7]=='-'){
3892+ i+=8;
3893+ if(Session.checkCipher((String)jsch.getConfig("aes192-cbc"))){
3894+ c=Class.forName((String)jsch.getConfig("aes192-cbc"));
3895+ cipher=(Cipher)(c.newInstance());
3896+ key=new byte[cipher.getBlockSize()];
3897+ iv=new byte[cipher.getIVSize()];
3898+ }
3899+ else{
3900+ throw new JSchException("privatekey: aes192-cbc is not available "+identity);
3901+ }
3902+ continue;
3903+ }
3904+ if(buf[i]=='A'&& i+7<len && buf[i+1]=='E'&& buf[i+2]=='S'&& buf[i+3]=='-' &&
3905+ buf[i+4]=='1'&& buf[i+5]=='2'&& buf[i+6]=='8'&& buf[i+7]=='-'){
3906+ i+=8;
3907+ if(Session.checkCipher((String)jsch.getConfig("aes128-cbc"))){
3908+ c=Class.forName((String)jsch.getConfig("aes128-cbc"));
3909+ cipher=(Cipher)(c.newInstance());
3910+ key=new byte[cipher.getBlockSize()];
3911+ iv=new byte[cipher.getIVSize()];
3912+ }
3913+ else{
3914+ throw new JSchException("privatekey: aes128-cbc is not available "+identity);
3915+ }
3916+ continue;
3917+ }
3918+ if(buf[i]=='C'&& i+3<len && buf[i+1]=='B'&& buf[i+2]=='C'&& buf[i+3]==','){
3919 i+=4;
3920 for(int ii=0; ii<iv.length; ii++){
3921 iv[ii]=(byte)(((a2b(buf[i++])<<4)&0xf0)+
3922@@ -194,19 +273,18 @@
3923 }
3924 continue;
3925 }
3926- if(buf[i]==0x0d &&
3927- i+1<buf.length && buf[i+1]==0x0a){
3928+ if(buf[i]==0x0d && i+1<len && buf[i+1]==0x0a){
3929 i++;
3930 continue;
3931 }
3932- if(buf[i]==0x0a && i+1<buf.length){
3933+ if(buf[i]==0x0a && i+1<len){
3934 if(buf[i+1]==0x0a){ i+=2; break; }
3935 if(buf[i+1]==0x0d &&
3936- i+2<buf.length && buf[i+2]==0x0a){
3937+ i+2<len && buf[i+2]==0x0a){
3938 i+=3; break;
3939 }
3940 boolean inheader=false;
3941- for(int j=i+1; j<buf.length; j++){
3942+ for(int j=i+1; j<len; j++){
3943 if(buf[j]==0x0a) break;
3944 //if(buf[j]==0x0d) break;
3945 if(buf[j]==':'){inheader=true; break;}
3946@@ -254,7 +332,7 @@
3947 byte[]_type=_buf.getString();
3948 //System.err.println("type: "+new String(_type));
3949 byte[] _cipher=_buf.getString();
3950- String cipher=new String(_cipher);
3951+ String cipher=Util.byte2str(_cipher);
3952 //System.err.println("cipher: "+cipher);
3953 if(cipher.equals("3des-cbc")){
3954 _buf.getInt();
3955@@ -421,7 +499,7 @@
3956 Buffer buf=new Buffer("ssh-rsa".length()+4+
3957 e_array.length+4+
3958 n_array.length+4);
3959- buf.putString("ssh-rsa".getBytes());
3960+ buf.putString(Util.str2byte("ssh-rsa"));
3961 buf.putString(e_array);
3962 buf.putString(n_array);
3963 return buf.buffer;
3964@@ -434,7 +512,7 @@
3965 Q_array.length+4+
3966 G_array.length+4+
3967 pub_array.length+4);
3968- buf.putString("ssh-dss".getBytes());
3969+ buf.putString(Util.str2byte("ssh-dss"));
3970 buf.putString(P_array);
3971 buf.putString(Q_array);
3972 buf.putString(G_array);
3973@@ -459,7 +537,7 @@
3974 byte[] sig = rsa.sign();
3975 Buffer buf=new Buffer("ssh-rsa".length()+4+
3976 sig.length+4);
3977- buf.putString("ssh-rsa".getBytes());
3978+ buf.putString(Util.str2byte("ssh-rsa"));
3979 buf.putString(sig);
3980 return buf.buffer;
3981 }
3982@@ -502,7 +580,7 @@
3983 byte[] sig = dsa.sign();
3984 Buffer buf=new Buffer("ssh-dss".length()+4+
3985 sig.length+4);
3986- buf.putString("ssh-dss".getBytes());
3987+ buf.putString(Util.str2byte("ssh-dss"));
3988 buf.putString(sig);
3989 return buf.buffer;
3990 }
3991
3992=== added file 'src/main/java/com/jcraft/jsch/IdentityRepository.java'
3993--- src/main/java/com/jcraft/jsch/IdentityRepository.java 1970-01-01 00:00:00 +0000
3994+++ src/main/java/com/jcraft/jsch/IdentityRepository.java 2012-05-04 10:23:17 +0000
3995@@ -0,0 +1,44 @@
3996+/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3997+/*
3998+Copyright (c) 2012 ymnk, JCraft,Inc. All rights reserved.
3999+
4000+Redistribution and use in source and binary forms, with or without
4001+modification, are permitted provided that the following conditions are met:
4002+
4003+ 1. Redistributions of source code must retain the above copyright notice,
4004+ this list of conditions and the following disclaimer.
4005+
4006+ 2. Redistributions in binary form must reproduce the above copyright
4007+ notice, this list of conditions and the following disclaimer in
4008+ the documentation and/or other materials provided with the distribution.
4009+
4010+ 3. The names of the authors may not be used to endorse or promote products
4011+ derived from this software without specific prior written permission.
4012+
4013+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
4014+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
4015+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
4016+INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
4017+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
4018+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
4019+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
4020+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4021+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
4022+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4023+*/
4024+
4025+package com.jcraft.jsch;
4026+
4027+import java.util.Vector;
4028+
4029+public interface IdentityRepository {
4030+ public static final int UNAVAILABLE=0;
4031+ public static final int NOTRUNNING=1;
4032+ public static final int RUNNING=2;
4033+ public String getName();
4034+ public int getStatus();
4035+ public Vector getIdentities();
4036+ public boolean add(byte[] identity);
4037+ public boolean remove(byte[] blob);
4038+ public void removeAll();
4039+}
4040
4041=== modified file 'src/main/java/com/jcraft/jsch/JSch.java'
4042--- src/com/jcraft/jsch/JSch.java 2010-06-27 23:17:34 +0000
4043+++ src/main/java/com/jcraft/jsch/JSch.java 2012-05-04 10:23:17 +0000
4044@@ -1,6 +1,6 @@
4045 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
4046 /*
4047-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
4048+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
4049
4050 Redistribution and use in source and binary forms, with or without
4051 modification, are permitted provided that the following conditions are met:
4052@@ -33,12 +33,15 @@
4053 import java.util.Vector;
4054
4055 public class JSch{
4056+ /**
4057+ * The version number.
4058+ */
4059+ public static final String VERSION = "0.1.48";
4060+
4061 static java.util.Hashtable config=new java.util.Hashtable();
4062 static{
4063-// config.put("kex", "diffie-hellman-group-exchange-sha1");
4064- config.put("kex", "diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1");
4065+ config.put("kex", "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1");
4066 config.put("server_host_key", "ssh-rsa,ssh-dss");
4067-// config.put("server_host_key", "ssh-dss,ssh-rsa");
4068
4069 config.put("cipher.s2c",
4070 "aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-cbc,aes256-cbc");
4071@@ -48,9 +51,7 @@
4072 config.put("mac.s2c", "hmac-md5,hmac-sha1,hmac-sha1-96,hmac-md5-96");
4073 config.put("mac.c2s", "hmac-md5,hmac-sha1,hmac-sha1-96,hmac-md5-96");
4074 config.put("compression.s2c", "none");
4075- // config.put("compression.s2c", "zlib@openssh.com,zlib,none");
4076 config.put("compression.c2s", "none");
4077- // config.put("compression.c2s", "zlib@openssh.com,zlib,none");
4078
4079 config.put("lang.s2c", "");
4080 config.put("lang.c2s", "");
4081@@ -61,6 +62,8 @@
4082 "com.jcraft.jsch.DHGEX");
4083 config.put("diffie-hellman-group1-sha1",
4084 "com.jcraft.jsch.DHG1");
4085+ config.put("diffie-hellman-group14-sha1",
4086+ "com.jcraft.jsch.DHG14");
4087
4088 config.put("dh", "com.jcraft.jsch.jce.DH");
4089 config.put("3des-cbc", "com.jcraft.jsch.jce.TripleDESCBC");
4090@@ -103,13 +106,44 @@
4091
4092 config.put("StrictHostKeyChecking", "ask");
4093 config.put("HashKnownHosts", "no");
4094- //config.put("HashKnownHosts", "yes");
4095+
4096 config.put("PreferredAuthentications", "gssapi-with-mic,publickey,keyboard-interactive,password");
4097
4098 config.put("CheckCiphers", "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256");
4099- }
4100- java.util.Vector pool=new java.util.Vector();
4101- java.util.Vector identities=new java.util.Vector();
4102+ config.put("CheckKexes", "diffie-hellman-group14-sha1");
4103+
4104+ config.put("MaxAuthTries", "6");
4105+ }
4106+
4107+ private java.util.Vector sessionPool = new java.util.Vector();
4108+
4109+ private IdentityRepository defaultIdentityRepository =
4110+ new LocalIdentityRepository(this);
4111+
4112+ private IdentityRepository identityRepository = defaultIdentityRepository;
4113+
4114+ /**
4115+ * Sets the <code>identityRepository</code>, which will be referred
4116+ * in the public key authentication.
4117+ *
4118+ * @param identityRepository if <code>null</code> is given,
4119+ * the default repository, which usually refers to ~/.ssh/, will be used.
4120+ *
4121+ * @see #getIdentityRepository()
4122+ */
4123+ public synchronized void setIdentityRepository(IdentityRepository identityRepository){
4124+ if(identityRepository == null){
4125+ this.identityRepository = defaultIdentityRepository;
4126+ }
4127+ else{
4128+ this.identityRepository = identityRepository;
4129+ }
4130+ }
4131+
4132+ synchronized IdentityRepository getIdentityRepository(){
4133+ return this.identityRepository;
4134+ }
4135+
4136 private HostKeyRepository known_hosts=null;
4137
4138 private static final Logger DEVNULL=new Logger(){
4139@@ -134,7 +168,47 @@
4140
4141 }
4142
4143- public Session getSession(String username, String host) throws JSchException { return getSession(username, host, 22); }
4144+ /**
4145+ * Instantiates the <code>Session</code> object with
4146+ * <code>username</code> and <code>host</code>.
4147+ * The TCP port 22 will be used in making the connection.
4148+ * Note that the TCP connection must not be established
4149+ * until Session#connect().
4150+ *
4151+ * @param username user name
4152+ * @param host hostname
4153+ *
4154+ * @throws JSchException
4155+ * if <code>username</code> or <code>host</code> are invalid.
4156+ *
4157+ * @return the instance of <code>Session</code> class.
4158+ *
4159+ * @see #getSession(String username, String host, int port)
4160+ * @see com.jcraft.jsch.Session
4161+ */
4162+ public Session getSession(String username, String host)
4163+ throws JSchException {
4164+ return getSession(username, host, 22);
4165+ }
4166+
4167+ /**
4168+ * Instantiates the <code>Session</code> object with given
4169+ * <code>username</code>, <code>host</code> and <code>port</code>.
4170+ * Note that the TCP connection must not be established
4171+ * until Session#connect().
4172+ *
4173+ * @param username user name
4174+ * @param host hostname
4175+ * @param post port number
4176+ *
4177+ * @throws JSchException
4178+ * if <code>username</code> or <code>host</code> are invalid.
4179+ *
4180+ * @return the instance of <code>Session</code> class.
4181+ *
4182+ * @see #getSession(String username, String host, int port)
4183+ * @see com.jcraft.jsch.Session
4184+ */
4185 public Session getSession(String username, String host, int port) throws JSchException {
4186 if(username==null){
4187 throw new JSchException("username must not be null.");
4188@@ -146,25 +220,44 @@
4189 s.setUserName(username);
4190 s.setHost(host);
4191 s.setPort(port);
4192- //pool.addElement(s);
4193 return s;
4194 }
4195
4196 protected void addSession(Session session){
4197- synchronized(pool){
4198- pool.addElement(session);
4199+ synchronized(sessionPool){
4200+ sessionPool.addElement(session);
4201 }
4202 }
4203
4204 protected boolean removeSession(Session session){
4205- synchronized(pool){
4206- return pool.remove(session);
4207+ synchronized(sessionPool){
4208+ return sessionPool.remove(session);
4209 }
4210 }
4211+
4212+ /**
4213+ * Sets the hostkey repository.
4214+ *
4215+ * @param hkrepo
4216+ *
4217+ * @see com.jcraft.jsch.HostKeyRepository
4218+ * @see com.jcraft.jsch.KnownHosts
4219+ */
4220 public void setHostKeyRepository(HostKeyRepository hkrepo){
4221 known_hosts=hkrepo;
4222 }
4223
4224+ /**
4225+ * Sets the instance of <code>KnownHosts</code>, which refers
4226+ * to <code>filename</code>.
4227+ *
4228+ * @param filename filename of known_hosts file.
4229+ *
4230+ * @throws JSchException
4231+ * if the given filename is invalid.
4232+ *
4233+ * @see com.jcraft.jsch.KnownHosts
4234+ */
4235 public void setKnownHosts(String filename) throws JSchException{
4236 if(known_hosts==null) known_hosts=new KnownHosts(this);
4237 if(known_hosts instanceof KnownHosts){
4238@@ -174,6 +267,17 @@
4239 }
4240 }
4241
4242+ /**
4243+ * Sets the instance of <code>KnownHosts</code> generated with
4244+ * <code>stream</code>.
4245+ *
4246+ * @param stream the instance of InputStream from known_hosts file.
4247+ *
4248+ * @throws JSchException
4249+ * if an I/O error occurs.
4250+ *
4251+ * @see com.jcraft.jsch.KnownHosts
4252+ */
4253 public void setKnownHosts(InputStream stream) throws JSchException{
4254 if(known_hosts==null) known_hosts=new KnownHosts(this);
4255 if(known_hosts instanceof KnownHosts){
4256@@ -183,15 +287,47 @@
4257 }
4258 }
4259
4260+ /**
4261+ * Returns the current hostkey repository.
4262+ * By the default, this method will the instance of <code>KnownHosts</code>.
4263+ *
4264+ * @return current hostkey repository.
4265+ *
4266+ * @see com.jcraft.jsch.HostKeyRepository
4267+ * @see com.jcraft.jsch.KnownHosts
4268+ */
4269 public HostKeyRepository getHostKeyRepository(){
4270 if(known_hosts==null) known_hosts=new KnownHosts(this);
4271 return known_hosts;
4272 }
4273
4274+ /**
4275+ * Sets the private key, which will be referred in
4276+ * the public key authentication.
4277+ *
4278+ * @param prvkey filename of the private key.
4279+ *
4280+ * @throws JSchException if <code>prvkey</code> is invalid.
4281+ *
4282+ * @see #addIdentity(String prvkey, String passphrase)
4283+ */
4284 public void addIdentity(String prvkey) throws JSchException{
4285 addIdentity(prvkey, (byte[])null);
4286 }
4287
4288+ /**
4289+ * Sets the private key, which will be referred in
4290+ * the public key authentication.
4291+ * Before registering it into identityRepository,
4292+ * it will be deciphered with <code>passphrase</code>.
4293+ *
4294+ * @param prvkey filename of the private key.
4295+ * @param passphrase passphrase for <code>prvkey</code>.
4296+ *
4297+ * @throws JSchException if <code>passphrase</code> is not right.
4298+ *
4299+ * @see #addIdentity(String prvkey, byte[] passphrase)
4300+ */
4301 public void addIdentity(String prvkey, String passphrase) throws JSchException{
4302 byte[] _passphrase=null;
4303 if(passphrase!=null){
4304@@ -202,20 +338,70 @@
4305 Util.bzero(_passphrase);
4306 }
4307
4308+ /**
4309+ * Sets the private key, which will be referred in
4310+ * the public key authentication.
4311+ * Before registering it into identityRepository,
4312+ * it will be deciphered with <code>passphrase</code>.
4313+ *
4314+ * @param prvkey filename of the private key.
4315+ * @param passphrase passphrase for <code>prvkey</code>.
4316+ *
4317+ * @throws JSchException if <code>passphrase</code> is not right.
4318+ *
4319+ * @see #addIdentity(String prvkey, String pubkey, byte[] passphrase)
4320+ */
4321 public void addIdentity(String prvkey, byte[] passphrase) throws JSchException{
4322 Identity identity=IdentityFile.newInstance(prvkey, null, this);
4323 addIdentity(identity, passphrase);
4324 }
4325+
4326+ /**
4327+ * Sets the private key, which will be referred in
4328+ * the public key authentication.
4329+ * Before registering it into identityRepository,
4330+ * it will be deciphered with <code>passphrase</code>.
4331+ *
4332+ * @param prvkey filename of the private key.
4333+ * @param pubkey filename of the public key.
4334+ * @param passphrase passphrase for <code>prvkey</code>.
4335+ *
4336+ * @throws JSchException if <code>passphrase</code> is not right.
4337+ */
4338 public void addIdentity(String prvkey, String pubkey, byte[] passphrase) throws JSchException{
4339 Identity identity=IdentityFile.newInstance(prvkey, pubkey, this);
4340 addIdentity(identity, passphrase);
4341 }
4342
4343+ /**
4344+ * Sets the private key, which will be referred in
4345+ * the public key authentication.
4346+ * Before registering it into identityRepository,
4347+ * it will be deciphered with <code>passphrase</code>.
4348+ *
4349+ * @param name name of the identity to be used to
4350+ retrieve it in the identityRepository.
4351+ * @param prvkey private key in byte array.
4352+ * @param pubkey public key in byte array.
4353+ * @param passphrase passphrase for <code>prvkey</code>.
4354+ *
4355+ */
4356 public void addIdentity(String name, byte[]prvkey, byte[]pubkey, byte[] passphrase) throws JSchException{
4357 Identity identity=IdentityFile.newInstance(name, prvkey, pubkey, this);
4358 addIdentity(identity, passphrase);
4359 }
4360
4361+ /**
4362+ * Sets the private key, which will be referred in
4363+ * the public key authentication.
4364+ * Before registering it into identityRepository,
4365+ * it will be deciphered with <code>passphrase</code>.
4366+ *
4367+ * @param identity private key.
4368+ * @param passphrase passphrase for <code>identity</code>.
4369+ *
4370+ * @throws JSchException if <code>passphrase</code> is not right.
4371+ */
4372 public void addIdentity(Identity identity, byte[] passphrase) throws JSchException{
4373 if(passphrase!=null){
4374 try{
4375@@ -228,53 +414,83 @@
4376 Util.bzero(passphrase);
4377 }
4378 }
4379- synchronized(identities){
4380- if(!identities.contains(identity)){
4381- identities.addElement(identity);
4382- }
4383+
4384+ if(identityRepository instanceof LocalIdentityRepository){
4385+ ((LocalIdentityRepository)identityRepository).add(identity);
4386+ }
4387+ else {
4388+ // TODO
4389 }
4390 }
4391
4392+ /**
4393+ * @deprecated use #removeIdentity(Identity identity)
4394+ */
4395 public void removeIdentity(String name) throws JSchException{
4396- synchronized(identities){
4397- for(int i=0; i<identities.size(); i++){
4398- Identity identity=(Identity)(identities.elementAt(i));
4399- if(!identity.getName().equals(name))
4400- continue;
4401- identities.removeElement(identity);
4402- identity.clear();
4403- break;
4404- }
4405+ Vector identities = identityRepository.getIdentities();
4406+ for(int i=0; i<identities.size(); i++){
4407+ Identity identity=(Identity)(identities.elementAt(i));
4408+ if(!identity.getName().equals(name))
4409+ continue;
4410+ identityRepository.remove(identity.getPublicKeyBlob());
4411+ break;
4412 }
4413 }
4414
4415+ /**
4416+ * Removes the identity from identityRepository.
4417+ *
4418+ * @param identity the indentity to be removed.
4419+ *
4420+ * @throws JSchException if <code>identity</code> is invalid.
4421+ */
4422+ public void removeIdentity(Identity identity) throws JSchException{
4423+ identityRepository.remove(identity.getPublicKeyBlob());
4424+ }
4425+
4426+ /**
4427+ * Lists names of identities included in the identityRepository.
4428+ *
4429+ * @return names of identities
4430+ *
4431+ * @throws JSchException if identityReposory has problems.
4432+ */
4433 public Vector getIdentityNames() throws JSchException{
4434 Vector foo=new Vector();
4435- synchronized(identities){
4436- for(int i=0; i<identities.size(); i++){
4437- Identity identity=(Identity)(identities.elementAt(i));
4438- foo.addElement(identity.getName());
4439- }
4440+ Vector identities = identityRepository.getIdentities();
4441+ for(int i=0; i<identities.size(); i++){
4442+ Identity identity=(Identity)(identities.elementAt(i));
4443+ foo.addElement(identity.getName());
4444 }
4445 return foo;
4446 }
4447
4448+ /**
4449+ * Removes all identities from identityRepository.
4450+ *
4451+ * @throws JSchException if identityReposory has problems.
4452+ */
4453 public void removeAllIdentity() throws JSchException{
4454- synchronized(identities){
4455- Vector foo=getIdentityNames();
4456- for(int i=0; i<foo.size(); i++){
4457- String name=((String)foo.elementAt(i));
4458- removeIdentity(name);
4459- }
4460- }
4461+ identityRepository.removeAll();
4462 }
4463
4464+ /**
4465+ * Returns the config value for the specified key.
4466+ *
4467+ * @param key key for the configuration.
4468+ * @return config value
4469+ */
4470 public static String getConfig(String key){
4471 synchronized(config){
4472 return (String)(config.get(key));
4473 }
4474 }
4475
4476+ /**
4477+ * Sets or Overrides the configuration.
4478+ *
4479+ * @param newconf configurations
4480+ */
4481 public static void setConfig(java.util.Hashtable newconf){
4482 synchronized(config){
4483 for(java.util.Enumeration e=newconf.keys() ; e.hasMoreElements() ;) {
4484@@ -284,14 +500,28 @@
4485 }
4486 }
4487
4488+ /**
4489+ * Sets or Overrides the configuration.
4490+ *
4491+ * @param key key for the configuration
4492+ * @param value value for the configuration
4493+ */
4494 public static void setConfig(String key, String value){
4495 config.put(key, value);
4496 }
4497
4498+ /**
4499+ * Sets the logger
4500+ *
4501+ * @param logger logger
4502+ *
4503+ * @see com.jcraft.jsch.Logger
4504+ */
4505 public static void setLogger(Logger logger){
4506- if(logger==null) JSch.logger=DEVNULL;
4507+ if(logger==null) logger=DEVNULL;
4508 JSch.logger=logger;
4509 }
4510+
4511 static Logger getLogger(){
4512 return logger;
4513 }
4514
4515=== modified file 'src/main/java/com/jcraft/jsch/JSchAuthCancelException.java'
4516--- src/com/jcraft/jsch/JSchAuthCancelException.java 2010-06-27 23:17:34 +0000
4517+++ src/main/java/com/jcraft/jsch/JSchAuthCancelException.java 2012-05-04 10:23:17 +0000
4518@@ -1,6 +1,6 @@
4519 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
4520 /*
4521-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
4522+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
4523
4524 Redistribution and use in source and binary forms, with or without
4525 modification, are permitted provided that the following conditions are met:
4526
4527=== modified file 'src/main/java/com/jcraft/jsch/JSchException.java'
4528--- src/com/jcraft/jsch/JSchException.java 2010-06-27 23:17:34 +0000
4529+++ src/main/java/com/jcraft/jsch/JSchException.java 2012-05-04 10:23:17 +0000
4530@@ -1,6 +1,6 @@
4531 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
4532 /*
4533-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
4534+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
4535
4536 Redistribution and use in source and binary forms, with or without
4537 modification, are permitted provided that the following conditions are met:
4538
4539=== modified file 'src/main/java/com/jcraft/jsch/JSchPartialAuthException.java'
4540--- src/com/jcraft/jsch/JSchPartialAuthException.java 2010-06-27 23:17:34 +0000
4541+++ src/main/java/com/jcraft/jsch/JSchPartialAuthException.java 2012-05-04 10:23:17 +0000
4542@@ -1,6 +1,6 @@
4543 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
4544 /*
4545-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
4546+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
4547
4548 Redistribution and use in source and binary forms, with or without
4549 modification, are permitted provided that the following conditions are met:
4550
4551=== modified file 'src/main/java/com/jcraft/jsch/KeyExchange.java'
4552--- src/com/jcraft/jsch/KeyExchange.java 2010-06-27 23:17:34 +0000
4553+++ src/main/java/com/jcraft/jsch/KeyExchange.java 2012-05-04 10:23:17 +0000
4554@@ -1,6 +1,6 @@
4555 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
4556 /*
4557-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
4558+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
4559
4560 Redistribution and use in source and binary forms, with or without
4561 modification, are permitted provided that the following conditions are met:
4562@@ -85,36 +85,41 @@
4563 */
4564
4565 protected static String[] guess(byte[]I_S, byte[]I_C){
4566-//System.err.println("guess: ");
4567 String[] guess=new String[PROPOSAL_MAX];
4568 Buffer sb=new Buffer(I_S); sb.setOffSet(17);
4569 Buffer cb=new Buffer(I_C); cb.setOffSet(17);
4570
4571+ if(JSch.getLogger().isEnabled(Logger.INFO)){
4572+ for(int i=0; i<PROPOSAL_MAX; i++){
4573+ JSch.getLogger().log(Logger.INFO,
4574+ "kex: server: "+Util.byte2str(sb.getString()));
4575+ }
4576+ for(int i=0; i<PROPOSAL_MAX; i++){
4577+ JSch.getLogger().log(Logger.INFO,
4578+ "kex: client: "+Util.byte2str(cb.getString()));
4579+ }
4580+ sb.setOffSet(17);
4581+ cb.setOffSet(17);
4582+ }
4583+
4584 for(int i=0; i<PROPOSAL_MAX; i++){
4585 byte[] sp=sb.getString(); // server proposal
4586 byte[] cp=cb.getString(); // client proposal
4587-
4588-//System.err.println("server-proposal: |"+new String(sp)+"|");
4589-//System.err.println("client-proposal: |"+new String(cp)+"|");
4590-
4591 int j=0;
4592 int k=0;
4593-//System.err.println(new String(cp));
4594+
4595 loop:
4596 while(j<cp.length){
4597 while(j<cp.length && cp[j]!=',')j++;
4598 if(k==j) return null;
4599- String algorithm=new String(cp, k, j-k);
4600-//System.err.println("algorithm: "+algorithm);
4601+ String algorithm=Util.byte2str(cp, k, j-k);
4602 int l=0;
4603 int m=0;
4604 while(l<sp.length){
4605 while(l<sp.length && sp[l]!=',')l++;
4606 if(m==l) return null;
4607-//System.err.println(" "+new String(sp, m, l-m));
4608- if(algorithm.equals(new String(sp, m, l-m))){
4609+ if(algorithm.equals(Util.byte2str(sp, m, l-m))){
4610 guess[i]=algorithm;
4611-//System.err.println(" "+algorithm);
4612 break loop;
4613 }
4614 l++;
4615@@ -127,7 +132,6 @@
4616 guess[i]="";
4617 }
4618 else if(guess[i]==null){
4619-//System.err.println(" fail");
4620 return null;
4621 }
4622 }
4623@@ -145,10 +149,6 @@
4624 " "+guess[PROPOSAL_COMP_ALGS_CTOS]);
4625 }
4626
4627-// for(int i=0; i<PROPOSAL_MAX; i++){
4628-// System.err.println("guess: ["+guess[i]+"]");
4629-// }
4630-
4631 return guess;
4632 }
4633
4634
4635=== modified file 'src/main/java/com/jcraft/jsch/KeyPair.java'
4636--- src/com/jcraft/jsch/KeyPair.java 2010-06-27 23:17:34 +0000
4637+++ src/main/java/com/jcraft/jsch/KeyPair.java 2012-05-04 10:23:17 +0000
4638@@ -1,6 +1,6 @@
4639 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
4640 /*
4641-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
4642+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
4643
4644 Redistribution and use in source and binary forms, with or without
4645 modification, are permitted provided that the following conditions are met:
4646@@ -43,7 +43,7 @@
4647 static final int VENDOR_FSECURE=1;
4648 int vendor=VENDOR_OPENSSH;
4649
4650- private static final byte[] cr="\n".getBytes();
4651+ private static final byte[] cr=Util.str2byte("\n");
4652
4653 public static KeyPair genKeyPair(JSch jsch, int type) throws JSchException{
4654 return genKeyPair(jsch, type, 1024);
4655@@ -64,6 +64,11 @@
4656 abstract byte[] getEnd();
4657 abstract int getKeySize();
4658
4659+ public String getPublicKeyComment(){
4660+ return publicKeyComment;
4661+ }
4662+ private String publicKeyComment = "";
4663+
4664 JSch jsch=null;
4665 private Cipher cipher;
4666 private HASH hash;
4667@@ -75,8 +80,8 @@
4668 this.jsch=jsch;
4669 }
4670
4671- static byte[][] header={"Proc-Type: 4,ENCRYPTED".getBytes(),
4672- "DEK-Info: DES-EDE3-CBC,".getBytes()};
4673+ static byte[][] header={Util.str2byte("Proc-Type: 4,ENCRYPTED"),
4674+ Util.str2byte("DEK-Info: DES-EDE3-CBC,")};
4675
4676 abstract byte[] getPrivateKey();
4677
4678@@ -120,7 +125,7 @@
4679 }
4680 }
4681
4682- private static byte[] space=" ".getBytes();
4683+ private static byte[] space=Util.str2byte(" ");
4684
4685 abstract byte[] getKeyTypeName();
4686 public abstract int getKeyType();
4687@@ -133,7 +138,7 @@
4688 try{
4689 out.write(getKeyTypeName()); out.write(space);
4690 out.write(pub, 0, pub.length); out.write(space);
4691- out.write(comment.getBytes());
4692+ out.write(Util.str2byte(comment));
4693 out.write(cr);
4694 }
4695 catch(Exception e){
4696@@ -150,8 +155,8 @@
4697 byte[] pubblob=getPublicKeyBlob();
4698 byte[] pub=Util.toBase64(pubblob, 0, pubblob.length);
4699 try{
4700- out.write("---- BEGIN SSH2 PUBLIC KEY ----".getBytes()); out.write(cr);
4701- out.write(("Comment: \""+comment+"\"").getBytes()); out.write(cr);
4702+ out.write(Util.str2byte("---- BEGIN SSH2 PUBLIC KEY ----")); out.write(cr);
4703+ out.write(Util.str2byte("Comment: \""+comment+"\"")); out.write(cr);
4704 int index=0;
4705 while(index<pub.length){
4706 int len=70;
4707@@ -159,7 +164,7 @@
4708 out.write(pub, index, len); out.write(cr);
4709 index+=len;
4710 }
4711- out.write("---- END SSH2 PUBLIC KEY ----".getBytes()); out.write(cr);
4712+ out.write(Util.str2byte("---- END SSH2 PUBLIC KEY ----")); out.write(cr);
4713 }
4714 catch(Exception e){
4715 }
4716@@ -335,7 +340,7 @@
4717 for(int index=0; index+hsize<=hn.length;){
4718 if(tmp!=null){ hash.update(tmp, 0, tmp.length); }
4719 hash.update(passphrase, 0, passphrase.length);
4720- hash.update(iv, 0, iv.length);
4721+ hash.update(iv, 0, iv.length > 8 ? 8: iv.length);
4722 tmp=hash.digest();
4723 System.arraycopy(tmp, 0, hn, index, tmp.length);
4724 index+=tmp.length;
4725@@ -420,6 +425,8 @@
4726
4727 int type=ERROR;
4728 int vendor=VENDOR_OPENSSH;
4729+ String publicKeyComment = "";
4730+ Cipher cipher=null;
4731
4732 try{
4733 File file=new File(prvkey);
4734@@ -437,7 +444,16 @@
4735 int i=0;
4736
4737 while(i<len){
4738- if(buf[i]=='B'&& buf[i+1]=='E'&& buf[i+2]=='G'&& buf[i+3]=='I'){
4739+ if(buf[i] == '-' && i+4<len &&
4740+ buf[i+1] == '-' && buf[i+2] == '-' &&
4741+ buf[i+3] == '-' && buf[i+4] == '-'){
4742+ break;
4743+ }
4744+ i++;
4745+ }
4746+
4747+ while(i<len){
4748+ if(buf[i]=='B'&& i+3<len && buf[i+1]=='E'&& buf[i+2]=='G'&& buf[i+3]=='I'){
4749 i+=6;
4750 if(buf[i]=='D'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=DSA; }
4751 else if(buf[i]=='R'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=RSA; }
4752@@ -446,21 +462,61 @@
4753 vendor=VENDOR_FSECURE;
4754 }
4755 else{
4756- //System.err.println("invalid format: "+identity);
4757 throw new JSchException("invalid privatekey: "+prvkey);
4758 }
4759 i+=3;
4760 continue;
4761 }
4762- if(buf[i]=='C'&& buf[i+1]=='B'&& buf[i+2]=='C'&& buf[i+3]==','){
4763+ if(buf[i]=='A'&& i+7<len && buf[i+1]=='E'&& buf[i+2]=='S'&& buf[i+3]=='-' &&
4764+ buf[i+4]=='2'&& buf[i+5]=='5'&& buf[i+6]=='6'&& buf[i+7]=='-'){
4765+ i+=8;
4766+ if(Session.checkCipher((String)jsch.getConfig("aes256-cbc"))){
4767+ Class c=Class.forName((String)jsch.getConfig("aes256-cbc"));
4768+ cipher=(Cipher)(c.newInstance());
4769+ // key=new byte[cipher.getBlockSize()];
4770+ iv=new byte[cipher.getIVSize()];
4771+ }
4772+ else{
4773+ throw new JSchException("privatekey: aes256-cbc is not available "+prvkey);
4774+ }
4775+ continue;
4776+ }
4777+ if(buf[i]=='A'&& i+7<len && buf[i+1]=='E'&& buf[i+2]=='S'&& buf[i+3]=='-' &&
4778+ buf[i+4]=='1'&& buf[i+5]=='9'&& buf[i+6]=='2'&& buf[i+7]=='-'){
4779+ i+=8;
4780+ if(Session.checkCipher((String)jsch.getConfig("aes192-cbc"))){
4781+ Class c=Class.forName((String)jsch.getConfig("aes192-cbc"));
4782+ cipher=(Cipher)(c.newInstance());
4783+ // key=new byte[cipher.getBlockSize()];
4784+ iv=new byte[cipher.getIVSize()];
4785+ }
4786+ else{
4787+ throw new JSchException("privatekey: aes192-cbc is not available "+prvkey);
4788+ }
4789+ continue;
4790+ }
4791+ if(buf[i]=='A'&& i+7<len && buf[i+1]=='E'&& buf[i+2]=='S'&& buf[i+3]=='-' &&
4792+ buf[i+4]=='1'&& buf[i+5]=='2'&& buf[i+6]=='8'&& buf[i+7]=='-'){
4793+ i+=8;
4794+ if(Session.checkCipher((String)jsch.getConfig("aes128-cbc"))){
4795+ Class c=Class.forName((String)jsch.getConfig("aes128-cbc"));
4796+ cipher=(Cipher)(c.newInstance());
4797+ // key=new byte[cipher.getBlockSize()];
4798+ iv=new byte[cipher.getIVSize()];
4799+ }
4800+ else{
4801+ throw new JSchException("privatekey: aes128-cbc is not available "+prvkey);
4802+ }
4803+ continue;
4804+ }
4805+ if(buf[i]=='C'&& i+3<len && buf[i+1]=='B'&& buf[i+2]=='C'&& buf[i+3]==','){
4806 i+=4;
4807 for(int ii=0; ii<iv.length; ii++){
4808 iv[ii]=(byte)(((a2b(buf[i++])<<4)&0xf0)+(a2b(buf[i++])&0xf));
4809 }
4810 continue;
4811 }
4812- if(buf[i]==0x0d &&
4813- i+1<buf.length && buf[i+1]==0x0a){
4814+ if(buf[i]==0x0d && i+1<buf.length && buf[i+1]==0x0a){
4815 i++;
4816 continue;
4817 }
4818@@ -518,10 +574,9 @@
4819 _buf.getInt();
4820 byte[]_type=_buf.getString();
4821 //System.err.println("type: "+new String(_type));
4822- byte[] _cipher=_buf.getString();
4823- String cipher=new String(_cipher);
4824- //System.err.println("cipher: "+cipher);
4825- if(cipher.equals("3des-cbc")){
4826+ String _cipher=Util.byte2str(_buf.getString());
4827+ //System.err.println("cipher: "+_cipher);
4828+ if(_cipher.equals("3des-cbc")){
4829 _buf.getInt();
4830 byte[] foo=new byte[data.length-_buf.getOffSet()];
4831 _buf.getByte(foo);
4832@@ -529,7 +584,7 @@
4833 encrypted=true;
4834 throw new JSchException("unknown privatekey format: "+prvkey);
4835 }
4836- else if(cipher.equals("none")){
4837+ else if(_cipher.equals("none")){
4838 _buf.getInt();
4839 _buf.getInt();
4840
4841@@ -606,6 +661,13 @@
4842 while(i<len){ if(buf[i]==' ')break; i++;}
4843 publickeyblob=Util.fromBase64(buf, start, i-start);
4844 }
4845+ if(i++<len){
4846+ int s=i;
4847+ while(i<len){ if(buf[i]=='\n')break; i++;}
4848+ if(i<len){
4849+ publicKeyComment = new String(buf, s, i-s);
4850+ }
4851+ }
4852 }
4853 }
4854 }
4855@@ -628,6 +690,8 @@
4856 kpair.encrypted=encrypted;
4857 kpair.publickeyblob=publickeyblob;
4858 kpair.vendor=vendor;
4859+ kpair.publicKeyComment=publicKeyComment;
4860+ kpair.cipher=cipher;
4861
4862 if(encrypted){
4863 kpair.iv=iv;
4864
4865=== modified file 'src/main/java/com/jcraft/jsch/KeyPairDSA.java'
4866--- src/com/jcraft/jsch/KeyPairDSA.java 2010-06-27 23:17:34 +0000
4867+++ src/main/java/com/jcraft/jsch/KeyPairDSA.java 2012-05-04 10:23:17 +0000
4868@@ -1,6 +1,6 @@
4869 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
4870 /*
4871-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
4872+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
4873
4874 Redistribution and use in source and binary forms, with or without
4875 modification, are permitted provided that the following conditions are met:
4876@@ -65,8 +65,8 @@
4877 }
4878 }
4879
4880- private static final byte[] begin="-----BEGIN DSA PRIVATE KEY-----".getBytes();
4881- private static final byte[] end="-----END DSA PRIVATE KEY-----".getBytes();
4882+ private static final byte[] begin=Util.str2byte("-----BEGIN DSA PRIVATE KEY-----");
4883+ private static final byte[] end=Util.str2byte("-----END DSA PRIVATE KEY-----");
4884
4885 byte[] getBegin(){ return begin; }
4886 byte[] getEnd(){ return end; }
4887@@ -209,7 +209,7 @@
4888 return buf.buffer;
4889 }
4890
4891- private static final byte[] sshdss="ssh-dss".getBytes();
4892+ private static final byte[] sshdss=Util.str2byte("ssh-dss");
4893 byte[] getKeyTypeName(){return sshdss;}
4894 public int getKeyType(){return DSA;}
4895
4896
4897=== modified file 'src/main/java/com/jcraft/jsch/KeyPairGenDSA.java'
4898--- src/com/jcraft/jsch/KeyPairGenDSA.java 2010-06-27 23:17:34 +0000
4899+++ src/main/java/com/jcraft/jsch/KeyPairGenDSA.java 2012-05-04 10:23:17 +0000
4900@@ -1,6 +1,6 @@
4901 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
4902 /*
4903-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
4904+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
4905
4906 Redistribution and use in source and binary forms, with or without
4907 modification, are permitted provided that the following conditions are met:
4908
4909=== modified file 'src/main/java/com/jcraft/jsch/KeyPairGenRSA.java'
4910--- src/com/jcraft/jsch/KeyPairGenRSA.java 2010-06-27 23:17:34 +0000
4911+++ src/main/java/com/jcraft/jsch/KeyPairGenRSA.java 2012-05-04 10:23:17 +0000
4912@@ -1,6 +1,6 @@
4913 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
4914 /*
4915-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
4916+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
4917
4918 Redistribution and use in source and binary forms, with or without
4919 modification, are permitted provided that the following conditions are met:
4920
4921=== modified file 'src/main/java/com/jcraft/jsch/KeyPairRSA.java'
4922--- src/com/jcraft/jsch/KeyPairRSA.java 2010-06-27 23:17:34 +0000
4923+++ src/main/java/com/jcraft/jsch/KeyPairRSA.java 2012-05-04 10:23:17 +0000
4924@@ -1,6 +1,6 @@
4925 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
4926 /*
4927-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
4928+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
4929
4930 Redistribution and use in source and binary forms, with or without
4931 modification, are permitted provided that the following conditions are met:
4932@@ -73,8 +73,8 @@
4933 }
4934 }
4935
4936- private static final byte[] begin="-----BEGIN RSA PRIVATE KEY-----".getBytes();
4937- private static final byte[] end="-----END RSA PRIVATE KEY-----".getBytes();
4938+ private static final byte[] begin=Util.str2byte("-----BEGIN RSA PRIVATE KEY-----");
4939+ private static final byte[] end=Util.str2byte("-----END RSA PRIVATE KEY-----");
4940
4941 byte[] getBegin(){ return begin; }
4942 byte[] getEnd(){ return end; }
4943@@ -308,7 +308,7 @@
4944 return buf.buffer;
4945 }
4946
4947- private static final byte[] sshrsa="ssh-rsa".getBytes();
4948+ private static final byte[] sshrsa=Util.str2byte("ssh-rsa");
4949 byte[] getKeyTypeName(){return sshrsa;}
4950 public int getKeyType(){return RSA;}
4951
4952
4953=== modified file 'src/main/java/com/jcraft/jsch/KnownHosts.java'
4954--- src/com/jcraft/jsch/KnownHosts.java 2010-06-27 23:17:34 +0000
4955+++ src/main/java/com/jcraft/jsch/KnownHosts.java 2012-05-04 10:23:17 +0000
4956@@ -1,6 +1,6 @@
4957 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
4958 /*
4959-Copyright (c) 2002-2009 ymnk, JCraft,Inc. All rights reserved.
4960+Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved.
4961
4962 Redistribution and use in source and binary forms, with or without
4963 modification, are permitted provided that the following conditions are met:
4964@@ -100,13 +100,13 @@
4965 i=buf[j];
4966 if(i==' '||i=='\t'){ j++; continue; }
4967 if(i=='#'){
4968- addInvalidLine(new String(buf, 0, bufl));
4969+ addInvalidLine(Util.byte2str(buf, 0, bufl));
4970 continue loop;
4971 }
4972 break;
4973 }
4974 if(j>=bufl){
4975- addInvalidLine(new String(buf, 0, bufl));
4976+ addInvalidLine(Util.byte2str(buf, 0, bufl));
4977 continue loop;
4978 }
4979
4980@@ -118,7 +118,7 @@
4981 }
4982 host=sb.toString();
4983 if(j>=bufl || host.length()==0){
4984- addInvalidLine(new String(buf, 0, bufl));
4985+ addInvalidLine(Util.byte2str(buf, 0, bufl));
4986 continue loop;
4987 }
4988
4989@@ -133,7 +133,7 @@
4990 else if(sb.toString().equals("ssh-rsa")){ type=HostKey.SSHRSA; }
4991 else { j=bufl; }
4992 if(j>=bufl){
4993- addInvalidLine(new String(buf, 0, bufl));
4994+ addInvalidLine(Util.byte2str(buf, 0, bufl));
4995 continue loop;
4996 }
4997
4998@@ -146,7 +146,7 @@
4999 }
5000 key=sb.toString();
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches